音频处理
采样率
音频格式
+----------------------sample is signed if set | | +----------sample is bigendian if set | | | | +--sample is float if set | | | | | | +--sample bit size---+ | | | | | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
各字段解释
sample is signed if set:
对应下面的signed,unsigned。
sample is bigendian if set:
对应下面的little-endian byte order,big-endian byte order。
sample is float if set:
对应下面的floating point。
sample bit size:
有8位,16位,32位的。对应下面的8-bit support,16-bit support,32-bit support。
8-bit support |
|
AUDIO_S8 |
signed 8-bit samples |
AUDIO_U8 |
unsigned 8-bit samples |
16-bit support |
|
AUDIO_S16LSB |
signed 16-bit samples in little-endian byte order |
AUDIO_S16MSB |
signed 16-bit samples in big-endian byte order |
AUDIO_S16SYS |
signed 16-bit samples in native byte order |
AUDIO_S16 |
AUDIO_S16LSB |
AUDIO_U16LSB |
unsigned 16-bit samples in little-endian byte order |
AUDIO_U16MSB |
unsigned 16-bit samples in big-endian byte order |
AUDIO_U16SYS |
unsigned 16-bit samples in native byte order |
AUDIO_U16 |
AUDIO_U16LSB |
32-bit support (new to SDL 2.0) |
|
AUDIO_S32LSB |
32-bit integer samples in little-endian byte order |
AUDIO_S32MSB |
32-bit integer samples in big-endian byte order |
AUDIO_S32SYS |
32-bit integer samples in native byte order |
AUDIO_S32 |
AUDIO_S32LSB |
float support (new to SDL 2.0) |
|
AUDIO_F32LSB |
32-bit floating point samples in little-endian byte order |
AUDIO_F32MSB |
32-bit floating point samples in big-endian byte order |
AUDIO_F32SYS |
32-bit floating point samples in native byte order |
AUDIO_F32 |
AUDIO_F32LSB |
/**
* \name Audio format flags
*
* Defaults to LSB byte order.
*/
/* @{ */
#define AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */
#define AUDIO_S8 0x8008 /**< Signed 8-bit samples */
#define AUDIO_U16LSB 0x0010 /**< Unsigned 16-bit samples */
#define AUDIO_S16LSB 0x8010 /**< Signed 16-bit samples */
#define AUDIO_U16MSB 0x1010 /**< As above, but big-endian byte order */
#define AUDIO_S16MSB 0x9010 /**< As above, but big-endian byte order */
#define AUDIO_U16 AUDIO_U16LSB
#define AUDIO_S16 AUDIO_S16LSB
/* @} */
/**
* \name int32 support
*/
/* @{ */
#define AUDIO_S32LSB 0x8020 /**< 32-bit integer samples */
#define AUDIO_S32MSB 0x9020 /**< As above, but big-endian byte order */
#define AUDIO_S32 AUDIO_S32LSB
/* @} */
/**
* \name float32 support
*/
/* @{ */
#define AUDIO_F32LSB 0x8120 /**< 32-bit floating point samples */
#define AUDIO_F32MSB 0x9120 /**< As above, but big-endian byte order */
#define AUDIO_F32 AUDIO_F32LSB
/* @} */
/**
* \name Native audio byte ordering
*/
/* @{ */
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
#define AUDIO_U16SYS AUDIO_U16LSB
#define AUDIO_S16SYS AUDIO_S16LSB
#define AUDIO_S32SYS AUDIO_S32LSB
#define AUDIO_F32SYS AUDIO_F32LSB
#else
#define AUDIO_U16SYS AUDIO_U16MSB
#define AUDIO_S16SYS AUDIO_S16MSB
#define AUDIO_S32SYS AUDIO_S32MSB
#define AUDIO_F32SYS AUDIO_F32MSB
#endif
通道
音频播放
* The calculated values in this structure are calculated by SDL_OpenAudio().
*
* For multi-channel audio, the default SDL channel mapping is:
* 2: FL FR (stereo)
* 3: FL FR LFE (2.1 surround)
* 4: FL FR BL BR (quad)
* 5: FL FR FC BL BR (quad + center)
* 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR)
* 7: FL FR FC LFE BC SL SR (6.1 surround)
* 8: FL FR FC LFE BL BR SL SR (7.1 surround)
*/
typedef struct SDL_AudioSpec
{
int freq; /**< DSP frequency -- samples per second */
SDL_AudioFormat format; /**< Audio data format */
Uint8 channels; /**< Number of channels: 1 mono, 2 stereo */
Uint8 silence; /**< Audio buffer silence value (calculated) */
Uint16 samples; /**< Audio buffer size in sample FRAMES (total samples divided by channel count) */
Uint16 padding; /**< Necessary for some compile environments */
Uint32 size; /**< Audio buffer size in bytes (calculated) */
SDL_AudioCallback callback; /**< Callback that feeds the audio device (NULL to use SDL_QueueAudio()). */
void *userdata; /**< Userdata passed to callback (ignored for NULL callbacks). */
} SDL_AudioSpec;
各字段解释:
freq
采样率
format
音频数据格式
channels
通道数
silence
静默
samples
padding
size
音频缓冲区大小
callback
回调函数
函数原型
void SDLCALL SDL_AudioCallback(void *userdata, Uint8 * stream, int len);
第1个参数userdata是由用户自定义(application-specific)传递的参数,这个参数由userdata指定;
第2个参数stream表示指向音频数据缓冲区的指针;
第3个参数len表示缓冲区大小(字节数)。
userdata
用户自定义(application-specific)传递的数据
播放wav格式的音频
#include<stdio.h> #include<SDL_audio.h> struct sample { Uint8 *data; Uint32 d_pos; Uint32 d_len; } audio; void sdl_callback(void *unused, Uint8 *stream, int len) { int amount = audio.d_len - audio.d_pos; if (amount > len) { amount = len; } if (amount <= 0) { SDL_PauseAudio(1); return; } SDL_memcpy(stream, audio.data + audio.d_pos, amount); audio.d_pos += amount; } // mp h:\\sample.wav // mp h:\\yuganqingwuguan-c_a_wmav2.wav // mp h:\\yuganqingwuguan.wav int main(int argc, char **argv) { char *filename; SDL_AudioSpec audio_spec; if (argc != 2) { fprintf(stderr, "invalid args...\n"); return 1; } filename = *(argv + 1); if (SDL_LoadWAV(filename, &audio_spec, &audio.data, &audio.d_len) == NULL) { fprintf(stderr, "load wav err: %s\n", SDL_GetError()); return 1; } audio_spec.callback = sdl_callback; audio_spec.userdata = NULL; if (SDL_OpenAudio(&audio_spec, NULL) < 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_FreeWAV(audio.data); SDL_Quit(); return 0; }
编译
这里一次性完成编译链接。编译的时候注意通过“-I”指定头文件目录,在链接的时候通过“-L”指定要链接的静态库文件目录,以及通过“-l”指定要链接的静态库。
gcc -I D:\sbin\usr\local\sdl\include\SDL2 -L D:\sbin\usr\local\sdl\lib sdl_test.c -o sdl_test -lSDL2
运行
在运行之前SDL2.dll拷贝到程序目录下:
>cp -rf d:\sbin\usr\local\sdl\bin\SDL2.dll .
mp h:\\sample.wav
mp h:\\yuganqingwuguan-c_a_wmav2.wav
mp h:\\yuganqingwuguan.wav
#include<stdio.h> #include<SDL_audio.h> #include<SDL_log.h> struct sample { Uint8 *data; Uint32 d_pos; Uint32 d_len; } audio; void sdl_callback(void *unused, Uint8 *stream, int len) { int amount = audio.d_len - audio.d_pos; if (amount > len) { amount = len; } printf("audio: len= %u, pos= %u. audio buffer: @%p, len= %d, amount= %d\n", audio.d_len, audio.d_pos, stream, len, amount); if (amount <= 0) { SDL_PauseAudio(1); return; } SDL_memcpy(stream, audio.data + audio.d_pos, amount); audio.d_pos += amount; } void display_audio_spec(SDL_AudioSpec *audio_spec) { printf("audio: freq...%d\n", audio_spec->freq); printf("audio: format...%d\n", audio_spec->format); printf("audio: channels...%d\n", audio_spec->channels); printf("audio: silence...%d\n", audio_spec->silence); printf("audio: samples...%d\n", audio_spec->samples); printf("audio: padding...%d\n", audio_spec->padding); printf("audio: size...%d\n", audio_spec->size); printf("audio: callback...%p\n", audio_spec->callback); } // mp h:\\sample.wav // mp h:\\yuganqingwuguan-c_a_wmav2.wav // mp h:\\yuganqingwuguan.wav int main(int argc, char **argv) { char *filename; Uint8 *data; Uint32 d_len; SDL_AudioSpec audio_spec; SDL_AudioCVT audio_cvt; if (argc != 2) { fprintf(stderr, "invalid args...\n"); return 1; } display_audio_spec(&audio_spec); filename = *(argv + 1); if (SDL_LoadWAV(filename, &audio_spec, &data, &d_len) == NULL) { fprintf(stderr, "load wav err: %s\n", SDL_GetError()); return 1; } display_audio_spec(&audio_spec); /* if (SDL_BuildAudioCVT(&audio_cvt, audio_spec.format, audio_spec.channels, audio_spec.freq, AUDIO_S16, 1, 22050) < 0) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "build audio cvt err: %s\n", SDL_GetError()); return 1; } */ /* if (SDL_BuildAudioCVT(&audio_cvt, audio_spec.format, audio_spec.channels, audio_spec.freq, AUDIO_S16, 2, 22050) < 0) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "build audio cvt err: %s\n", SDL_GetError()); return 1; } */ /* if (SDL_BuildAudioCVT(&audio_cvt, audio_spec.format, audio_spec.channels, audio_spec.freq, audio_spec.format, audio_spec.channels, audio_spec.freq) < 0) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "build audio cvt err: %s\n", SDL_GetError()); return 1; } */ /* if (SDL_BuildAudioCVT(&audio_cvt, audio_spec.format, audio_spec.channels, audio_spec.freq, AUDIO_S16, audio_spec.channels == 1 ? audio_spec.channels : 2, audio_spec.freq) < 0) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "build audio cvt err: %s\n", SDL_GetError()); return 1; } //*/ //* if (SDL_BuildAudioCVT(&audio_cvt, audio_spec.format, audio_spec.channels, audio_spec.freq, AUDIO_S16, audio_spec.channels == 1 ? audio_spec.channels : 2, 34100) < 0) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "build audio cvt err: %s\n", SDL_GetError()); fprintf(stderr, "build audio cvt err: %s\n", SDL_GetError()); return 1; } //*/ /* if (SDL_BuildAudioCVT(&audio_cvt, audio_spec.format, audio_spec.channels, audio_spec.freq, AUDIO_S16, audio_spec.channels == 1 ? audio_spec.channels : 2, 44100) < 0) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "build audio cvt err: %s\n", SDL_GetError()); fprintf(stderr, "build audio cvt err: %s\n", SDL_GetError()); return 1; } //*/ /* if (SDL_BuildAudioCVT(&audio_cvt, audio_spec.format, audio_spec.channels, audio_spec.freq, AUDIO_S16, audio_spec.channels == 1 ? audio_spec.channels : 2, 84100) < 0) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "build audio cvt err: %s\n", SDL_GetError()); fprintf(stderr, "build audio cvt err: %s\n", SDL_GetError()); return 1; } //*/ audio_cvt.len = d_len; audio_cvt.buf = (Uint8 *) SDL_malloc(audio_cvt.len * audio_cvt.len_mult); memcpy(audio_cvt.buf, data, d_len); SDL_ConvertAudio(&audio_cvt); SDL_FreeWAV(data); SDL_LockAudio(); audio.data = audio_cvt.buf; audio.d_len = audio_cvt.len_cvt; audio.d_pos = 0; SDL_UnlockAudio(); // audio_spec.silence = 1; // 这个设置没用, 由SDL_OpenAudio()计算设置。 audio_spec.callback = sdl_callback; audio_spec.userdata = NULL; if (SDL_OpenAudio(&audio_spec, NULL) < 0) { fprintf(stderr, "open audio err: %s\n", SDL_GetError()); return -1; } display_audio_spec(&audio_spec); SDL_PauseAudio(0); printf("playing...%s\n", filename); while ((SDL_GetAudioStatus() == SDL_AUDIO_PLAYING)) { SDL_Delay(1000); } printf("played!\n"); SDL_CloseAudio(); SDL_FreeWAV(audio.data); SDL_Quit(); return 0; }
如果在程序中包含了SDL.h这个头文件:
#include<SDL.h>
编译链接的时候报如下错误:
/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../libcygwin.a(libcmain.o): In
function `main':
/usr/src/debug/cygwin-1.7.18-1/winsup/cygwin/lib/libcmain.c:39: undefi
ned reference to `_WinMain@16'
collect2: ld returned 1 exit status
需要将入口函数:
int main(int argc, char **argv);
换成:
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow);
同时包含windows.h头文件:
#include<windows.h>
这个时候就是个Win32应用程序了。
#include<stdio.h> #include<stdlib.h> #include<windows.h> #include<SDL.h> #include<SDL_audio.h> struct sample { Uint8 *data; Uint32 d_pos; Uint32 d_len; } audio; void sdl_callback(void *unused, Uint8 *stream, int len) { int amount = audio.d_len - audio.d_pos; if (amount > len) { amount = len; } printf("audio: len= %u, pos= %u. audio buffer: @%p, len= %d, amount= %d\n", audio.d_len, audio.d_pos, stream, len, amount); if (amount <= 0) { SDL_PauseAudio(1); return; } SDL_memcpy(stream, audio.data + audio.d_pos, amount); audio.d_pos += amount; } void display_audio_spec(SDL_AudioSpec *audio_spec) { printf("audio: freq...%d\n", audio_spec->freq); printf("audio: format...%d\n", audio_spec->format); printf("audio: channels...%d\n", audio_spec->channels); printf("audio: silence...%d\n", audio_spec->silence); printf("audio: samples...%d\n", audio_spec->samples); printf("audio: padding...%d\n", audio_spec->padding); printf("audio: size...%d\n", audio_spec->size); printf("audio: callback...%p\n", audio_spec->callback); } // mp h:\\sample.wav // mp h:\\yuganqingwuguan-c_a_wmav2.wav // mp h:\\yuganqingwuguan.wav int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char *filename; SDL_AudioSpec audio_spec; display_audio_spec(&audio_spec); filename = "h:\\sample.wav"; // *(argv + 1); "h:\\sample.wav"; if (SDL_LoadWAV(filename, &audio_spec, &audio.data, &audio.d_len) == NULL) { fprintf(stderr, "load wav err: %s\n", SDL_GetError()); return 1; } display_audio_spec(&audio_spec); // audio_spec.silence = 1; // 这个设置没用, 由SDL_OpenAudio()计算设置。 audio_spec.callback = sdl_callback; audio_spec.userdata = NULL; if (SDL_OpenAudio(&audio_spec, NULL) < 0) { fprintf(stderr, "open audio err: %s\n", SDL_GetError()); return -1; } display_audio_spec(&audio_spec); SDL_PauseAudio(0); printf("playing...%s\n", filename); while ((SDL_GetAudioStatus() == SDL_AUDIO_PLAYING)) { SDL_Delay(1000); } printf("played!\n"); SDL_CloseAudio(); SDL_FreeWAV(audio.data); SDL_Quit(); return 0; }
编译
这里一次性完成编译链接。编译的时候注意通过“-I”指定头文件目录,在链接的时候通过“-L”指定要链接的静态库文件目录,以及通过“-l”指定要链接的静态库。
gcc -I D:\sbin\usr\local\sdl\include\SDL2 -L D:\sbin\usr\local\sdl\lib sdl_test_v2.c -o sdl_test_v2 -lSDL2
运行
在运行之前SDL2.dll拷贝到程序目录下:
>cp -rf d:\sbin\usr\local\sdl\bin\SDL2.dll .
mp
SDL2_mixer
#include<SDL_events.h> #include<SDL_mixer.h> int main(int argc, char** argv) { SDL_Event e; int exit = 0; Mix_Music *music; // frequency // // format // // channels // // chunksize // MIX_MAX_VOLUME Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 2048); // 这里chunksize参数指定为2048比较正常 music = Mix_LoadMUS("h:\\yuganqingwuguan.wav"); // h:\\yuganqingwuguan.mp3 // h:\\yuganqingwuguan.wav if (music == NULL) { fprintf(stderr, "load music err: %s\n", SDL_GetError()); return -1; } Mix_PlayMusic(music, 1); while(! exit) { while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { exit = 1; } } } }
相关推荐
3. **07linux-sdl-thread**:多线程编程在现代应用中至关重要,特别是在处理音视频时。这部分会讲解如何在SDL中创建和管理线程,以实现并发任务,比如同时播放音频和渲染视频。 4. **08linux-sdl-playyuv**:YUV是...
在本资源包中,我们主要关注的是C语言与SDL2库结合进行游戏编程的基础知识。SDL2(Simple DirectMedia Layer 2)是一个跨平台的开发库,它为开发者提供了丰富的功能,包括图形渲染、音频处理、事件管理等,是创建2D...
SDL提供了基本的窗口管理、图像渲染、音频播放和键盘/鼠标输入处理等功能,是许多初学者和专业开发者入门游戏编程的首选库。 在"tank-sdl-0.3.0"源代码中,我们可以学习到以下关键点: 1. **游戏循环**:任何游戏...
SDL2(Simple DirectMedia Layer 2)是一个跨平台的开发库,用于处理图形、音频、输入设备等多媒体元素。它在游戏开发领域特别受欢迎,因为它的API简洁高效,并且支持多种操作系统,包括Windows、Linux、Mac OS X...
**标题与描述解析** 标题"SDL2-2.0.2"指的是...熟悉C/C++编程是必要的,因为这是SDL2主要支持的语言。对于Linux运维人员来说,理解如何在服务器上安装、管理和更新SDL2库,以及解决相关的依赖问题,也是重要的技能。
它提供了窗口管理、事件处理、音频输出、图像加载和渲染、以及键盘和鼠标输入等功能。SDL2的一个主要优点是它的跨平台性,可以在Windows、Linux、Mac OS X、Android和iOS等操作系统上运行。 **Android NDK和JNI** ...
SDL2是用C语言编写的,但具有良好的可扩展性,可以通过绑定到其他编程语言,如Python、Java、甚至JavaScript。它的核心功能包括: 1. **图形渲染**:SDL2支持2D渲染,可以创建窗口、绘制图形、线条和文本。它还提供...
- SDL的核心功能包括窗口管理、事件处理、2D渲染、音频播放和键盘/鼠标输入。 ### C++编程语言 - C++是C语言的增强版,增加了面向对象编程特性,同时保留了C语言的效率和灵活性。 - 在imgviewer-sdl项目中,C++用于...
在Linux和Windows操作系统上,SDL 提供了一个统一的编程接口,使得开发者可以在多个平台上轻松移植代码。 标题“linux-winows-跨平台开源图形库 SDL-1.2”明确指出,这个资源是关于 SDL 库的一个特定版本——1.2.13...
总的来说,基于C语言的音频采集和波形显示涉及到音频硬件的交互、信号处理和图形界面编程等多个技术领域。通过学习和实践这样的项目,开发者可以深入了解音频处理的基础知识,并提升其在嵌入式系统或桌面应用中的...
在计算机编程中,Simple DirectMedia Layer(SDL)是一个跨平台的多媒体库,主要用于游戏开发和图形用户界面的创建。它提供了对硬件加速图形、音频、输入设备等的访问,使得开发者可以轻松地编写跨平台的应用程序。...
6. **跨平台兼容性**:商业编程通常需要考虑多平台支持,MyAmp可能使用跨平台的库(如SDL或JUCE)来实现Windows、MacOS、Linux等不同操作系统上的音频播放。 7. **用户界面设计**:音频播放器的用户界面也是关键...
SDL(Simple DirectMedia Layer)是一个开源的C库,它的主要目标是提供一个简单、高效的方式来处理图形、音频和输入设备。它为开发者提供了底层硬件访问的能力,包括显卡、声卡、键盘、鼠标等,同时也支持多线程和...
SDL(Simple DirectMedia Layer)是一个开源的跨平台开发库,主要用于多媒体编程,包括音频处理、图形绘制和输入设备管理等。SDL库是游戏开发、媒体播放器和其他图形应用程序的理想选择,因为它提供了低级别的硬件...
通过Alien-sdl,SBCL能够直接调用SDL的C接口,使得Lisp程序可以直接处理图形、音频和输入事件,极大地扩展了Lisp在游戏开发和多媒体领域的应用范围。 Alien-sdl的核心是对外部函数的绑定。在Lisp中,"alien"一词...
2. **Linux环境下的图形编程**:在Linux系统中,开发者通常需要直接操作X Window System或Wayland等窗口系统来实现图形界面,而SDL库则抽象了这些复杂的接口,提供了一套统一的编程模型。 3. **SDL2.0.3版本特点**...
2. **SDL2库**:SDL2是一个开源的跨平台库,允许开发者在多种操作系统上创建高性能的图形应用程序,包括Windows、Linux、Mac OS X和Android等。它提供了图形渲染、音频处理、键盘和鼠标输入等功能。 3. **C++编程**...
- SDL音频模块:音乐播放器的核心是SDL的音频处理功能,它允许程序加载、解码和播放各种音频格式,如MP3、WAV等。 - SDL事件系统:用于捕获用户交互,如键盘、鼠标点击,支持播放、暂停、上一首、下一首等操作。 ...
在Linux环境下,使用FFmpeg和SDL(Simple DirectMedia Layer)框架...这个过程中涉及的知识点包括音视频编码解码原理、多媒体文件格式、流处理技术、图形用户界面编程等,是深入理解多媒体处理和Linux开发的重要实践。
- **输入**:处理键盘、鼠标、游戏手柄等输入设备的事件。 - **文件I/O**:读写文件,支持各种数据格式。 - **网络**:提供基本的网络功能,如TCP/IP通信。 - **多线程**:支持并发编程,优化多核处理器的性能。...