| main | console | Legend - Hand of God | web | contact |
| cd.* | music.* | ogg.* |
| burnAudioCD | makeOgg |
This script creates gapless (no gaps between the tracks, useful for live recordings) cds. It will burn all audio (mp3, ogg, wav) files from the current directory. On runtime, you have to confirm the selected files and specify burning speed.
Then the script will automatically convert the files to wav, create the cd's TOC file and burn the cd. When it is down, it will delete all temporary files.
Note: Although this script will display the total running time of the files to be burned, it will not check whether the files will fit onto the CD.
1#!/bin/sh 2# the next line restarts using tclsh \ 3exec tclsh "$0" "$@" 4 5 6# 7# needed programs: 8# cdrdao 9# lame 10# ogg123 11# ogginfo 12# mp3info 13# shntool 14# 15 16# settings 17set config(device) "/dev/cdrom1" 18set config(driver) "generic-mmc" 19set config(max_speed) "48" 20 21 22# 23# temporarely, only allow root to use this script 24# 25if {[exec /usr/bin/whoami] != "root"} then { 26 puts "this script can only be run by root" 27 exit 28} 29 30 31# 32# which files to burn? 33# 34set listOfFiles [lsort [glob -nocomplain -types f *.{ogg,mp3,wav}]] 35 36# 37# nothing to do 38# 39if {[llength $listOfFiles] == 0} then { 40 puts "No files to burn.." 41 unset listOfFiles 42 exit 43} 44 45 46# 47# determine running time of the given file 48# 49proc fileLength {file} { 50 switch [file extension $file] { 51 ".mp3" { 52 set length [exec mp3info -p "%S" $file] 53 } 54 55 ".ogg" { 56 set text [exec ogginfo $file] 57 58 set secs 0 59 foreach line [split $text "\n"] { 60 set line [string trim $line] 61 62 if {[string range $line 0 15] == "Playback length:"} then { 63 set line [string trim [join [lrange [split $line ":"] 1 end] ":"]] 64 65 # line has now the form "4m:17s", now convert to seconds 66 foreach i [split $line ":"] { 67 set val [string range $i 0 end-1] 68 set mod [string index $i end] 69 70 if {[string index $val 0] == "0" && [string length $val] > 1} then {set val [string range $val 1 end]} 71 72 if {$mod == "s"} then {set secs [expr $secs + $val]} 73 if {$mod == "m"} then {set secs [expr $secs + ($val * 60)]} 74 if {$mod == "h"} then {set secs [expr $secs + ($val * 60 * 60)]} 75 76 unset val mod i 77 } 78 break 79 } 80 } 81 set length $secs 82 unset line text secs 83 } 84 85 ".wav" { 86 set lines [split [exec shntool len $file] \n] 87 # first line is the table heading 88 # second the first file 89 # total length of all files 90 # we did only specify one file, so we take the 2nd line 91 92 set length [lindex [split [string trim [lindex $lines 1]] " "] 0] 93 94 # shninfo returns the length nicely formatted, we need seconds here 95 set length [split $length ": ."] 96 97 set min [lindex $length 0] 98 set sec [lindex $length 1] 99 set mili [lindex $length 2] 100 101 if {[string index $sec 0] == "0"} then {set sec [string index $sec 1]} 102 if {$mili != "00"} then {incr sec} 103 104 set length [expr $sec + ($min * 60)] 105 106 unset lines min sec mili 107 } 108 } 109 110 return $length 111} 112 113# 114# converts seconds into 'nice' time values 115# 116proc transform_secs {in} { 117 118 set m [expr $in / 60] 119 set s [expr $in % 60] 120 121 if {$m < 10} then {set m "0$m"} 122 if {$s < 10} then {set s "0$s"} 123 124 # hrs, if necessary 125 if {$m > 60} then { 126 set h [expr $m / 60] 127 set m [expr $m % 60] 128 if {$h < 10} then {set h "0$h"} 129 if {$m < 10} then {set m "0$m"} 130 set m "$h:$m" 131 } 132 133 return "$m:$s" 134} 135 136# 137# waits for exactly one keypress and returns this key 138# 139proc getKey {} { 140 # eof is MIN - see termio(7) 141 exec stty -icanon eof \001 142 set R [read stdin 1] 143 scan $R "%c" V 144 # Reset the tty, assuming eof was ^D 145 exec stty icanon eof \004 146 147 return $R 148} 149 150 151# 152# display all files to be burned 153# 154 155puts "\tTrack\tFile" 156puts "\t-----\t----" 157 158set nr 1 159set length 0 160 161foreach file $listOfFiles { 162 if {$nr < 10} then {set nrTmp "0$nr"} else {set nrTmp $nr} 163 164 puts "\t $nrTmp:\t$file" 165 166 set length [expr $length + [fileLength $file]] 167 incr nr 168 unset file nrTmp 169} 170unset nr 171 172puts "\n\t Total: [transform_secs $length]" 173 174puts -nonewline "\nBurn these tracks? (y/N): " 175if {[getKey] != "y"} then { 176 unset listOfFiles 177 puts "" 178 exit 179} 180 181 182# 183# which drive speed? 184# 185puts -nonewline "\nBurn at max speed? (y/N): " 186if {[getKey] == "y"} then { 187 puts "" 188 set burnSpeed $config(max_speed) 189} else { 190 puts -nonewline "\nWhich speed?: " 191 set burnSpeed [string trim [read stdin 2]] 192} 193 194if {![string is integer $burnSpeed] || $burnSpeed > $config(max_speed) || [expr $burnSpeed % 2] != 0} then { 195 puts "Unsupported speed!" 196 unset burnSpeed listOfFiles 197 exit 198} 199 200 201# 202# final confirmation 203# 204puts -nonewline "\nStart to burn? (y/N): " 205set ans "" 206while {$ans != "y" && $ans != "n"} { 207 set ans [getKey] 208} 209 210if {$ans != "y"} then { 211 unset ans burnSpeed listOfFiles 212 puts "" 213 exit 214} 215unset ans 216 217 218# 219# let the burning begin... 220# 221 222# converting all non-wav files 223puts "\n\nPreparing files .." 224 225set tmpFiles {cd.toc} 226for {set i 0} {$i < [llength $listOfFiles]} {incr i} { 227 set file [lindex $listOfFiles $i] 228 set ext [file extension $file] 229 230 if {$ext == ".wav"} then { 231 # no conversion necessary 232 unset file ext 233 continue 234 } 235 236 # 237 # convert files 238 # 239 puts " Converting $file .." 240 241 if {[file exists $file.wav]} then { 242 puts " ERROR: $file.wav already exists" 243 unset listOfFiles tmpFiles burnSpeed i file ext 244 exit 245 } 246 247 if {$ext == ".ogg"} then { 248 exec ogg123 --quiet -d wav $file -f $file.wav 249 } 250 251 if {$ext == ".mp3"} then { 252 catch {exec lame --quiet --decode $file $file.wav} 253 } 254 255 set listOfFiles [lreplace $listOfFiles $i $i "$file.wav"] 256 lappend tmpFiles $file.wav 257 258 unset file ext 259} 260unset i 261 262# creating TOC file 263puts "Creating toc file .." 264 265set fd [open cd.toc w+] 266puts $fd "CD_DA" 267puts $fd "" 268 269foreach i $listOfFiles { 270 puts $fd "TRACK AUDIO" 271 puts $fd "AUDIOFILE \"$i\" 0" 272 puts $fd "" 273 unset i 274} 275 276close $fd 277unset fd 278 279 280# 281# burning!! 282# 283puts "Burning at [set burnSpeed]X ..\n" 284 285catch {exec cdrdao write --device $config(device) --driver $config(driver) --speed $burnSpeed -n -v 1 cd.toc >@stdout 2>@stderr} 286#catch {exec cdrdao simulate --device $config(device) --driver $config(driver) --speed $burnSpeed -n -v 1 cd.toc >@stdout 2>@stderr} 287 288 289 290 291# 292# remove temporary wave files 293# 294puts "\nRemoving temporary files .." 295foreach i $tmpFiles { 296 file delete $i 297 unset i 298} 299 300 301 302 303unset burnSpeed listOfFiles tmpFiles 304exit