-
Notifications
You must be signed in to change notification settings - Fork 11
/
sound.c
107 lines (89 loc) · 2.65 KB
/
sound.c
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
100
101
102
103
104
105
106
107
#include <string.h>
#include <SDL.h>
typedef struct snd {
int playing;
int current_sample;
int current_position;
} SoundControl;
#define MAXSAMPLES 10
int sound_bell;
int sound_initok = 0;
SDL_AudioSpec sound_audiospec;
int sound_numsamples;
int sound_length[MAXSAMPLES];
Uint8 *sound_buffer[MAXSAMPLES];
SoundControl sound_control;
void fillbuffer(void *userdata, Uint8 *stream, int len) {
if (len) {
if (sound_control.playing) {
if (sound_control.current_position + len >= sound_length[sound_control.current_sample]) {
memcpy(stream, sound_buffer[sound_control.current_sample] + sound_control.current_position,
sound_length[sound_control.current_sample] - sound_control.current_position);
memset(stream + sound_length[sound_control.current_sample] - sound_control.current_position,
sound_audiospec.silence,
len - (sound_length[sound_control.current_sample] - sound_control.current_position));
sound_control.playing = 0;
} else {
memcpy(stream, sound_buffer[sound_control.current_sample] + sound_control.current_position, len);
sound_control.current_position += len;
}
} else {
memset(stream, sound_audiospec.silence, len);
}
}
}
int sound_init(void) {
sound_initok = 0;
sound_numsamples = 0;
memset(sound_buffer, 0, sizeof(sound_buffer));
sound_control.playing = SDL_FALSE;
if (SDL_InitSubSystem(SDL_INIT_AUDIO)) {
printf("Audio init failed: %s\n", SDL_GetError());
return(1);
}
sound_audiospec.freq = 22050;
sound_audiospec.format = AUDIO_S16;
sound_audiospec.channels = 1;
sound_audiospec.samples = 1024;
sound_audiospec.callback = fillbuffer;
sound_audiospec.userdata = NULL;
if (SDL_OpenAudio(&sound_audiospec, NULL) < 0) {
printf("Audio init failed: %s\n", SDL_GetError());
return(1);
}
SDL_PauseAudio(0);
sound_initok = 1;
return(0);
}
signed int sound_load_sample(char *filename) {
int sample;
if (sound_initok) {
if (sound_numsamples >= MAXSAMPLES) {
return(-1);
}
for (sample = 0; sound_buffer[sample]; ++sample);
if (SDL_LoadWAV(filename, &sound_audiospec, &sound_buffer[sample], &sound_length[sample]) == NULL) {
return(-1);
}
return(sample);
} else {
return(0);
}
}
void sound_free_sample(int sample) {
if (sound_buffer[sample]) {
SDL_FreeWAV(sound_buffer[sample]);
sound_buffer[sample] = 0;
}
}
void sound_play_sample(int sample) {
if (sound_initok) {
if (sound_buffer[sample] && !sound_control.playing) {
SDL_LockAudio();
sound_control.current_sample = sample;
sound_control.current_position = 0;
sound_control.playing = SDL_TRUE;
SDL_UnlockAudio();
}
}
}