summaryrefslogtreecommitdiff
path: root/uisimulator/sdl/sound.c
diff options
context:
space:
mode:
Diffstat (limited to 'uisimulator/sdl/sound.c')
-rw-r--r--uisimulator/sdl/sound.c426
1 files changed, 0 insertions, 426 deletions
diff --git a/uisimulator/sdl/sound.c b/uisimulator/sdl/sound.c
deleted file mode 100644
index 0f8d5d4934..0000000000
--- a/uisimulator/sdl/sound.c
+++ /dev/null
@@ -1,426 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Nick Lanham
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "autoconf.h"
23
24#include <stdlib.h>
25#include <stdbool.h>
26#include <memory.h>
27#include "kernel.h"
28#include "sound.h"
29#include "audiohw.h"
30
31#include "pcm.h"
32#include "pcm_sampr.h"
33#include "SDL.h"
34
35/*#define LOGF_ENABLE*/
36#include "logf.h"
37
38static int sim_volume = 0;
39
40#if CONFIG_CODEC == SWCODEC
41static int cvt_status = -1;
42
43static Uint8* pcm_data;
44static size_t pcm_data_size;
45static size_t pcm_sample_bytes;
46static size_t pcm_channel_bytes;
47
48static struct pcm_udata
49{
50 Uint8 *stream;
51 Uint32 num_in;
52 Uint32 num_out;
53 FILE *debug;
54} udata;
55
56static SDL_AudioSpec obtained;
57static SDL_AudioCVT cvt;
58
59extern bool debug_audio;
60
61#ifndef MIN
62#define MIN(a, b) (((a) < (b)) ? (a) : (b))
63#endif
64
65void pcm_play_lock(void)
66{
67 SDL_LockAudio();
68}
69
70void pcm_play_unlock(void)
71{
72 SDL_UnlockAudio();
73}
74
75static void pcm_dma_apply_settings_nolock(void)
76{
77 cvt_status = SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, 2, pcm_sampr,
78 obtained.format, obtained.channels, obtained.freq);
79
80 if (cvt_status < 0) {
81 cvt.len_ratio = (double)obtained.freq / (double)pcm_sampr;
82 }
83}
84
85void pcm_dma_apply_settings(void)
86{
87 pcm_play_lock();
88 pcm_dma_apply_settings_nolock();
89 pcm_play_unlock();
90}
91
92void pcm_play_dma_start(const void *addr, size_t size)
93{
94 pcm_dma_apply_settings_nolock();
95
96 pcm_data = (Uint8 *) addr;
97 pcm_data_size = size;
98
99 SDL_PauseAudio(0);
100}
101
102void pcm_play_dma_stop(void)
103{
104 SDL_PauseAudio(1);
105 if (udata.debug != NULL) {
106 fclose(udata.debug);
107 udata.debug = NULL;
108 DEBUGF("Audio debug file closed\n");
109 }
110}
111
112void pcm_play_dma_pause(bool pause)
113{
114 if (pause)
115 SDL_PauseAudio(1);
116 else
117 SDL_PauseAudio(0);
118}
119
120size_t pcm_get_bytes_waiting(void)
121{
122 return pcm_data_size;
123}
124
125extern int sim_volume; /* in firmware/sound.c */
126static void write_to_soundcard(struct pcm_udata *udata) {
127 if (debug_audio && (udata->debug == NULL)) {
128 udata->debug = fopen("audiodebug.raw", "ab");
129 DEBUGF("Audio debug file open\n");
130 }
131
132 if (cvt.needed) {
133 Uint32 rd = udata->num_in;
134 Uint32 wr = (double)rd * cvt.len_ratio;
135
136 if (wr > udata->num_out) {
137 wr = udata->num_out;
138 rd = (double)wr / cvt.len_ratio;
139
140 if (rd > udata->num_in)
141 {
142 rd = udata->num_in;
143 wr = (double)rd * cvt.len_ratio;
144 }
145 }
146
147 if (wr == 0 || rd == 0)
148 {
149 udata->num_out = udata->num_in = 0;
150 return;
151 }
152
153 if (cvt_status > 0) {
154 cvt.len = rd * pcm_sample_bytes;
155 cvt.buf = (Uint8 *) malloc(cvt.len * cvt.len_mult);
156
157 memcpy(cvt.buf, pcm_data, cvt.len);
158
159 SDL_ConvertAudio(&cvt);
160 SDL_MixAudio(udata->stream, cvt.buf, cvt.len_cvt, sim_volume);
161
162 udata->num_in = cvt.len / pcm_sample_bytes;
163 udata->num_out = cvt.len_cvt / pcm_sample_bytes;
164
165 if (udata->debug != NULL) {
166 fwrite(cvt.buf, sizeof(Uint8), cvt.len_cvt, udata->debug);
167 }
168
169 free(cvt.buf);
170 }
171 else {
172 /* Convert is bad, so do silence */
173 Uint32 num = wr*obtained.channels;
174 udata->num_in = rd;
175 udata->num_out = wr;
176
177 switch (pcm_channel_bytes)
178 {
179 case 1:
180 {
181 Uint8 *stream = udata->stream;
182 while (num-- > 0)
183 *stream++ = obtained.silence;
184 break;
185 }
186 case 2:
187 {
188 Uint16 *stream = (Uint16 *)udata->stream;
189 while (num-- > 0)
190 *stream++ = obtained.silence;
191 break;
192 }
193 }
194
195 if (udata->debug != NULL) {
196 fwrite(udata->stream, sizeof(Uint8), wr, udata->debug);
197 }
198 }
199 } else {
200 udata->num_in = udata->num_out = MIN(udata->num_in, udata->num_out);
201 SDL_MixAudio(udata->stream, pcm_data,
202 udata->num_out * pcm_sample_bytes, sim_volume);
203
204 if (udata->debug != NULL) {
205 fwrite(pcm_data, sizeof(Uint8), udata->num_out * pcm_sample_bytes,
206 udata->debug);
207 }
208 }
209}
210
211static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
212{
213 logf("sdl_audio_callback: len %d, pcm %d\n", len, pcm_data_size);
214 udata->stream = stream;
215
216 /* Write what we have in the PCM buffer */
217 if (pcm_data_size > 0)
218 goto start;
219
220 /* Audio card wants more? Get some more then. */
221 while (len > 0) {
222 if ((ssize_t)pcm_data_size <= 0) {
223 pcm_data_size = 0;
224 if (pcm_callback_for_more)
225 pcm_callback_for_more(&pcm_data, &pcm_data_size);
226 }
227
228 if (pcm_data_size > 0) {
229 start:
230 udata->num_in = pcm_data_size / pcm_sample_bytes;
231 udata->num_out = len / pcm_sample_bytes;
232
233 write_to_soundcard(udata);
234
235 udata->num_in *= pcm_sample_bytes;
236 udata->num_out *= pcm_sample_bytes;
237
238 pcm_data += udata->num_in;
239 pcm_data_size -= udata->num_in;
240 udata->stream += udata->num_out;
241 len -= udata->num_out;
242 } else {
243 DEBUGF("sdl_audio_callback: No Data.\n");
244 pcm_play_dma_stop();
245 pcm_play_dma_stopped_callback();
246 break;
247 }
248 }
249}
250
251const void * pcm_play_dma_get_peak_buffer(int *count)
252{
253 uintptr_t addr = (uintptr_t)pcm_data;
254 *count = pcm_data_size / 4;
255 return (void *)((addr + 2) & ~3);
256}
257
258#ifdef HAVE_RECORDING
259void pcm_rec_lock(void)
260{
261}
262
263void pcm_rec_unlock(void)
264{
265}
266
267void pcm_rec_dma_init(void)
268{
269}
270
271void pcm_rec_dma_close(void)
272{
273}
274
275void pcm_rec_dma_start(void *start, size_t size)
276{
277 (void)start;
278 (void)size;
279}
280
281void pcm_rec_dma_stop(void)
282{
283}
284
285void pcm_rec_dma_record_more(void *start, size_t size)
286{
287 (void)start;
288 (void)size;
289}
290
291unsigned long pcm_rec_status(void)
292{
293 return 0;
294}
295
296const void * pcm_rec_dma_get_peak_buffer(void)
297{
298 return NULL;
299}
300
301#endif /* HAVE_RECORDING */
302
303void pcm_play_dma_init(void)
304{
305 SDL_AudioSpec wanted_spec;
306 udata.debug = NULL;
307
308 if (debug_audio) {
309 udata.debug = fopen("audiodebug.raw", "wb");
310 DEBUGF("Audio debug file open\n");
311 }
312
313 /* Set 16-bit stereo audio at 44Khz */
314 wanted_spec.freq = 44100;
315 wanted_spec.format = AUDIO_S16SYS;
316 wanted_spec.channels = 2;
317 wanted_spec.samples = 2048;
318 wanted_spec.callback =
319 (void (SDLCALL *)(void *userdata,
320 Uint8 *stream, int len))sdl_audio_callback;
321 wanted_spec.userdata = &udata;
322
323 /* Open the audio device and start playing sound! */
324 if(SDL_OpenAudio(&wanted_spec, &obtained) < 0) {
325 fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
326 return;
327 }
328
329 switch (obtained.format)
330 {
331 case AUDIO_U8:
332 case AUDIO_S8:
333 pcm_channel_bytes = 1;
334 break;
335 case AUDIO_U16LSB:
336 case AUDIO_S16LSB:
337 case AUDIO_U16MSB:
338 case AUDIO_S16MSB:
339 pcm_channel_bytes = 2;
340 break;
341 default:
342 fprintf(stderr, "Unknown sample format obtained: %u\n",
343 (unsigned)obtained.format);
344 return;
345 }
346
347 pcm_sample_bytes = obtained.channels * pcm_channel_bytes;
348
349 pcm_dma_apply_settings_nolock();
350}
351
352void pcm_postinit(void)
353{
354}
355
356#endif /* CONFIG_CODEC == SWCODEC */
357
358/**
359 * Audio Hardware api. Make them do nothing as we cannot properly simulate with
360 * SDL. if we used DSP we would run code that doesn't actually run on the target
361 **/
362void audiohw_set_volume(int volume)
363{
364 sim_volume = SDL_MIX_MAXVOLUME * ((volume - VOLUME_MIN) / 10) / (VOLUME_RANGE / 10);
365}
366#if defined(AUDIOHW_HAVE_PRESCALER)
367void audiohw_set_prescaler(int value) { (void)value; }
368#endif
369#if defined(AUDIOHW_HAVE_BALANCE)
370void audiohw_set_balance(int value) { (void)value; }
371#endif
372#if defined(AUDIOHW_HAVE_BASS)
373void audiohw_set_bass(int value) { (void)value; }
374#endif
375#if defined(AUDIOHW_HAVE_TREBLE)
376void audiohw_set_treble(int value) { (void)value; }
377#endif
378#if CONFIG_CODEC != SWCODEC
379void audiohw_set_channel(int value) { (void)value; }
380void audiohw_set_stereo_width(int value){ (void)value; }
381#endif
382#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
383void audiohw_set_bass_cutoff(int value) { (void)value; }
384#endif
385#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
386void audiohw_set_treble_cutoff(int value){ (void)value; }
387#endif
388/* EQ-based tone controls */
389#if defined(AUDIOHW_HAVE_EQ)
390void audiohw_set_eq_band_gain(unsigned int band, int value)
391 { (void)band; (void)value; }
392#endif
393#if defined(AUDIOHW_HAVE_EQ_FREQUENCY)
394void audiohw_set_eq_band_frequency(unsigned int band, int value)
395 { (void)band; (void)value; }
396#endif
397#if defined(AUDIOHW_HAVE_EQ_WIDTH)
398void audiohw_set_eq_band_width(unsigned int band, int value)
399 { (void)band; (void)value; }
400#endif
401#if defined(AUDIOHW_HAVE_DEPTH_3D)
402void audiohw_set_depth_3d(int value)
403 { (void)value; }
404#endif
405#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
406int mas_codec_readreg(int reg)
407{
408 (void)reg;
409 return 0;
410}
411
412int mas_codec_writereg(int reg, unsigned int val)
413{
414 (void)reg;
415 (void)val;
416 return 0;
417}
418int mas_writemem(int bank, int addr, const unsigned long* src, int len)
419{
420 (void)bank;
421 (void)addr;
422 (void)src;
423 (void)len;
424 return 0;
425}
426#endif