直接播放pcm格式练习

直接播放pcm格式练习

pcm直接使用 sdl播放,主要理解的是操作流程,就是将从文件读取出来的数据通过回调函数 copy到音频队列中,主线程和读取函数也就是回调函数是不在同一个线程中的,每次通过fread*读取到全局变量audio_chunk中,在回调函数中复制到音频设备。

#include 

#include 
#include 

extern  "C" {
    #include 
    #include 
    #include 
    #include 
    #include 
}

static SDL_Window       *window = nullptr;
static SDL_Renderer     *renderer = nullptr;
static SDL_RendererInfo  renderenInfo;
static SDL_Texture      *texture = nullptr;
static SDL_Surface      *surface = nullptr;

#ifdef __MINGW32__
#undef main
#endif

const size_t default_width = 640;
const size_t default_height = 480;

#define MY_EVENT (SDL_USEREVENT)

#include 

static ssize_t audio_len; 
static Uint8 *audio_pos; 
static Uint8 *audio_chunk;

#include 

/* @data:程序特定的参数,保存在SDL_AudioSpec结构体中
 * @stream:指向缓存区的指针,这个缓存区将被这个回调函数填满
 * @len:缓存区的数据长度(字节数)
 */
void read_audio(void *data, Uint8 *stream, int len) {
    qDebug() << GetCurrentThreadId();
    qDebug() << getpid();

    qDebug() << "-1";
    SDL_memset(stream, 0, len);
    if(audio_len == 0){
        return ;
    }

    len = (len>audio_len?audio_len : len);

    SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);
    audio_pos += len;
    audio_len -= len;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << GetCurrentThreadId();
    qDebug() << getpid();
    size_t data_count = 0;
    SDL_Init(SDL_INIT_AUDIO);

    SDL_AudioSpec spec;
    spec.freq = 44100;  //采样率
    spec.format = AUDIO_S16SYS;  //
    spec.channels = 2;  // 声音的通道数 1 单声道, 2 立体声;
    spec.silence = 0;  //表示静音的值。因为声音采样是有符号的,所以0当然就是这个值。
    spec.samples = 1024;  //
    spec.size = 1024; //音频缓存区大小(字节数),当我们想要更多声音的时候,我们想让SDL给出来的声音缓冲区的尺寸。一个比较合适的值在512到8192之间;ffplay使用1024。
    spec.callback = read_audio;

    SDL_OpenAudio(&spec, NULL);

    FILE *fp= fopen("./test.pcm", "rb+");
    if(fp == NULL){
        exit(-1);
    }

    int pcm_buffer_size = 4096;
    char *pcm_buffer = (char *)malloc(pcm_buffer_size );

    SDL_PauseAudio(0);

    while(1) {
        if(fread(pcm_buffer, 1, pcm_buffer_size, fp)!=pcm_buffer_size) {
            fseek(fp, 0, SEEK_SET);
            fread(pcm_buffer, 1, pcm_buffer_size, fp);
            data_count = 0;
        }
        printf("Now  Playing  %10d Bytes data. ", data_count);
        data_count += pcm_buffer_size;
        audio_chunk = (Uint8 *)pcm_buffer;
        audio_len = pcm_buffer_size;
        audio_pos = audio_chunk;
        qDebug() << "1";
        while(audio_len>0) {
            SDL_Delay(1);
        }
    }
    free(pcm_buffer);
    SDL_Quit();

    a.exec();

}


你可能感兴趣的:(FFMpeg)