大声说出从0到9的数字


15

受到来自electronic.SE这个问题的启发,对您来说是一个挑战:

编写一个程序或子程序,该程序或子程序使用一个十进制数字序列(0到9)并大声说出来,而无需使用现有的语音合成工具。

输入:

您可以要求以任何合理的格式提供输入数字,例如,以ASCII数字字符串,整数数组,BCD编码的数字等形式提供。如果您的解决方案是可执行程序,则可以将输入作为命令行参数,从标准输入中读取它,或以任何其他合理的方式获取它。

您的程序每次调用必须至少能说八位数。您可以假设第一个数字不为零,除非它是唯一的数字。

输出:

您的程序可以使用音频设备直接说出数字,也可以输出可播放的声音文件。输出文件(如果有)可以采用任何标准音频格式,也可以包含原始样本数据。如果输出原始样本数据,请注意适当的回放参数(采样率,每个样本的位数,字节序,有符号/无符号,通道数)。aplay支持的格式是首选。

您可以自由决定如何说出数字的细节,但是您的输出应包括以典型英语使用者可以理解的方式说出的英语数字,并且应该足够清晰,以使听者能够准确地转录八位数的随机数字。不,只鸣响n次不算。不要忘记在数字之间包含停顿。

得分:

适用标准的评分规则:得分是代码的长度(以字节为单位),或者,如果代码是用Unicode文本编写的,则是Unicode字符。最低分获胜。任何语言都可以。

作为关于电子学的最初问题,SE是关于嵌入式编程的,我认为使用低级语言向作者扔骨头是合适的:如果您的解决方案是用编译语言编写的,则可以选择计算语言的长度。已编译的可执行文件(以字节为单位)作为您的分数。(是的,预编译的字节码,例如Java .class文件也是可以的。)如果您选择使用此选项,请在答案中包括已编译的可执行文件的副本(例如,作为十六进制转储)以及源代码。以及用于生成它的编译器版本和选项。

荣誉奖,与50代表沿奖金,将被授予第一个答案也能满足该的标准原来的问题,即,能够与闪光灯的4 kb和SRAM的1kb的上的嵌入式微控制器运行。

限制条件:

除非您将上述文件或资源的长度计入分数,否则您不得使用不属于所选语言的标准运行时环境的任何文件或网络资源。(这是不允许的,例如从网络上加载音频样本。)

您也可能不使用任何预先存在的语音合成工具或库或音频数据的汇编(除非您也将它们的大小计为分数的一部分),即使它们已包含在所选语言的标准运行时环境中也是如此。


附言 如果我设法使它产生听起来确实可以理解的东西,我可能会在以后发布自己的解决方案。不过,不要羞于发布自己的内容;在这一点上,任何答案都是一个好的答案。
Ilmari Karonen

1
是允许我们下载语音数字数据库(并将其大小计入乐谱)还是必​​须录制自己的声音?我怀疑我是否可以通过算法生成语音样本。
约翰·德沃夏克

嗯...“输出”部分未指定我们必须输出语音样本。我们可以只发出十次哔声吗?
John Dvorak

@PeterTaylor:如果将它们的大小作为分数的一部分,那就可以了。我只是担心可能会有一些系统在其标准运行时环境中某个地方埋藏着数字音频样本。
Ilmari Karonen

3
由于似乎有一堆人没有读到最后并把琐碎的包装贴在重量级库周围,所以值得编辑来将更多的重点放在“自己动手”方面。
彼得·泰勒

Answers:


10

红宝石-3710 = 90个字符的代码+ 3620个字节的数据

require'zlib'
$><<$*[0].chars.map{|x|Zlib::Inflate.inflate File.open(x).read}.join(?0*5e3)

输入:单个命令行参数,要读取的数字

输出:原始声音数据,PCM 8bit / 8kHz

可以读取任何输入字符串,只要

  • 它仅包含有效文件名的字符。对于仅四个字符,您可以将其设置为所有字符。
  • 您有必要的文件。
  • 为什么哦,你太空,哦,撇号三通,太空,我,迪伊,太空三通,我的时代

