采样率
采样率可以通过mpg123_rates函数获取mpg123支持哪些采样率:
MPG123_EXPORT void mpg123_rates(const long **list, size_t *number);
通道数
定义:
/** They can be combined into one number (3) to indicate mono and stereo... */
enum mpg123_channelcount
{
MPG123_MONO = 1 /**< mono */
,MPG123_STEREO = 2 /**< stereo */
};
编码(格式)
编码(格式)可以通过mpg123_encodings函数获取mpg123支持哪些编码(格式):
MPG123_EXPORT void mpg123_encodings(const int **list, size_t *number);
获取音频格式:
MPG123_EXPORT int mpg123_getformat( mpg123_handle *mh
, long *rate, int *channels, int *encoding );
参数rate表示采样率
参数channels表示通道数
参数encoding表示编码(格式)
播放mp3格式的音频
#include<stdio.h> #include<string.h> #include<SDL_audio.h> #include<mpg123.h> #define CHUNK_SIZE 16384 #define INIT_CHUNK_LIST(chunk_list) \ { \ chunk_list.head = NULL; \ chunk_list.tail = NULL; \ chunk_list.ptr = NULL; \ chunk_list.ptr_pos = 0; \ } typedef struct chunk { unsigned char data[CHUNK_SIZE]; int size; struct chunk *next; } chunk_t; typedef struct { struct chunk *head; struct chunk *tail; struct chunk *ptr; int ptr_pos; } chunk_list_t; #define BUFFER_SIZE 16384 chunk_list_t chunk_list; struct chunk* alloc_chunk() { struct chunk *ptr = (struct chunk *) malloc(sizeof(struct chunk)); memset(ptr, 0, sizeof(struct chunk)); return ptr; } int chunk_list_empty(chunk_list_t *chunk_list) { return chunk_list->head == NULL && chunk_list->tail == NULL; } void chunk_list_add(chunk_list_t *chunk_list, chunk_t *chunk) { if (chunk_list_empty(chunk_list)) { chunk_list->head = chunk; chunk_list->tail = chunk; } else { chunk_list->tail->next = chunk; chunk_list->tail = chunk; } } void callback_on_take_sample(void *unused, Uint8 *stream, int len) { chunk_list_t* chunk_list = (chunk_list_t *) (unused); chunk_t *ptr; next: ptr = chunk_list->ptr; if (ptr == NULL) { SDL_PauseAudio(1); return; } int amount = ptr->size - chunk_list->ptr_pos; if (amount > len) { amount = len; } if (amount <= 0) { chunk_list->ptr = ptr->next; chunk_list->ptr_pos = 0; goto next; } printf("audio: len= %u, pos= %u. audio buffer: @%p, len= %d, amount= %d\n", ptr->size, chunk_list->ptr_pos, stream, len, amount); SDL_memcpy(stream, ptr->data + chunk_list->ptr_pos, amount); chunk_list->ptr_pos += amount; } void memdump(unsigned char* in, size_t size) { int i; for (i = 0; i < size; i++) { fprintf(stdout, "%.2X ", in[i]); } fprintf(stdout, "\n"); } int read_chunk_internal_handle(mpg123_handle *handle, chunk_t* chunk, int *state) { int result = 0; size_t nbytes; while(chunk->size < CHUNK_SIZE) { result = mpg123_decode(handle, NULL, 0, chunk->data + chunk->size, CHUNK_SIZE - chunk->size, &nbytes); if (result == MPG123_ERR) { fprintf(stderr, "decode err: %d\n", result); return 1; } fprintf(stdout, "decode: result=%d, actually decoded bytes=%u\n", result, nbytes); if (nbytes > 0) { chunk->size += nbytes; } if (result == MPG123_NEW_FORMAT) { *state = result; } if (result == MPG123_NEED_MORE) { break; } if (result == MPG123_DONE) { *state = result; break; } } return 0; } int read_chunk(FILE *fp, mpg123_handle *handle, chunk_t* chunk, int *state) { int result = 0; size_t nbytes; //fprintf(stdout, "reading from internal handle...\n"); result = read_chunk_internal_handle(handle, chunk, state); if (result) { return result; } //fprintf(stdout, "reading from fp...\n"); while(chunk->size < CHUNK_SIZE) { char buf[BUFFER_SIZE]; nbytes = fread(buf, 1, sizeof(buf), fp); result = ferror(fp); if (result) { fprintf(stderr, "read err: %d\n", result); return 1; } if (feof(fp)) { return -1; } fprintf(stdout, "read: %d bytes\n", nbytes); result = mpg123_decode(handle, buf, nbytes, chunk->data + chunk->size, CHUNK_SIZE - chunk->size, &nbytes); if (result == MPG123_ERR) { fprintf(stderr, "decode err: %d\n", result); return 1; } fprintf(stdout, "decode: result=%d, actually decoded bytes=%u\n", result, nbytes); if (nbytes > 0) { chunk->size += nbytes; } if (result == MPG123_NEW_FORMAT) { *state = result; } if (result == MPG123_DONE) { break; } } return 0; } // .\mpg123_test h:\\yuganqingwuguan.mp3 int main(int argc, char** argv) { int result = 0; char *filename; FILE *fp; chunk_t *chunk; const char **decoders; const char **supported_decoders; mpg123_handle *handle; SDL_AudioSpec audio_spec_desired; SDL_AudioSpec audio_spec_obtained; int i; if (argc != 2) { fprintf(stderr, "invalid args\n"); return 1; } filename = argv[1]; INIT_CHUNK_LIST(chunk_list); result = mpg123_init(); if (result != MPG123_OK) { fprintf(stderr, "init err: %d\n", result); return 1; } fprintf(stdout, "available decoder list: \n"); decoders = mpg123_decoders(); for (i = 0; decoders[i] != NULL; i++) { fprintf(stdout, "\t%d: %s\n", i, decoders[i]); } supported_decoders = mpg123_supported_decoders(); fprintf(stdout, "decoders supported: \n"); for (i = 0; supported_decoders[i] != NULL; i++) { fprintf(stdout, "\t%d: %s\n", i, supported_decoders[i]); } handle = mpg123_new(NULL, &result); if (handle == NULL) { fprintf(stderr, "new err: %d\n", result); } fprintf(stdout, "current decoder: %s\n", mpg123_current_decoder(handle)); result = mpg123_open_feed(handle); if (result != MPG123_OK) { fprintf(stderr, "open feed err: %d\n", result); return 1; } fp = fopen(filename, "rb"); if (fp == NULL) { fprintf(stderr, "open err: %s\n", filename); return 1; } i = 0; while (result != MPG123_DONE) { int ret = 0; chunk = alloc_chunk(); ret = read_chunk(fp, handle, chunk, &result); if (ret) { if (ret == -1) { break; } fprintf(stderr, "read chunk err\n"); return 1; } i++; fprintf(stdout, "%d chunk readed...\n", i); chunk_list_add(&chunk_list, chunk); if (result == MPG123_NEW_FORMAT) { long rate; int channels; int encoding; result = mpg123_getformat(handle, &rate, &channels, &encoding); if (result != MPG123_OK) { fprintf(stderr, "get format err: %d\n", result); return 1; } fprintf(stdout, "format: rate=%ld, channels=%d, encoding=%d\n", rate, channels, encoding); chunk_list.ptr = chunk_list.head; audio_spec_desired.freq = rate; audio_spec_desired.format = AUDIO_S16; audio_spec_desired.samples = 4096; audio_spec_desired.callback = callback_on_take_sample; audio_spec_desired.userdata = &chunk_list; audio_spec_desired.channels = channels; if (SDL_OpenAudio(&audio_spec_desired, &audio_spec_obtained) < 0) { fprintf(stderr, "open audio err: %s\n", SDL_GetError()); return -1; } } } SDL_PauseAudio(0); printf("playing...%s\n", filename); while ((SDL_GetAudioStatus() == SDL_AUDIO_PLAYING)) { SDL_Delay(1000); } printf("played!\n"); SDL_CloseAudio(); SDL_Quit(); }
编译
这里一次性完成编译链接。编译的时候注意通过“-I”指定头文件目录,在链接的时候通过“-L”指定要链接的静态库文件目录,以及通过“-l”指定要链接的静态库。
gcc -I/usr/local/SDL2-2.0.7/include/SDL2 -L/usr/local/lib -L/usr/local/SDL2-2.0.7/lib mpg123_test.c -o mpg123_test -lSDL2 -lmpg123
运行
如果是在Cygwin下,在运行之前SDL2.dll、cygmpg123-0.dll拷贝到程序目录下:
>cp -rf d:\sbin\usr\local\sdl\bin\SDL2.dll .
>cp -rf D:\sbin\usr\local\bin\cygmpg123-0.dll .
>.\mpg123_test h:\\yuganqingwuguan.mp3
相关推荐
hi3559a交叉编译freetype-2.10.1+SDL2-2.0.12+SDL2_ttf-2.0.15 +测试代码。包括库文件,每个包下面有个build.sh脚本,分别执行脚本即可。(这是linux下的压缩包,其他系统无法解压)
mpg123是优秀的mp3播放器,这是源码包,在嵌入式开发声卡中,可以利用该源码进行交叉编译实现MP3播放。
此项目的最新版本为v0.3,它提供了Go编程语言对Simple DirectMedia Layer(SDL2)的绑定,允许Go开发者利用SDL2的强大功能进行游戏开发、多媒体处理和其他图形用户界面相关的应用。 SDL2是一个跨平台的开发库,广泛...
FFmpeg再学习 -- FFmpeg+SDL+MFC实现图形界面视频播放器-附件资源
SDL音频部分包括音频缓冲区管理和混合,支持多种音频格式,并且提供了一套事件驱动的模型来处理音频播放。 **FFmpeg详解** FFmpeg是一个强大的开源多媒体框架,用于处理音频、视频、图像等多种格式的数据。它包含了...
Linux下的Simple DirectMedia Layer(SDL)是一个开源的跨平台开发库,主要用于处理多媒体、图形界面、游戏开发等任务。SDL库提供了丰富的功能,包括硬件加速的2D图形、音频输入和输出、键盘和鼠标事件处理、游戏...
首先,SDL是一个低级别的多媒体库,它为开发者提供了处理图形、音频、输入设备等的能力,特别适合用于游戏开发和多媒体应用。它的主要特点包括: 1. **图形渲染**:SDL提供了一套API,可以创建窗口、渲染2D图形,并...
3. **07linux-sdl-thread**:多线程编程在现代应用中至关重要,特别是在处理音视频时。这部分会讲解如何在SDL中创建和管理线程,以实现并发任务,比如同时播放音频和渲染视频。 4. **08linux-sdl-playyuv**:YUV是...
在本资源包中,我们主要关注的是C语言与SDL2库结合进行游戏编程的基础知识。SDL2(Simple DirectMedia Layer 2)是一个跨平台的开发库,它为开发者提供了丰富的功能,包括图形渲染、音频处理、事件管理等,是创建2D...
QT + ffmpeg + SDL音频播放器是一种利用开源库组合来实现音频播放的应用程序。在这个项目中,QT是一个跨平台的C++应用程序开发框架,用于构建用户界面;ffmpeg是一个强大的多媒体处理库,负责音频和视频的解码;而...
ffmpeg+sdl播放器解码视音频,使用ffmpeg-2.5.2+SDL-1.2.15,参考ffmpeg官方例子,欢迎交流 内含10个工程 1.保存为bmp图片 2.解码视频 3.解码视频, 音频 4.分离代码,加入线程(伪同步) 5.视频同步到音频 6.音频同步到...
**标题与描述解析** 标题"SDL2-2.0.2"指的是...熟悉C/C++编程是必要的,因为这是SDL2主要支持的语言。对于Linux运维人员来说,理解如何在服务器上安装、管理和更新SDL2库,以及解决相关的依赖问题,也是重要的技能。
SDL提供了基本的窗口管理、图像渲染、音频播放和键盘/鼠标输入处理等功能,是许多初学者和专业开发者入门游戏编程的首选库。 在"tank-sdl-0.3.0"源代码中,我们可以学习到以下关键点: 1. **游戏循环**:任何游戏...
在Linux环境下,使用FFmpeg和SDL(Simple DirectMedia Layer)框架...这个过程中涉及的知识点包括音视频编码解码原理、多媒体文件格式、流处理技术、图形用户界面编程等,是深入理解多媒体处理和Linux开发的重要实践。
SDL2(Simple DirectMedia Layer 2)是一个跨平台的开发库,用于处理图形、音频、输入设备等多媒体元素。它在游戏开发领域特别受欢迎,因为它的API简洁高效,并且支持多种操作系统,包括Windows、Linux、Mac OS X...
这个Go绑定使得Go程序员能够利用C语言的SDL2库的强大功能,而无需直接处理C语言的复杂性。 Go-sdl2是Go语言中的一个开源项目,它为Go程序员提供了与SDL2库交互的API。这包括窗口管理、事件处理、图像渲染、音频处理...
SDL2(Simple DirectMedia Layer)则是一个跨平台的开发库,用于处理图形用户界面、音频和输入设备,常用于游戏开发和多媒体应用。 在这个"ffmpeg+SDL2实现的音频播放器V2.0(无杂音)"项目中,开发者利用 FFmpeg ...
- 音频回调函数:开发者可以注册一个回调函数,每当需要填充音频缓冲区时,SDL会自动调用该函数,将处理后的音频数据填入缓冲区。 - 音频格式转换:SDL支持多种音频格式,如果原始音频数据与目标设备不兼容,SDL...
**C-SDL:C语言SDL解析器解释器** C-SDL是一个基于C语言实现的SDL(Simple DirectMedia Layer)解析器和解释器。SDL库是一个跨平台的开发库,主要用于多媒体应用开发,如游戏、图形界面和音频处理。C-SDL项目的目标...