我已经编写了一小段代码,旨在读取wav文件并通过portaudio播放它。
我将自己限制在某些特定的wav文件中:线性pcm(无压缩),最多2个通道。如我所见,wav文件解码工作正常,我相信以后通过portaudio播放它时会遇到麻烦。
对于我的测试,我选择了一个过于简单的wav文件(简短:8位比特深度,11025采样率,单声道和大约3秒长)。
因此,一旦我准备好所有样本,我就将它们送至portaudio(按比例缩放它们,使其在本教程示例中位于-1.0f和1.0f之间),并且我可以识别声音,但它失真得很严重...
我认为可能是因为采样率(大约11025 Hz非常标准),然后将其重新采样为Pa_getDeviceInfo-> getDefaultSampleRate(44100hz)给出的速率。
但我只是得到相同的结果。我还尝试选择另一台设备bt,但它并没有变得更好。
我从Bjorn Roche(http://blog.bjornroche.com/2011/11/slides-from-fundamentals-of-audio.html)的一些幻灯片中读到,我的缩放方法不好,但是我找不到其他选择。
可能是配置问题吗?还是我错过了有关采样和音频播放的重要事项? (这是我第一次进行音频编程)
顺便说一句,我在linux和alsa上使用portaudio,并且在初始化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;
}
谢谢阅读!
最佳答案
声音失真的原因如下:采样以无符号的8位格式存储,但是静音被定义为beign 255,因为我认为它为0。整个缩放顺序相反。
我改变了这一行:
*out++ = (float) ((data->getSample(::actualSample)-127)/128);
与
*out++ = (float) (((-1)*data->getSample(::actualSample)+127)/128);
一切顺利。
以防万一它可以帮助某人。