Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/gawk -f
- # nokia2beeps.tcl - Play an RTTL ringtone file as beeps
- # Usage: ./nokia2beeps.tcl ringtone_file
- #TODO: imelody
- #TODO: chord
- BEGIN {
- default_duration = 4
- default_octave = 4
- default_beat = 63
- base_time = 200000
- loop = 3
- # option_qwerty_midi = 0
- # option_adjust_octave = 1
- # http://www.phy.mtu.edu/~suits/notefreqs.html
- split("\
- C0 16.35 C#0 17.32 Db0 17.32 D0 18.35 D#0 19.45 Eb0 19.45 \
- E0 20.60 F0 21.83 F#0 23.12 Gb0 23.12 G0 24.50 G#0 25.96 \
- Ab0 25.96 A0 27.50 A#0 29.14 Bb0 29.14 B0 30.87 C1 32.70 \
- C#1 34.65 Db1 34.65 D1 36.71 D#1 38.89 Eb1 38.89 E1 41.20 \
- F1 43.65 F#1 46.25 Gb1 46.25 G1 49.00 G#1 51.91 Ab1 51.91 \
- A1 55.00 A#1 58.27 Bb1 58.27 B1 61.74 C2 65.41 C#2 69.30 \
- Db2 69.30 D2 73.42 D#2 77.78 Eb2 77.78 E2 82.41 F2 87.31 \
- F#2 92.50 Gb2 92.50 G2 98.00 G#2 103.83 Ab2 103.83 A2 110.00 \
- A#2 116.54 Bb2 116.54 B2 123.47 C3 130.81 C#3 138.59 Db3 138.59 \
- D3 146.83 D#3 155.56 Eb3 155.56 E3 164.81 F3 174.61 F#3 185.00 \
- Gb3 185.00 G3 196.00 G#3 207.65 Ab3 207.65 A3 220.00 A#3 233.08 \
- Bb3 233.08 B3 246.94 C4 261.63 C#4 277.18 Db4 277.18 D4 293.66 \
- D#4 311.13 Eb4 311.13 E4 329.63 F4 349.23 F#4 369.99 Gb4 369.99 \
- G4 392.00 G#4 415.30 Ab4 415.30 A4 440.00 A#4 466.16 Bb4 466.16 \
- B4 493.88 C5 523.25 C#5 554.37 Db5 554.37 D5 587.33 D#5 622.25 \
- Eb5 622.25 E5 659.26 F5 698.46 F#5 739.99 Gb5 739.99 G5 783.99 \
- G#5 830.61 Ab5 830.61 A5 880.00 A#5 932.33 Bb5 932.33 B5 987.77 \
- C6 1046.50 C#6 1108.73 Db6 1108.73 D6 1174.66 D#6 1244.51 Eb6 1244.51 \
- E6 1318.51 F6 1396.91 F#6 1479.98 Gb6 1479.98 G6 1567.98 G#6 1661.22 \
- Ab6 1661.22 A6 1760.00 A#6 1864.66 Bb6 1864.66 B6 1975.53 C7 2093.00 \
- C#7 2217.46 Db7 2217.46 D7 2349.32 D#7 2489.02 Eb7 2489.02 E7 2637.02 \
- F7 2793.83 F#7 2959.96 Gb7 2959.96 G7 3135.96 G#7 3322.44 Ab7 3322.44 \
- A7 3520.00 A#7 3729.31 Bb7 3729.31 B7 3951.07 C8 4186.01 C#8 4434.92 \
- Db8 4434.92 D8 4698.64 D#8 4978.03 Eb8 4978.03 E8 5274.04 F8 5587.65 \
- F#8 5919.91 Gb8 5919.91 G8 6271.93 G#8 6644.88 Ab8 6644.88 A8 7040.00 \
- A#8 7458.62 Bb8 7458.62 B8 7902.13", arr)
- for (i = 1; i <= length(arr); i += 2)
- scale[arr[i]] = arr[i + 1]
- delete arr
- }
- function nokia2scale(note, octave)
- {
- gsub("\\.", "", note)
- gsub(/[rR-]/, "P", note)
- match(note, /[a-gA-GpP#].*/)
- note = toupper(substr(note, RSTART, RLENGTH))
- octave = default_octave
- if (match(note, /[0-8]$/)) {
- octave = substr(note, length(note), 1)
- note = substr(note, 1, length(note) - 1)
- }
- if (option_adjust_octave)
- octave += trans_octave
- return (note ~ /P/) ? note : note octave
- }
- function nokia2length(note, duration, dotted)
- {
- match(note, /^(0.|)[0-9]+/)
- duration = substr(note, RSTART, RLENGTH)
- if (duration == "")
- duration = default_duration
- note = substr(note, RSTART+RLENGTH)
- dotted = gsub("\\.", "", note)
- if (dotted) duration /= (1.5 * dotted)
- return base_time / default_beat / duration
- }
- function playnote(note)
- {
- note = trim(note)
- if (note == "") return
- if (!quiet)
- printf "%s ", option_qwerty_midi ? keymap(note) : note
- delay = nokia2length(note)
- note = nokia2scale(note)
- if (note ~ /P/) {
- after(delay)
- } else {
- if (system("beep -f " scale[note] " -l " delay " -D 0 >/dev/null"))
- printf "\nError: (note,scale[note],delay)=(%s,%s,%s)\n", note, scale[note], delay
- }
- }
- function trim(s) { sub(/^[ \t]+/, "", s); sub(/[ \t]+$/, "", s); return s }
- function after(delay) { system("sleep " delay/1000) }
- function playRTTL( str, arr, value, i, title, r)
- {
- str = gensub(/\(Tempo=([0-9]+)\)/, "b=\\1", 1, $0)
- while (match(str, /([dob])[ \t]*=[ \t]*([0-9]+)/, arr) > 0) {
- if (title == "")
- title = substr(str, 1, arr[1, "start"] - 1)
- if (title ~ /:$/) title = substr(title, 1, length(title) - 1)
- value = arr[2]
- switch (arr[1]) {
- case "d": default_duration = value; break
- case "o": default_octave = value; break
- case "b": default_beat = value; break
- }
- str = substr(str, arr[2, "start"] + arr[2, "length"] + 1)
- }
- print title
- print "beat: " default_beat
- trans_octave = 0
- if (test_nokia_composer(str)) {
- trans_octave = 3
- str = gensub(/#([a-gA-G])/, "\\1#", "g", str)
- }
- quiet = 0
- for (r = 1; r <= loop; ) {
- split(str, arr, /[ ,]/)
- for (i = 1; i <= length(arr); i++)
- playnote(arr[i])
- if (r == 1) print ""
- r++
- if (r > 1 && r <= loop) {
- quiet = 1 #suppress output
- printf "\rrepeat " r-1
- after(nokia2length("R"))
- }
- }
- print "\ndone."
- }
- # http://nokia.nigelcoldwell.co.uk
- function test_nokia_composer(str, arr, i, n, o)
- {
- # get octaves range (global for keymap)
- min_octave = 10; max_octave = -1
- split(str, arr, /[ ,]/)
- for (i = 1; i <= length(arr); i++) {
- o = default_octave
- if (arr[i] ~ /[-pP]/) continue
- if (match(arr[i], /[0-4]$/))
- o = substr(arr[i], RSTART, 1)+0
- if (o < min_octave) min_octave = o
- if (o > max_octave) max_octave = o
- }
- return str ~ /-/ || min_octave < 3 && max_octave - min_octave < 4
- }
- # http://outputchannel.com/monophonic-ringtone-synthesizer/
- function keymap(note, str)
- {
- str = "Cl A C#l W Dl S D#l E El D Fl F F#l T Gl G G#l Y " \
- "Al H A#l U Bl J Cu K C#u O Du L D#u P Eu ; Eu [ Fu ' F#u ] Gu \\"
- if (note ~ /[-pP]/) return "."
- gsub("\\.", "", note)
- match(note, /[a-gA-GpP#].*/)
- note = toupper(substr(note, RSTART, RLENGTH))
- if (note !~ /[0-8]$/) note = note default_octave
- sub(min_octave, "l", note)
- sub(min_octave+1, "u", note)
- if (match(str, note))
- return substr(str, RSTART+RLENGTH+1, 1)
- return "?" note "?"
- }
- # http://www.phoneringsong.com/nokia_composer_tones/
- function keypress2composer(str,
- result, score, duration, octave, dot, pitch, arr, i, n)
- {
- score = ""; duration = 4; octave = 1; dot = ""
- split("cdefgab", pitch, ""); pitch[0] = "-"
- match(str, "( [0-9#*] )|(P&H)")
- result = substr(str, 1, RSTART - 1)
- n = split(substr(str, RSTART), arr)
- for (i = 1; i <= n; i++) {
- if (sony_ericsson) {
- sub("0", "@", arr[i])
- sub("*", "0", arr[i])
- sub("@", "*", arr[i])
- }
- switch(arr[i]) {
- case /P&H/: dot = "."
- case /[0-7]/:
- score = pitch[substr(arr[i], length(arr[i]), 1)]
- break
- case /#/: score = "#" score; break
- case /8/: duration *= 2; break
- case /9/: duration /= 2; break
- case /[*]/:
- if (sony_ericsson)
- octave = octave++ % 4 + 1
- else
- octave = octave++ % 3 + 1
- break
- }
- if (i == n || arr[i + 1] ~ /[0-7]/) {
- result = result " " duration dot score
- if (score !~ /r/) result = result octave
- score = ""; duration = 4; dot = ""
- }
- }
- return result
- }
- /^#/ || !NF { print; next }
- /,$/ { buf = buf $0 " " }
- {
- #if (FNR == 1 && is_imelody()) {
- # read whole data
- # play
- # nextfile
- #}
- if (buf) $0 = buf $0 " "
- if (/ [0-9#*] /)
- $0 = keypress2composer($0)
- if (/[ドレミファソラシ]/)
- $0 = chakumero_conv($0)
- playRTTL($0)
- if (buf) buf = ""
- }
- # http://www.pluto.dti.ne.jp/~imasa/melody.html
- # "テンポ=6(126)1:ドH1 2:シ1 3:ドH1 4:シ1 5:ドH1 6:-3 7:ドH1 8:シ1 9:ドH1 10:シ1 11:ドH1 12:-3 13:ドH1 14:シ1 15:ドH1 16:シ1 17:ドH1 18:-1 19:ミH1 20:-1 21:ソ6 22:ラ1 23:ソ1 24:ラ1 25:ソ1 26:ラ1 27:-3 28:ラ1 29:ソ1 30:ラ1 31:ソ1 32:ラ1 33:-3 34:ラ1 35:ソ1 36:ラ1 37:ソ1 38:ラ1 39:-1 40:ドH1 41:-1 42:ミ6 43:レ1 44:-1 45:レ1 46:ミ1 47:ファ1 48:-3 49:ファ1 50:-1 51:ファ1 52:ソ1 53:ラ1 54:-3 55:ソ1 56:-1 57:ソ1 58:ラ1 59:シ1 60:-1 61:ドH1 62:-1 63:レH6"
- # "テンポ=7(138)1:ド1 2:ドH1 3:シ1 4:ドH1 5:ミH1 6:ドH1 7:シ1 8:ドH1 9:ド1 10:ドH1 11:ラ#1 12:ドH1 13:ミH1 14:ドH1 15:ラ#1 16:ドH1 17:ド1 18:ドH1 19:ラ1 20:ドH1 21:ミH1 22:ドH1 23:ラ1 24:ドH1 25:ド1 26:ドH1 27:ソ#1 28:ドH1 29:ミH1 30:ドH1 31:ソ#1 32:ドH1"
- # "テンポ=6(126)1:ソL1 2:-1 3:ド1 4:ミ1 5:ソ1 6:ラ1 7:ソ1 8:ミ1 9:ファ1 10:-1 11:ファ1 12:-1 13:レ4 14:ソL1 15:-1 16:シL1 17:レ1 18:ファ1 19:ラ1 20:ソ1 21:ファ1 22:ミ1 23:-1 24:レ1 25:-1 26:ソ4 27:ソL1 28:-1 29:ド1 30:ミ1 31:ソ1 32:ラ1 33:ソ1 34:ミ1 35:ファ1 36:-1 37:ファ1 38:-1 39:レ4 40:シL1 41:レ1 42:ファ1 43:ラ1 44:ソ1 45:-1 46:シL1 47:-1 48:ド1 49:-1 50:ド1 51:-1 52:ド1 53:-3"
- # http://www.geocities.co.jp/HeartLand-Namiki/8944/onpu.html
- # "テンポ4(108)レ5/ファ#1/ソ4/-1/レ3/ミ3/レ2/ミ2/シL1/シL5/-4/-1/ド2/シL2/ラL1/シL2/ラL1/ソL2/ソL3/-1/ソL2/ファ#L2/ソL2/ミ4/レ2/ミ1/レ2/-1/レ5/ファ#1/ソ4/-1/レ3/ミ3/ファ#2/ソ2/レ1/レ5/-4/-1/ド2/シL2/ラL1/シL2/ラL1/ソL2/ソL3/-1/ソL2/レ2/ミ2/レ5/-4/-2/ミ2/ミ2/レ1/ミ3/シL1/シL2/-2/-1/ラL1/シL1/ド1/ラL2/シL1/ド1/シL2/ラL1/ソL2/-4/ソL2/ラL2/シL2/ラL4/シL2/ド2/シL4/ソL2/ソL6/-4"
- # "テンポ3(96)レ2/ミ2/ラ↓2/ラ↓5/休2/ミ2/レ2/ミ2/ソ↓2/ソ↓5/休4/ラ↓2/シ↓2/ド2/ミ5/休2/ミ2/レ2/ミ5/レ1/ミ5/休2/レ2/ミ2/ラ↓2/ラ↓5/ミ2/ミ2/レ2/ミ2/ソ↓2/ソ↓5/ミ2/休2/ラ↓2/シ↓2/ド2/ミ4/ミ4/ミ2/レ5/ミ1/レ1/ミ5/休2/ミ2/レ2/ド2/ラ↓4/ラ↓4/ラ↓2/レ2/休2/レ2/レ4/レ2/シ↓2/シ↓1/シ↓1/ラ↓7/休4"
- # "テンポ7(138)レ#2/レ2/レ#2/レ2/レ#4/レ2/レ#4/レ2/レ#2/レ2/レ#4/休2/ラ#↓2/ラ#↓4/レ#2/レ#5/ソ2/ソ5/ラ#2/ラ#4/ソ4/レ#7/休4/ド2/ラ#↓2/ド4/レ4/ラ#↓4/ド4/レ4/レ#4/ド4/レ4/レ#4/ファ6/休2/レ#2/レ2/レ#2/レ2/レ#4/レ2/レ#4/レ2/レ#2/レ2/レ#4/休2/ラ#↓2/ラ#↓4/レ#2/レ#5/ソ2/ソ5/ラ#2/ラ#4/ソ4/レ#7/休4/ド2/ラ#↓2/ド4/レ4/ラ#↓4/ド4/レ2/レ#0/休4/休4/休4"
- # http://hasu.jp/cmelo/index.html
- # "テンポ144 ラ2・ シ4 ラ8 ラ4 シ8 ド△4 ド△8 ド△4 レ△8 ミ△4・ ●4・ ラ4 ラ8 ラ4 ソ8 ソ4 ソ8 ラ4 ソ8 ミ4 ソ2・ ●2 ラ4 ラ8 ラ4 ラ8 シ4 シ8 ラ4 シ8 ド△4 ド△8 ド△4 レ△8 ミ△4・ ●4・ ラ4 ラ8 ラ4 ラ8 ソ4 ソ8 ラ4 シ8 ド△全 ●2"
- # "テンポ144 ファ2・ ソ4 ファ8 ファ4 ファ8 ミ4 ミ8 ミ4 ファ8 ソ4・ ●4・ ファ4 ファ8 ファ4 ファ8 ソ4 ソ8 ソ4 ファ8 ファ4 ミ2・ ●2 ファ4 ファ8 ファ4 ファ8 ソ4 ソ8 ファ4 ファ8 ミ4 ミ8 ミ4 ファ8 ソ4・ ●4・ ファ4 ファ8 ファ4 ファ8 ソ4 ソ8 ソ4 ソ8 ソ全 ●2"
- # "テンポ144 ファ▽2・ ソ▽2・ ラ▽4・ シ▽4・ ド4・ ソ4・ ファ2・ ソ▽2・ ド2・ ラ4・ ソ4・ ファ2・ ソ▽2・ ラ▽4・ シ▽4・ ド4・ ソ4 ファ#8 ファ2・ ソ▽2・ ド全 ド8 シ▽4 ラ▽#8"
- function chakumero_conv(str,
- arr, i, j,note, octave, beat, tr_s, tr_d, score, duration, tie_s)
- { gsub("\"", "", str)
- octave = 4; beat = 63
- if (match(str, /[0-9]{2,3}/))
- beat = substr(str, RSTART, RLENGTH)
- str = substr(str, RSTART+RLENGTH+1)
- split("ド|c|レ|d|ミ|e|ファ|f|ソ|g|ラ|a|シ|b|#|#|-|p|休|p|●|p|・|.", tr_s, "|")
- split("9|12|8|6|7|2.|6|2|5|4.|4|4|3|8.|2|8|1|16|0|1|16|16|8|8|4|4|2|2|全|1", tr_d, "|")
- split(str, arr, "[ /]")
- for (i = 1; i <= length(arr); i++) {
- if (match(arr[i], /:/))
- arr[i] = substr(arr[i], RSTART+1)
- for (j = 1; j <= length(tr_s); j += 2)
- sub(tr_s[j], tr_s[j+1], arr[i])
- for (j = 1; j <= length(tr_d); j += 2)
- if (sub(tr_d[j], tr_d[j+1], arr[i]))
- break
- if (match(arr[i], /[.0-9]+$/)) {
- score = substr(arr[i], 1, RSTART-1)
- duration = substr(arr[i], RSTART)
- }
- sub("\\^", tie_s, score); tie_s = score
- if (score ~ /[HL↑↓△▽]/) {
- score = gensub(/([△▽])#/, "#\\1", 1, score)
- sub(/[H↑△]/, octave+1, score)
- sub(/[L↓▽]/, octave-1, score)
- }
- note = duration score
- str = (i == 1) ? note : str "," note
- }
- return sprintf("o=%d,b=%d:%s", octave, beat, str)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement