Я написал небольшой фрагмент кода, который намеревается прочитать файл wav и воспроизвести его через portaudio.
Я ограничился некоторыми конкретными файлами WAV: линейный PCM (без сжатия), не более 2 каналов. Как я вижу, декодирование wav-файлов работает просто отлично, я думаю, что позже у меня проблемы с воспроизведением через portaudio.
Для своих тестов я выбрал слишком простой WAV-файл (короткий: битовая глубина 8 бит, частота дискретизации 11025, моно и длительность около 3 секунд).
Итак, как только я собрал все свои сэмплы, я передал их portaudio (сваливая их так, что они между -1.0f и 1.0f, как в учебном примере), и я смог распознать звук, но он был ужасно искажен …
Я подумал, что это может быть из-за частоты дискретизации (хотя стандартная частота составляет 11025 Гц), и заново сэмплировал ее до частоты, указанной в Pa_getDeviceInfo-> getDefaultSampleRate (44100hz).
Но я просто получаю тот же результат. Я также попытался выбрать другое устройство, но оно не улучшается.
Я читал в некоторых слайдах от Бьорн Рош (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);
и все прошло хорошо.
на всякий случай это может кому-то помочь.
Других решений пока нет …