-
Notifications
You must be signed in to change notification settings - Fork 13
/
sdl_snd.c
127 lines (108 loc) · 3.08 KB
/
sdl_snd.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include "def.h"
#include "device.h"
#include "hardware.h"
#include "digger_math.h"
#include "digger_log.h"
#include "newsnd.h"
#include "sdl_snd.h"
static void fill_audio(void *udata, uint8_t *stream, int len);
bool wave_device_available = false;
bool initsounddevice(void)
{
return(true);
}
struct sudata {
SDL_AudioSpec obtained;
SDL_AudioDeviceID dev;
int16_t *buf;
unsigned int bsize;
struct bqd_filter *lp_fltr;
struct bqd_filter *hp_fltr;
};
static struct sudata *sud;
bool setsounddevice(uint16_t samprate, uint16_t bufsize)
{
SDL_AudioSpec wanted;
bool result = false;
assert(sud == NULL);
sud = (struct sudata*)malloc(sizeof(*sud));
if (sud == NULL) {
fprintf(digger_log, "setsounddevice: malloc(3) failed\n");
return (false);
}
memset(sud, '\0', sizeof(*sud));
SDL_zero(wanted);
SDL_zero(sud->obtained);
wanted.freq = samprate;
wanted.samples = bufsize;
wanted.channels = 1;
wanted.format = AUDIO_S16;
wanted.userdata = sud;
wanted.callback = fill_audio;
if ((SDL_Init(SDL_INIT_AUDIO)) >= 0) {
sud->dev = SDL_OpenAudioDevice(NULL, 0, &wanted, &sud->obtained, 0);
if (sud->dev > 0)
result = true;
}
if (result == false) {
fprintf(digger_log, "Couldn't open audio: %s\n", SDL_GetError());
free(sud);
return (false);
}
#if defined(DIGGER_DEBUG)
fprintf(digger_log, "setsounddevice: wanted.samples=%d obtained.samples=%d\n",
wanted.samples, sud->obtained.samples);
#endif
sud->bsize = sud->obtained.size;
sud->buf = (int16_t*)malloc(sud->bsize);
if (sud->buf == NULL) {
fprintf(digger_log, "setsounddevice: malloc(3) failed\n");
SDL_CloseAudio();
free(sud);
return (false);
}
sud->lp_fltr = bqd_lp_init(sud->obtained.freq, 4000);
sud->hp_fltr = bqd_hp_init(sud->obtained.freq, 1000);
SDL_PauseAudioDevice(sud->dev, 0);
return(result);
}
static void fill_audio(void *udata, uint8_t *stream, int len)
{
int i;
struct sudata *sud;
#if !defined(NO_SND_FILTER)
double sample;
#endif
if (!wave_device_available)
wave_device_available = true;
sud = (struct sudata *)udata;
SDL_memset(stream, sud->obtained.silence, len);
if (len > sud->bsize) {
fprintf(digger_log, "fill_audio: OUCH, len > bsize!\n");
len = sud->bsize;
}
for (i = 0; i < len / sizeof(int16_t); i++) {
#if !defined(NO_SND_FILTER)
sample = getsample();
sample = bqd_apply(sud->hp_fltr, (sample - 127.0) * 128.0);
sud->buf[i] = round(bqd_apply(sud->lp_fltr, sample));
#else
sud->buf[i] = getsample();
#endif
}
SDL_MixAudioFormat(stream, (uint8_t *)sud->buf, sud->obtained.format, len,
SDL_MIX_MAXVOLUME);
}
static bool wave_device_paused = false;
void pausesounddevice(bool p)
{
if (wave_device_paused == p)
return;
SDL_PauseAudioDevice(sud->dev, p ? 1 : 0);
wave_device_paused = p;
}