sdl play .pcm

{

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <iostream>
#include <SDL.h>
 
static Uint8 *pAudio_chunk;
static Uint32 audio_len;
static Uint8 *pAudio_pos;
 
void fill_audio_buffer(void *userdata, Uint8 * stream, int len)
{
    SDL_memset(stream, 0, len);
    // 判断是否有读到数据
    if (audio_len == 0)
        return;
 
    len = (len > audio_len ? audio_len : len);
    SDL_MixAudio(stream, pAudio_pos, len, SDL_MIX_MAXVOLUME);
    pAudio_pos += len;
    audio_len -= len;
}
 
int SDL_main(int argc, char *argv[])
//int main(int argc, char *argv[])
{
 
 
    /*** 初始化SDL ***/
    if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER))
    {
        printf("Initialize SDL failed: %s\n", SDL_GetError());
        return -1;
    }
    /****************/
 
    /*** 初始化初始化SDL_AudioSpec结构体 ***/
    SDL_AudioSpec audioSpec;
 
    // 音频数据的采样率。常用的有48000,44100等
    audioSpec.freq = 48000;
 
    // 音频数据的格式
    audioSpec.format = AUDIO_F32LSB;
 
    // 声道数。例如单声道取值为1,立体声取值为2
    audioSpec.channels = 2;
 
    // 设置静音的值
    audioSpec.silence = 0;
 
    // 音频缓冲区中的采样个数,要求必须是2的n次方
    audioSpec.samples = 1024;
 
    // 填充音频缓冲区的回调函数
    audioSpec.callback = fill_audio_buffer;
    /************************************/
 
    // 打开音频设备
    if (SDL_OpenAudio(&audioSpec, nullptr) < 0)
    {
        printf("Can not open audio!");
        return -1;
    }
 
    FILE *pAudioFile = fopen("D:/out.pcm", "rb+");
    if (pAudioFile == nullptr)
    {
        printf("Can not open audio file!");
        return -1;
    }
 
    int pcm_buffer_size = 48000;
    char *pcm_buffer = (char *)malloc(pcm_buffer_size);
    int data_count = 0;
 
    SDL_PauseAudio(0);
 
    for (;;)
    {
        // 循环播放
        if (fread(pcm_buffer, 1, pcm_buffer_size, pAudioFile) != pcm_buffer_size)
        {
            fseek(pAudioFile, 0, SEEK_SET);
            fread(pcm_buffer, 1, pcm_buffer_size, pAudioFile);
            data_count = 0;
        }
        printf("Playing %10d Bytes data.\n", data_count);
        data_count += pcm_buffer_size;
 
        pAudio_chunk = (Uint8 *)pcm_buffer;
        audio_len = pcm_buffer_size;
        pAudio_pos = pAudio_chunk;
 
        while (audio_len > 0)
            SDL_Delay(0);
    }
    free(pcm_buffer);
    SDL_Quit();
 
    return 0;
}

 

}

posted @   YZFHKMS-X  阅读(101)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示