|
发表于 2004-7-22 10:18:22
|
显示全部楼层
SDL库提供了声音的支持,而且不会和其他的声音冲突
我做一个游戏写的一个声音处理部分可以供你参考
sound.h
#ifndef TANK_SOUND_H
#define TANK_SOUND_H
#include <SDL/SDL.h>
#define SND_FAILED 1
#define SND_OK 0
#define SND_NORMAL 0
#define SND_LOOP 1
//#define SND_MAX_TRACK 1;
typedef struct sound_s{
Uint8 *samples;
Uint32 length;
}sound_t, *sound_p;
typedef struct playing_s {
int active;
sound_p sound;
Uint32 position;
int loop; /* 0 play once, 1 play repeatly */
} playing_t, *playing_p;
SDL_AudioSpec AudioSpec,AudioObtained;
int initSound();
int LoadAndConvertSound(char *filename, SDL_AudioSpec *spec, sound_p sound);
int PlaySound(sound_p sound, int loop); // 0 play once, 1 play repeatly
void ClearPlayingSounds(void);
#endif
以下是实现文件
sound.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "sound.h"
#define MAX_PLAYING_SOUNDS 10
playing_t playing[MAX_PLAYING_SOUNDS];
#define VOLUME_PER_SOUND SDL_MIX_MAXVOLUME / 2
/* initializing sound system */
void AudioCallback(void *user_data, Uint8 *audio, int length)
{
int i;
memset(audio,0,length);
for(i=0;i<MAX_PLAYING_SOUNDS;i++){
if(playing.active){
Uint8 *sound_buf;
Uint32 sound_len;
sound_buf=playing.sound->samples;
sound_buf+=playing.position;
if((playing.position+length)>
playing.sound->length){
sound_len = playing.sound->length -
playing.position;
}else{
sound_len=length;
}
SDL_MixAudio(audio, sound_buf, sound_len,
VOLUME_PER_SOUND);
playing.position += length;
if(playing.position >= playing.sound->length){
if(playing.loop == SND_LOOP) playing.position = 0;
else
playing.active=0;
}
}
}
}
int initSound()
{
AudioSpec.freq = 44100;
AudioSpec.format = AUDIO_S16;
AudioSpec.samples = 4096;
AudioSpec.channels =2;
AudioSpec.callback = AudioCallback;
AudioSpec.userdata = NULL;
atexit(SDL_CloseAudio);
if(SDL_OpenAudio(&AudioSpec, &AudioObtained)<0){
printf("Unable to open audio device: %s\n", SDL_GetError());
return SND_FAILED;
}
ClearPlayingSounds();
SDL_PauseAudio(0);
return SND_OK;
}
int LoadAndConvertSound(char *filename, SDL_AudioSpec *spec,
sound_p sound)
{
SDL_AudioCVT cvt;
SDL_AudioSpec loaded;
Uint8 *new_buf;
if(SDL_LoadWAV(filename,
&loaded, &sound->samples,
&sound->length)==NULL){
printf("Unable to load sound: %s\n", SDL_GetError());
return SND_FAILED;
}
if(SDL_BuildAudioCVT(&cvt, loaded.format,
loaded.channels, loaded.freq,
spec->format,spec->channels,
spec->freq)<0){
printf("Unable to convert sound: %s\n",SDL_GetError());
return SND_FAILED;
}
cvt.len=sound->length;
new_buf=(Uint8 *) malloc(cvt.len*cvt.len_mult);
if(new_buf==NULL){
printf("Memory allocation failed.\n");
SDL_FreeWAV(sound->samples);
return SND_FAILED;
}
memcpy(new_buf, sound->samples, sound->length);
cvt.buf=new_buf;
if(SDL_ConvertAudio(&cvt)<0){
printf("Audio conversion error: %s\n",SDL_GetError());
free(new_buf);
SDL_FreeWAV(sound->samples);
return SND_FAILED;
}
SDL_FreeWAV(sound->samples);
sound->samples = new_buf;
sound->length =sound->length*cvt.len_mult;
printf("'%s' was loaded and converted successfully.\n", filename);
return SND_OK;
}
void ClearPlayingSounds(void)
{
int i;
for(i=0; i<MAX_PLAYING_SOUNDS; i++){
playing.active =0;
}
}
int PlaySound(sound_p sound, int loop) // 0 play once, 1 play repeatly
{
int i;
for(i=0;i<MAX_PLAYING_SOUNDS; i++){
if(playing.active == 0)
break;
}
if(i==MAX_PLAYING_SOUNDS)
return SND_FAILED;
SDL_LockAudio();
if(loop) playing.loop=SND_LOOP;
else
playing.loop=SND_NORMAL;
playing.active = 1;
playing.sound = sound;
playing.position =0;
SDL_UnlockAudio();
return SND_OK;
}
目前只能放wav文件,这么用
test.c
#include <SDL/SDL.h>
#include "sound.h"
int main()
{
sound_t s_background;
if(SDL_Init(SDL_INIT_AUDIO)!=0) {
printf("无法初始化 SDL: %s\n", SDL_GetError());
return 1;
}
atexit(SDL_Quit);
initSound();
if(LoadAndConvertSound("background.wav",&AudioObtained,
&s_background)!=0){
printf("Unable to load sound.\n");
return 1;
}
PlaySound(&s_background,SND_LOOP); // 循环放
SDL_Delay(30000); // 延时30秒,以便你能听到声音
SDL_PauseAudio(1); // 暂停声音播放
SDL_LockAudio(); // 暂停向声卡写数据
free(s_background.samples); // 释放声音文件
SDL_UnlockAudio(); // 解除锁
} |
|