Question

I have written a small piece of code which intents to read a wav file and play it through portaudio.

I restrained myself to some particular wav files : linear pcm (no compression) , no more than 2 channels. As i can see, the wav file decoding works just fine, i believe i'm in trouble later when playing it through portaudio.

For my tests i choosed an overly simple wav file (short : 8 bits bitdepth, 11025 sample rate, mono and about 3 sec long).

So, once i got all my samples ready i did give them to portaudio (scalling them so they're between -1.0f and 1.0f as in the tutorial example) and i could recognize the sound but it was horribly distorted...

I thought it could be because of the sample rate (altough 11025 hz is quite standard) and re-sampled it to the rate given by Pa_getDeviceInfo->getDefaultSampleRate (44100hz).

But i just get the same result. I also tried selecting another device bt still it doesn't get better.

I read in some slides from Bjorn Roche (http://blog.bjornroche.com/2011/11/slides-from-fundamentals-of-audio.html) that my scaling approach wasn't good but i found no alternative.

Could it be a configuration problem? Or did i miss something important about sampling and audio playback? (this is my first shot at audio programming)

By the way i'm using linux and alsa with portaudio and i get these error message when initializing 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)

I defined my callback function as follow : (only to play this particular file)

    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;
    }

Thanks for reading!

Was it helpful?

Solution

The reason the sound was distorted is the following : the samples were stored in unsigned 8 bits format, but silence was defined with the sample value beign 255 as i would consider it to be 0. the whole scaling is in reverse order.

I changed the line :

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

with

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

and it all went good.

just In case it could help someone.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top