summaryrefslogtreecommitdiffstats
path: root/uisimulator/sdl
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-10-06 22:27:27 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-10-06 22:27:27 +0000
commit6077e5b7c85c0d6f5963e4aadb215faf2c4d10d2 (patch)
treea6bc91ee4168e83617e942eeaea46e5523e82420 /uisimulator/sdl
parentf6de0d4083a4fcb6da57f271e1f8ccaf715e571d (diff)
downloadrockbox-6077e5b7c85c0d6f5963e4aadb215faf2c4d10d2.tar.gz
rockbox-6077e5b7c85c0d6f5963e4aadb215faf2c4d10d2.zip
Unify PCM interface just above the hardware driver level for all targets including the sims. Perform lockout of audio callback when changing states. Weird new playback or recording trouble? Check before and after this revision first though things seem quite sound.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15006 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'uisimulator/sdl')
-rw-r--r--uisimulator/sdl/sound.c250
1 files changed, 53 insertions, 197 deletions
diff --git a/uisimulator/sdl/sound.c b/uisimulator/sdl/sound.c
index 6016676f70..3636939f06 100644
--- a/uisimulator/sdl/sound.c
+++ b/uisimulator/sdl/sound.c
@@ -26,20 +26,12 @@
#include "kernel.h"
#include "sound.h"
-#ifdef HAVE_RECORDING
-#ifndef REC_SAMPR_CAPS
-#define REC_SAMPR_CAPS SAMPR_CAP_44
-#endif
-#endif
-
+#include "pcm.h"
#include "pcm_sampr.h"
#include "SDL.h"
-static bool pcm_playing;
-static bool pcm_paused;
static int cvt_status = -1;
static unsigned long pcm_frequency = SAMPR_44;
-static unsigned long pcm_curr_frequency = SAMPR_44;
static Uint8* pcm_data;
static size_t pcm_data_size;
@@ -63,66 +55,56 @@ extern bool debug_audio;
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
+void pcm_play_lock(void)
+{
+ SDL_LockAudio();
+}
+
+void pcm_play_unlock(void)
+{
+ SDL_UnlockAudio();
+}
+
static void pcm_apply_settings_nolock(void)
{
cvt_status = SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, 2, pcm_frequency,
obtained.format, obtained.channels, obtained.freq);
- pcm_curr_frequency = pcm_frequency;
+ pcm_curr_sampr = pcm_frequency;
if (cvt_status < 0) {
- cvt.len_ratio = (double)obtained.freq / (double)pcm_curr_frequency;
+ cvt.len_ratio = (double)obtained.freq / (double)pcm_curr_sampr;
}
}
void pcm_apply_settings(void)
{
- SDL_LockAudio();
+ pcm_play_lock();
pcm_apply_settings_nolock();
- SDL_UnlockAudio();
+ pcm_play_unlock();
}
-static void sdl_dma_start_nolock(const void *addr, size_t size)
+void pcm_play_dma_start(const void *addr, size_t size)
{
- pcm_playing = false;
-
pcm_apply_settings_nolock();
pcm_data = (Uint8 *) addr;
pcm_data_size = size;
- pcm_playing = true;
-
SDL_PauseAudio(0);
}
-static void sdl_dma_stop_nolock(void)
+void pcm_play_dma_stop(void)
{
- pcm_playing = false;
-
SDL_PauseAudio(1);
-
- pcm_paused = false;
}
-static void (*callback_for_more)(unsigned char**, size_t*) = NULL;
-void pcm_play_data(void (*get_more)(unsigned char** start, size_t* size),
- unsigned char* start, size_t size)
+void pcm_play_dma_pause(bool pause)
{
- SDL_LockAudio();
-
- callback_for_more = get_more;
-
- if (!(start && size)) {
- if (get_more)
- get_more(&start, &size);
- }
-
- if (start && size) {
- sdl_dma_start_nolock(start, size);
- }
-
- SDL_UnlockAudio();
+ if (pause)
+ SDL_PauseAudio(1);
+ else
+ SDL_PauseAudio(0);
}
size_t pcm_get_bytes_waiting(void)
@@ -130,74 +112,6 @@ size_t pcm_get_bytes_waiting(void)
return pcm_data_size;
}
-void pcm_mute(bool mute)
-{
- (void) mute;
-}
-
-void pcm_play_stop(void)
-{
- SDL_LockAudio();
- if (pcm_playing) {
- sdl_dma_stop_nolock();
- }
- SDL_UnlockAudio();
-}
-
-void pcm_play_pause(bool play)
-{
- size_t next_size;
- Uint8 *next_start;
-
- SDL_LockAudio();
-
- if (!pcm_playing) {
- SDL_UnlockAudio();
- return;
- }
-
- if(pcm_paused && play) {
- if (pcm_get_bytes_waiting()) {
- printf("unpause\n");
- pcm_apply_settings_nolock();
- SDL_PauseAudio(0);
- } else {
- printf("unpause, no data waiting\n");
-
- void (*get_more)(unsigned char**, size_t*) = callback_for_more;
-
- if (get_more) {
- get_more(&next_start, &next_size);
- }
-
- if (next_start && next_size) {
- sdl_dma_start_nolock(next_start, next_size);
- } else {
- sdl_dma_stop_nolock();
- printf("unpause attempted, no data\n");
- }
- }
- } else if(!pcm_paused && !play) {
- printf("pause\n");
-
- SDL_PauseAudio(1);
- }
-
- pcm_paused = !play;
-
- SDL_UnlockAudio();
-}
-
-bool pcm_is_paused(void)
-{
- return pcm_paused;
-}
-
-bool pcm_is_playing(void)
-{
- return pcm_playing;
-}
-
void pcm_set_frequency(unsigned int frequency)
{
switch (frequency)
@@ -222,70 +136,6 @@ void pcm_set_frequency(unsigned int frequency)
pcm_frequency = frequency;
}
-/*
- * This function goes directly into the DMA buffer to calculate the left and
- * right peak values. To avoid missing peaks it tries to look forward two full
- * peek periods (2/HZ sec, 100% overlap), although it's always possible that
- * the entire period will not be visible. To reduce CPU load it only looks at
- * every third sample, and this can be reduced even further if needed (even
- * every tenth sample would still be pretty accurate).
- */
-
-#define PEAK_SAMPLES (44100*2/HZ) /* 44100 samples * 2 / 100 Hz tick */
-#define PEAK_STRIDE 3 /* every 3rd sample is plenty... */
-
-void pcm_calculate_peaks(int *left, int *right)
-{
- long samples = (long) pcm_data_size / 4;
- short *addr = (short *) pcm_data;
-
- if (samples > PEAK_SAMPLES)
- samples = PEAK_SAMPLES;
-
- samples /= PEAK_STRIDE;
-
- if (left && right) {
- int left_peak = 0, right_peak = 0, value;
-
- while (samples--) {
- if ((value = addr [0]) > left_peak)
- left_peak = value;
- else if (-value > left_peak)
- left_peak = -value;
-
- if ((value = addr [PEAK_STRIDE | 1]) > right_peak)
- right_peak = value;
- else if (-value > right_peak)
- right_peak = -value;
-
- addr += PEAK_STRIDE * 2;
- }
-
- *left = left_peak;
- *right = right_peak;
- }
- else if (left || right) {
- int peak_value = 0, value;
-
- if (right)
- addr += (PEAK_STRIDE | 1);
-
- while (samples--) {
- if ((value = addr [0]) > peak_value)
- peak_value = value;
- else if (-value > peak_value)
- peak_value = -value;
-
- addr += PEAK_STRIDE * 2;
- }
-
- if (left)
- *left = peak_value;
- else
- *right = peak_value;
- }
-}
-
extern int sim_volume; /* in firmware/sound.c */
void write_to_soundcard(struct pcm_udata *udata) {
if (cvt.needed) {
@@ -380,8 +230,8 @@ void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
if ((ssize_t)pcm_data_size <= 0) {
pcm_data_size = 0;
- if (callback_for_more)
- callback_for_more(&pcm_data, &pcm_data_size);
+ if (pcm_callback_for_more)
+ pcm_callback_for_more(&pcm_data, &pcm_data_size);
}
if (pcm_data_size > 0) {
@@ -400,30 +250,42 @@ void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
len -= udata->num_out;
} else {
DEBUGF("sdl_audio_callback: No Data.\n");
- sdl_dma_stop_nolock();
+ pcm_play_dma_stop();
+ pcm_play_dma_stopped_callback();
break;
}
}
}
+const void * pcm_play_dma_get_peak_buffer(int *count)
+{
+ uintptr_t addr = (uintptr_t)pcm_data;
+ *count = pcm_data_size / 4;
+ return (void *)((addr + 2) & ~3);
+}
+
#ifdef HAVE_RECORDING
-void pcm_init_recording(void)
+void pcm_rec_lock(void)
{
}
-void pcm_close_recording(void)
+void pcm_rec_unlock(void)
{
}
-void pcm_record_data(void (*more_ready)(void* start, size_t size),
- void *start, size_t size)
+void pcm_rec_dma_init(void)
+{
+}
+
+void pcm_rec_dma_close(void)
{
- (void)more_ready;
- (void)start;
- (void)size;
}
-void pcm_stop_recording(void)
+void pcm_rec_dma_start(void *start, size_t size)
+{
+}
+
+void pcm_rec_dma_stop(void)
{
}
@@ -433,22 +295,20 @@ void pcm_record_more(void *start, size_t size)
(void)size;
}
-void pcm_calculate_rec_peaks(int *left, int *right)
+unsigned long pcm_rec_status(void)
{
- if (left)
- *left = 0;
- if (right)
- *right = 0;
+ return 0;
}
-unsigned long pcm_rec_status(void)
+const void * pcm_rec_dma_get_peak_buffer(int *count)
{
- return 0;
+ *count = 0;
+ return NULL;
}
#endif /* HAVE_RECORDING */
-int pcm_init(void)
+void pcm_play_dma_init(void)
{
SDL_AudioSpec wanted_spec;
udata.debug = NULL;
@@ -470,7 +330,7 @@ int pcm_init(void)
/* Open the audio device and start playing sound! */
if(SDL_OpenAudio(&wanted_spec, &obtained) < 0) {
fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
- return -1;
+ return;
}
switch (obtained.format)
@@ -488,16 +348,12 @@ int pcm_init(void)
default:
fprintf(stderr, "Unknown sample format obtained: %u\n",
(unsigned)obtained.format);
- return -1;
+ return;
}
pcm_sample_bytes = obtained.channels * pcm_channel_bytes;
pcm_apply_settings_nolock();
-
- sdl_dma_stop_nolock();
-
- return 0;
}
void pcm_postinit(void)