欢迎访问宙启技术站
智能推送

使用paContinue()函数实现音频流的连续播放

发布时间:2023-12-17 10:12:33

paContinue()函数是PortAudio库中的一个函数,用于指示回调函数继续读取音频数据进行播放。下面是使用paContinue()函数实现音频流的连续播放的一个例子。

#include <stdio.h>
#include "portaudio.h"

#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024)
#define NUM_SECONDS (5)

typedef struct {
    float *data;
    int frameIndex;
    int maxFrameIndex;
} AudioData;

AudioData audioData;

int audioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer,
                  const PaStreamCallbackTimeInfo *timeInfo,
                  PaStreamCallbackFlags statusFlags, void *userData) {
    float *out = (float *)outputBuffer;
    AudioData *data = (AudioData *)userData;
    int framesLeft = data->maxFrameIndex - data->frameIndex;

    if (framesLeft < framesPerBuffer) {
        // If there are not enough frames left, fill the buffer with silence
        memset(out, 0, sizeof(float) * framesPerBuffer);
        return paComplete;
    } else {
        // Fill the buffer with audio data
        memcpy(out, &(data->data[data->frameIndex]), sizeof(float) * framesPerBuffer);
        data->frameIndex += framesPerBuffer;
        return paContinue;
    }
}

int main(void) {
    PaStream *stream;
    PaError err;

    // Initialize PortAudio
    err = Pa_Initialize();
    if (err != paNoError) {
        printf("Failed to initialize PortAudio: %s
", Pa_GetErrorText(err));
        return 1;
    }

    // Initialize audio data
    audioData.data = (float *)malloc(sizeof(float) * SAMPLE_RATE * NUM_SECONDS);
    audioData.frameIndex = 0;
    audioData.maxFrameIndex = SAMPLE_RATE * NUM_SECONDS;
    // Fill audio data with some waveform
    for (int i = 0; i < audioData.maxFrameIndex; i++) {
        audioData.data[i] = (float)sin(2 * M_PI * 440 / SAMPLE_RATE * i);
    }

    // Open the stream
    err = Pa_OpenDefaultStream(&stream, 0, 1, paFloat32, SAMPLE_RATE, FRAMES_PER_BUFFER,
                               audioCallback, &audioData);
    if (err != paNoError) {
        printf("Failed to open stream: %s
", Pa_GetErrorText(err));
        return 1;
    }

    // Start the stream
    err = Pa_StartStream(stream);
    if (err != paNoError) {
        printf("Failed to start stream: %s
", Pa_GetErrorText(err));
        return 1;
    }

    // Wait for the stream to finish
    Pa_Sleep(NUM_SECONDS * 1000);

    // Stop and close the stream
    err = Pa_StopStream(stream);
    if (err != paNoError) {
        printf("Failed to stop stream: %s
", Pa_GetErrorText(err));
        return 1;
    }
    err = Pa_CloseStream(stream);
    if (err != paNoError) {
        printf("Failed to close stream: %s
", Pa_GetErrorText(err));
        return 1;
    }

    // Terminate PortAudio
    err = Pa_Terminate();
    if (err != paNoError) {
        printf("Failed to terminate PortAudio: %s
", Pa_GetErrorText(err));
        return 1;
    }

    free(audioData.data);

    return 0;
}

以上代码演示了使用paContinue()函数实现音频流的连续播放。代码首先通过Pa_Initialize()函数初始化了PortAudio库。然后创建了一个结构体AudioData,用于存储音频数据和相关参数。回调函数audioCallback()中,根据还剩下的音频帧数决定是填充音频数据还是填充静音。在main()函数中,通过Pa_OpenDefaultStream()函数打开音频流。使用Pa_StartStream()函数启动音频流的播放。通过Pa_Sleep()函数让程序等待一段时间,然后调用Pa_StopStream()函数停止音频流的播放,并通过Pa_CloseStream()函数关闭音频流。最后通过Pa_Terminate()函数终止PortAudio库的使用。

这个例子会播放一个长度为5秒的纯音频波形,示例中使用了sin函数生成了一个440Hz的正弦波。