c ++和portaudio,输出严重失真

Posted

技术标签:

【中文标题】c ++和portaudio,输出严重失真【英文标题】:c++ and portaudio, horribly distorted output 【发布时间】:2014-04-07 14:23:11 【问题描述】:

我编写了一小段代码,旨在读取一个 wav 文件并通过 portaudio 播放它。

我限制自己使用一些特定的 wav 文件:线性 pcm(无压缩),不超过 2 个通道。如我所见,wav文件解码工作得很好,我相信我以后通过portaudio播放它时会遇到麻烦。

对于我的测试,我选择了一个过于简单的 wav 文件(短:8 位比特深度,11025 采样率,单声道和大约 3 秒长)。

所以,一旦我准备好所有样本,我确实将它们提供给 portaudio(对它们进行缩放,使它们在 -1.0f 和 1.0f 之间,如教程示例中所示),我可以识别声音,但它严重失真。 ..

我认为这可能是因为采样率(尽管 11025 hz 是相当标准的)并将其重新采样到 Pa_getDeviceInfo->getDefaultSampleRate (44100hz) 给出的速率。

但我只是得到相同的结果。我也尝试选择其他设备,但仍然没有好转。

我在 Bjorn Roche (http://blog.bjornroche.com/2011/11/slides-from-fundamentals-of-audio.html) 的一些幻灯片中读到,我的缩放方法并不好,但我找不到其他选择。

会不会是配置问题?还是我错过了有关采样和音频播放的重要内容? (这是我第一次接触音频编程)

顺便说一句,我正在使用带有 portaudio 的 linux 和 alsa,我在初始化 portaudio 时收到这些错误消息:

    ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
    ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
    ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
    bt_audio_service_open: connect() failed: Connection refused (111)
    bt_audio_service_open: connect() failed: Connection refused (111)
    bt_audio_service_open: connect() failed: Connection refused (111)
    bt_audio_service_open: connect() failed: Connection refused (111)

我定义了我的回调函数如下:(只播放这个特定的文件)

    unsigned int actualSample;        

    static int patestCallback( const void *inputBuffer, void *outputBuffer,
                       unsigned long framesPerBuffer,
                       const PaStreamCallbackTimeInfo* timeInfo,
                       PaStreamCallbackFlags statusFlags,
                       void *userData )
    
        /* Cast data passed through stream to my wav file. */
        WavSound *data = (WavSound*)userData; 
        float *out = (float*)outputBuffer;
        unsigned int i;
        (void) inputBuffer; /* Prevent unused variable warning. */

        for( i=0; i<framesPerBuffer; i++ )
            
             *out++ = (float) ((data->getSample(::actualSample)-127)/128);
             ::actualSample = ::actualSample + 1;
             if(::actualSample >= data->getSamplesSize())
                 ::actualSample = 0;
        
        return 0;
    

感谢阅读!

【问题讨论】:

【参考方案1】:

声音失真的原因如下:样本以无符号 8 位格式存储,但静音是用样本值 255 定义的,因为我认为它是 0。整个缩放顺序是相反的。

我换行了:

*out++ = (float) ((data->getSample(::actualSample)-127)/128);

*out++ = (float) (((-1)*data->getSample(::actualSample)+127)/128);

一切顺利。

以防万一它可以帮助某人。

【讨论】:

以上是关于c ++和portaudio,输出严重失真的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Linux (Ubuntu) 中输出频率 1kHz 和功率/音量 = 60%?

C语言输出格式和类型

C语言输出如何右对齐?

c语言 怎样使计算是整数输出整数是小数输出两位小数

c语言怎样输出一个变量名?

c中如何输出一个字符的ASCII码