summaryrefslogtreecommitdiff
path: root/uisimulator/sdl/sound.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-05-15 21:02:47 +0000
committerThomas Martitz <kugel@rockbox.org>2010-05-15 21:02:47 +0000
commit3d0cee8abbaf764958743e8a7851eee94e60a913 (patch)
treea96b1ec825003a71643a7da4707c300f64824f82 /uisimulator/sdl/sound.c
parentdcf442e61f21fb2aef5ce7de0547f733557b156e (diff)
downloadrockbox-3d0cee8abbaf764958743e8a7851eee94e60a913.tar.gz
rockbox-3d0cee8abbaf764958743e8a7851eee94e60a913.zip
- Move uisimulator/sdl/*.[ch] into the target tree, under firmware/target/hosted/sdl, uisdl.c is split up across button-sdl.c and system-sdl.c.
- Refactor the program startup. main() is now in main.c like on target, and the implicit application thread will now act as our main thread (previously a separate one was created for this in thread initialization). This is part of Rockbox as an application and is the first step to make an application port from the uisimulator. In a further step the sim bits from the sdl build will be separated out. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26065 a1c6a512-1295-4272-9138-f99709370657
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