Ruby:生成Morse Code声音文件

时间:2012-11-28 19:21:03

标签: ruby audio morse-code

我正在训练用耳朵阅读Morsecode;)

为了训练自己,我编写了一个小的ruby脚本来使用命令行sox生成声音文件(见下文)。它基本上只需要dit s,dah s和多个空格(在ditdah之间,在字母之间和单词之间)预先制作的声音文件并粘合它们一起。它可以工作,但目标文件越大,速度越来越慢。

是否有更智能的方法将红宝石声音生成为wav文件?


#!/usr/bin/ruby

wordlength = 5
blocklength = 12
testlength = 5
alphabet = [ "G", "A", "S", "5", "D", "0", "R", "/", "2", "L", "9", "T", "V", "I", "O", "Q", "C", "4", "F", "X", "E", "N", "U" ]
playstring = ""
block = ""
page = ""

MORSE = {
        "!" => "---.", "\"" => ".-..-.", "$" => "...-..-", "'" => ".----.",
        "(" => "-.--.", ")" => "-.--.-", "+" => ".-.-.", "," => "--..--",
        "-" => "-....-", "." => ".-.-.-", "/" => "-..-.", "0" => "-----",
        "1" => ".----", "2" => "..---", "3" => "...--", "4" => "....-", "5" => ".....",
        "6" => "-....", "7" => "--...", "8" => "---..", "9" => "----.", ":" => "---...",
        ";" => "-.-.-.", "=" => "-...-", "?" => "..--..", "@" => ".--.-.", "A" => ".-",
        "B" => "-...", "C" => "-.-.", "D" => "-..", "E" => ".", "F" => "..-.",
        "G" => "--.", "H" => "....", "I" => "..", "J" => ".---", "K" => "-.-",
        "L" => ".-..", "M" => "--", "N" => "-.", "O" => "---", "P" => ".--.",
        "Q" => "--.-", "R" => ".-.", "S" => "...", "T" => "-", "U" => "..-",
        "V" => "...-", "W" => ".--", "X" => "-..-", "Y" => "-.--", "Z" => "--..",
        "[" => "-.--.", "]" => "-.--.-", "_" => "..--.-", 
        "ka" => "-.-.-.",
}

startblock = "dit.wav ditspace.wav dit.wav ditspace.wav dit.wav ditspace.wav dah.wav wordspace.wav dit.wav ditspace.wav dit.wav ditspace.wav dit.wav ditspace.wav dah.wav wordspace.wav dit.wav ditspace.wav dit.wav ditspace.wav dit.wav ditspace.wav dah.wav wordspace.wav dah.wav ditspace.wav dit.wav ditspace.wav dah.wav ditspace.wav dit.wav ditspace.wav dah.wav wordspace.wav wordspace.wav wordspace.wav "
endblock = "dit.wav ditspace.wav dah.wav ditspace.wav dit.wav ditspace.wav dah.wav ditspace.wav dit.wav blockspace.wav "

playstring << "uebungsanfang.wav wordspace.wav "
system ('/opt/local/bin/sox ' + playstring.to_s + ' tmp.wav 2>/dev/null')
system ('mv tmp.wav tmp2.wav')
playstring = ""

testlength.times do |line|
    printf line.to_s + " "
    playstring << "gruppe" + (line+1).to_s + ".wav wordspace.wav "
    playstring << startblock
    system ('/opt/local/bin/sox tmp2.wav ' + playstring.to_s + ' tmp.wav 2>/dev/null')
    system ('mv tmp.wav tmp2.wav')
    playstring = ""
    blocklength.times do |count|
        word = alphabet.sample.to_s + alphabet.sample.to_s + alphabet.sample.to_s + alphabet.sample.to_s + alphabet.sample.to_s
        word.each_char do |char|
            MORSE[char].each_char do |dahdit|
                case dahdit
                    when '.' then playstring << "dit.wav "
                    when '-' then playstring << "dah.wav "
                end
                playstring << "ditspace.wav "
            end
            playstring << "letterspace.wav "
            system ('/opt/local/bin/sox tmp2.wav ' + playstring.to_s + ' tmp.wav 2>/dev/null')
            system ('mv tmp.wav tmp2.wav')
            playstring = ""
        end
        playstring << "wordspace.wav "
        block << word.to_s + " "
    end
    playstring << endblock
    playstring << "blockspace.wav "
    system ('/opt/local/bin/sox tmp2.wav ' + playstring.to_s + ' tmp.wav')  #2>/dev/null
    system ('mv tmp.wav tmp2.wav')
    playstring = ""
    page << "%02d" %(line+1).to_s + ": VVV <ak> " + block + "+" + "\n"
    block = ""
end
playstring << "uebungsende.wav"
system ('/opt/local/bin/sox tmp2.wav ' + playstring.to_s + ' tmp.wav 2>/dev/null') #  &
system ('rm tmp2.wav')
system ('mv tmp.wav cw.wav')
system ('lame --cbr -b 128 cw.wav cw.mp3')
system ('rm cw.wav')
puts
puts page

声音文件是使用sox预先生成的:

sox -e floating-point -r 22500 -n -t wav - synth 0.3 sin 0 > letterspace.wav

使用MAc OS X命令Übungsende生成包含say等的文件(测试开始,测试结束,第一组,第二组......):

say -v Steffi --file-format=WAVE --data-format=LEF32@22500 -o uebungsanfang.wav "Anfang der Übung."

我上传了文件(最多为“Gruppe 5”,即“第5组”): https://docs.google.com/open?id=0B4QwMfBGRCjVbE5iZHpHMHBKT3c

1 个答案:

答案 0 :(得分:2)

我不知道ruby,所以我不完全确定我知道你在做什么,但看起来你正在生成代表点,短划线,空格等的音频文件,然后用sox连接原始数据从这些文件到新文件,然后使用lame转换为mp3。

总而言之,这是非常低效的,主要是因为你正在使用可以即时生成的原始文件做很多事情。也就是说,可能不值得以最有效的方式重写 - 毕竟,执行所有文件IO会使代码变得简单。所以我会重写代码,以便文件IO尽可能快。在这种情况下,必须反复打开和解析WAV文件,特别是32位浮点WAV文件,可能会减慢你的速度。对于你正在做的事情,你绝对不需要那样做。我将从使用16位整数WAV文件开始。

为了获得更高的速度,请尝试使用更简单的格式作为中间体,例如au(如果它足够好则使用u-law,否则使用16位线性)。您还可以尝试“原始”,也称为“无头”文件 - 只需告诉sox和lame使用的样本率,位深度,字节序数和样本数。那么你不需要使用sox来连接原始数据,你可以使用“cat”unix工具,它应该更快一些。