Javascript - 具有音高和持续时间控制的文本到语音

标签 javascript audio text-to-speech speech

我一直在研究让我的 javascript 程序唱歌。

我首先查看了网络语音 api,但音高控制似乎非常有限,所以我想也许有一种方法可以将结果发送到网络音频节点,并从那里应用效果,但似乎不可能.

我找到了 mespeak.js 库:http://www.masswerk.at/mespeak/

它允许返回一个音频缓冲区,我会将其视为我的音频节点的来源,从而实现更多控制。

我的输入是一个音符序列,具有频率和持续时间。像这样的东西:

var seq = [[440hz,1000ms],[880hz,500ms],...];

我设法从这个序列和一系列单词到我的程序,以不同频率的节奏说出这些单词

但我遇到了一些问题。

  • 网络音频失谐与 playbackRate 相关联,因此音调会改变单词持续时间。
  • 我似乎只能使用 detune 或 playbackRate 值进行播放,这不允许我输入频率(例如 440)并获得该频率的结果。我唯一能做的就是近似我语音的基频,计算与预期音符和音高的差异,但结果不是很好。
  • 我对如何处理持续时间一无所知。 playbackRate 是人为改变单词持续时间的唯一方法吗?我怎样才能强制我的话传播到特定的持续时间?

如果你们中的任何人对这类事情有任何经验,我将不胜感激。

非常感谢

编辑:添加一些代码

function sing(text,note,duration){
  var buffer = meSpeak.speak(text,{rawdata:'default'});
  playSound(buffer,freqToCents(note),duration)
}

function freqToCents(freq){
  var root = 440 //no idea what is the base frequency of the speech generator
  return 3986*Math.log10(freq/440)
}

function playSound(streamBuffer, cents, duration, callback) { 
  var source = context.createBufferSource();
  source.connect(compressor);

  context.decodeAudioData(streamBuffer, function(audioData) { 
    var duration = audioData.duration; 
    var delay = (duration)? Math.ceil(duration * 1000) : 1000;
    setTimeout(callback, delay);
    source.buffer = audioData;
    source.detune.value = cents; 

    source.start(0);
  }, function(error) { }); 
}

我的音序器正在工作,并且在每一步都在必要时调用 sings 函数,例如:

sing('test', 440, 1000)

正如我所说,我希望持续时间参数能够影响结果

最佳答案

Espeak supports SSML mode ,您需要使用它来修改参数,而不是尝试对结果进行后处理。

您需要先使用 espeak,然后尝试在 javascript 端口中重现相同的结果。目前还不支持,但是在mespeak.js的这部分

  '-w', 'wav.wav',
      '-a', (typeof args.amplitude !== 'undefined')? String(args.amplitude) : (typeof args.a !== 'undefined')? String(args.a) : '1
      '-g', (typeof args.wordgap !== 'undefined')? String(args.wordgap) : (typeof args.g !== 'undefined')? String(args.g) : '0',
      '-p', (typeof args.pitch !== 'undefined')? String(args.pitch) : (typeof args.p !== 'undefined')? String(args.p) : '50',
      '-s', (typeof args.speed !== 'undefined')? String(args.speed) : (typeof args.s !== 'undefined')? String(args.s) : '175',

您需要添加-m选项来启用SSML。

关于Javascript - 具有音高和持续时间控制的文本到语音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36891851/

相关文章:

ios - 如何通过firemonkey在iOS应用程序中实现text-2-speech功能?

android - 如何在android中找到tts.SythensizetoFile已经完成

javascript - MEAN.JS setInterval 事件循环过程(从另一台服务器获取数据)

c# - SAPI5 讲 XML

javascript - 使用 Jquery Ajax POST 加载 PHP 响应

windows - Windows音频回送捕获的格式是否固定?还是声卡依赖?

html - 音频文件可以在HTML中内联使用吗?

ubuntu - 安装CUDA 8.0后在Ubuntu 17.04中没有声音

javascript - 如何使用 React 组件的 id 触发点击事件?

javascript - 根据两个选择选项显示 mysql 的结果数