5e3编码两个单词之间的停顿。在这里,5ksamples == 0.6s。根据需要进行调整。

现在,棘手的部分是获得4K的样本文件,但仍能够以足够的质量轻松解压缩它们。这是我的购买方式:

现在,必须选择采样率和抽取量。太多,声音将无法理解。太少,您不适合。我已经选择了8kHz / 3b。它们是:https : //github.com/honnza/drops/raw/master/digits.zip

  • 8KHz * 4b /样本和更高质量-太大
  • 8KHz * 3b /样本-低质量,但适合4K
  • 8KHz * 2b / sample-kch kchhhhhhhhh [无法理解]
  • 2KHz * 8b /样本-太大
  • 2KHz * 3b /样本-kch kchhhhhhhhh
  • 1KHz * 8b /样本-kch kchhhhhhhhh

这是抽取脚本:

require'zlib'
Dir.glob "*.raw" do |fname|
  File.open fname[/\d/], "wb" do |out|
    File.open fname do |input|
      bytes = input.bytes.to_a
      bytes.map! {|x|x&0xE0}
      dfl = Zlib::Deflate.deflate(bytes.pack("C*"),9)
      dfl.each_byte do |byte|
        out.print byte.chr
      end
      puts "done #{fname}: #{dfl.size}"
    end
  end
end

至于最初的挑战:代码和文件表有476个字节的空间。取决于我们使用DEFLATE库可以得到的大小,这可能有点太多。如有必要,我们可以通过更尖锐地裁剪音频样本来在此处和此处切开一些角落。[fo:r][o:]实际上并不重要,但它节省了字节。裁剪数字时,我有些仁慈。另外,采用不同的抽取方案或牺牲一些抽取以进行下采样可能会有所帮助-我稍后会介绍。另外,删除DEFLATE标头可能会节省少量空间。

连接声音样本非常容易,但是4K有点局促。如果您不受4k空间的限制,建议减少抽取。每个样本4位实际上效果很好,只是稍大一点。


+1,还不错。但是,清晰度非常有限:我尝试转录一些随机数,并获得了约70%的成功率。(我希望能达到99%的水平。)关于荣誉奖,我仍然有些犹豫:尽管您已经提出了一个很好的论点,即可以通过这种方式实现4K ,但您还没有实际证明了这一点。即使您为C放弃了ruby(这似乎很容易做到;我也愿意出于信念而参与其中),您是否真的可以在剩余的闪存空间中安装DEFLATE解码器?另外,正如我指出的,声音质量非常差。
Ilmari Karonen

附言 有关更好压缩的一些技巧:您可以将所有样本填充到具有空字节的固定长度(应该很好地压缩)并将它们连接到一个压缩文件中,然后解压缩和切片。同样,此答案的KZIP技巧可以为您提供更好的DEFLATE压缩。最后,尝试编辑组合的声音文件,以使用完全相同的副本替换等效的音素。
Ilmari Karonen

好吧,无论是IMO还是原始声音样本都无法完全理解-下采样对此几乎没有损害。我知道的最小的DEFLATE库-第一个由Wikipeda链接的库-重约500b。坦白说,您要我将充气机移植到该特定设备吗?我可能会真正了解它,但是我以前从未为ARM编写过代码。
John Dvorak

我对70%的成功率感到非常惊讶-我发现这些数字很容易理解。您最困惑哪个数字?
约翰·德沃夏克

它移植到一个皮质M0可能是一个有点过分的要求(但如果你能做到这一点,那简直是真棒!),但我认为一个独立的二进制文件(+数据文件,如果有的话)下拟合4k似乎是一个合理的示范。(不需要在libc中为文件I / O静态链接,因为您不需要在嵌入式设备上进行链接,但是一定要考虑DEFLATE代码。)基本上,您可以将其发布为原始问题的答案。 SE并自信地说“如果您为设备编译此文件,我敢打赌它会适合”。
Ilmari Karonen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.