【问题标题】:Generate .WAV from PCM (AWS Polly)从 PCM 生成 .WAV (AWS Polly)
【发布时间】:2019-10-27 10:46:18
【问题描述】:

我尝试在网上寻找答案,但找不到任何对我有帮助的东西...

我正在尝试使用 PHP (7.2) 将 PCM 流转换为 WAV 文件并将其保存在服务器上。

具体来说,我使用以下代码通过 Amazon Polly 生成语音:

try {
    $result = $client->synthesizeSpeech([
        'Text' => 'Dies ist ein Test.',
        'OutputFormat' => 'pcm',
        'SampleRate' => '8000',
        'VoiceId' => 'Hans'
    ]);

    $resultData = $result->get('AudioStream')->getContents();
}

我需要一个 WAV 文件,以便以后与不同的代码一起使用。

非常感谢您的帮助!

【问题讨论】:

    标签: php amazon-polly


    【解决方案1】:

    您只需要添加一个标头并附加 PCM 数据。 http://soundfile.sapp.org/doc/WaveFormat/

    我找不到任何 PHP 库,所以我写了一个简单的 PHP 程序来做到这一点:

    <?php
    
    $pcm = file_get_contents('polly.raw');
    
    //$pcm = $result->get('AudioStream')->getContents();
    
    //Output file
    $fp = fopen('file.wav', 'wb');
    
    $pcm_size = strlen($pcm);
    
    $size = 36 + $pcm_size;
    
    $chunk_size = 16;
    
    $audio_format = 1;
    
    $channels = 1; //mono
    
    /**From the AWS Polly documentation: Valid values for pcm are "8000" and "16000" The default value is "16000".
     * https://docs.aws.amazon.com/polly/latest/dg/API_SynthesizeSpeech.html#polly-SynthesizeSpeech-request-OutputFormat
    **/
    $sample_rate = 16000; //Hz
    
    $bits_per_sample = 16;
    
    $block_align = $channels * $bits_per_sample / 8;
    
    $byte_rate = $sample_rate * $channels * $bits_per_sample / 8;
    
    /**
    * http://soundfile.sapp.org/doc/WaveFormat/
    * https://github.com/jwhu1024/pcm-to-wav/blob/master/inc/wave.h
    * https://jun711.github.io/aws/convert-aws-polly-synthesized-speech-from-pcm-to-wav-format/
    **/
    
    //RIFF chunk descriptor
    fwrite($fp, 'RIFF');
    
    fwrite($fp,pack('I', $size));
    fwrite($fp, 'WAVE');
    
    //fmt sub-chunk
    fwrite($fp, 'fmt ');
    
    fwrite($fp,pack('I', $chunk_size));
    fwrite($fp,pack('v', $audio_format));
    fwrite($fp,pack('v', $channels));
    fwrite($fp,pack('I', $sample_rate));
    fwrite($fp,pack('I', $byte_rate));
    fwrite($fp,pack('v', $block_align));
    fwrite($fp,pack('v', $bits_per_sample));
    
    //data sub-chunk
    
    fwrite($fp, 'data');
    fwrite($fp,pack('i', $pcm_size));
    fwrite($fp, $pcm);
    
    fclose($fp);
    
    

    您也可以使用 FFmpeg 来实现这一点,但我的解决方案完全是用 PHP 编写的。

    希望能帮到你!

    【讨论】:

    • 哇 - 非常感谢!您的代码完美无缺! :) 我已经寻找有关如何创建正确 WAV 标头的示例,但找不到任何工作或自己弄清楚。
    【解决方案2】:

    可以从 PHP 脚本调用的 PHP 扩展函数和/或类

    https://www.php-cpp.com/documentation/functions

    简单的原生波形文件编写器示例:

    https://www3.nd.edu/~dthain/courses/cse20211/fall2013/wavfile/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多