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,输出严重失真的主要内容,如果未能解决你的问题,请参考以下文章