Domanda

This has me stumped; this works perfectly in mono, but when I change it to stereo it sounds choppy and staticy. Is this an interleaving issue or something (the data is interleaved, btw)

Edit: Changed the interleaving method to something more logical, but still to no avail...

    #include <pthread.h>
    #include <portaudio/portaudio.h>
    #include <sndfile.h>

    #define STEREO 2
    #define SAMPLE_RATE 44100

    typedef struct{
        M_float* data, *data_pos;
        sf_count_t frames;
    } StreamData;
    StreamData stream_data;

    int ProcessAudio(const void* input, void* output, ulong frames_per_buff,
            const PaStreamCallbackTimeInfo* time_info, PaStreamCallbackFlags flags, void* strm_data){

    M_StreamData* strm = (M_StreamData*)(strm_data);
    M_float* strm_out = (M_float*)(output);

    if(strm -> frames > frames_per_buff){

        for(sf_count_t frames_iter = 0; frames_iter < frames_per_buff;){
            M_float sample = (strm -> data_pos++)[0];
            strm_out[frames_iter] = sample;
            strm_out[++frames_iter] = sample;
        }

    }else{
        return (paComplete);
    }

    return (paContinue);
}

    void* StartAudio(void* params){
        SF_INFO info;
        info.channels = M_STEREO;
        info.samplerate = M_SAMPLE_RATE;
        info.format = SF_FORMAT_RAW | SF_FORMAT_FLOAT;

        SNDFILE* file = sf_open(u8"californication.raw", SFM_READ, &info);

        stream_data.data = malloc(info.frames * info.channels * sizeof(float));
        stream_data.data_pos = stream_data.data;
        stream_data.frames = sf_readf_float(file, stream_data.data, info.frames);

        sf_close(file);

        if(Pa_Initialize() != paNoError)exit(0);

        PaStream* pa_stream = NULLPTR_T;
        Pa_OpenDefaultStream(&pa_stream, 0, STEREO, paFloat32, SAMPLE_RATE, paFramesPerBufferUnspecified,
                &ProcessAudio, &stream_data);

        Pa_StartStream(pa_stream);
        Pa_Sleep(9001);
        Pa_StopStream(pa_stream);
        Pa_CloseStream(pa_stream);

        sf_close(file);
        free(stream_data.data);

        Pa_Terminate();

        return (NULLPTR_T);
    }

    int main(void){
        static pthread_t thrd;
        pthread_create(&thrd, NULLPTR_T, &M_StartAudio, NULLPTR_T);

        return (false);
    }
È stato utile?

Soluzione

I can't be certain without compiling your code, but it looks like your interleaving algorithm is writing two samples to the same index in your output buffer rather than writing one sample to the output buffer twice.

This code:

  strm_out[frames_iter] = (strm -> data_pos++)[0];
  strm_out[frames_iter] = (strm -> data_pos++)[1];

Should look something like:

M_float* sample =  (strm -> data_pos++)[0]; 
strm_out[frames_iter] = sample;
strm_out[++frames_iter] = sample;

Again this may not be exactly right, but hopefully it illustrates my point.

Altri suggerimenti

Try changing framesPerBuffer to a fixed value. Values that are evenly divisible by 44100 might work best. 4410 and 441 might be good places to start.

I have also had issues with using the default stream. In Linux I usually specify the device I want to use explicitly as opposed to using pulse or default. You can use aplay -l to get the list of devices on your system. Choose the index of the device you want to use. Use that index when opening the portaudio stream.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top