From a2b6703a369f6cdbfec1f150c408dadc877631fb Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Wed, 29 Jun 2011 06:37:04 +0000 Subject: Commit FS#12150 - Fully-functional audio mixer - and finally whip old limitations about playback of voice and other sounds when paused. Channels are independent in state and amplitude. Fade on stop/pause is handled by the channel's volume control rather than global volume which means it now works from anywhere. Opens up the possibility of plugin sounds during music playback by merely adding an additional channel enum. If any PCM drivers were not properly modified, see one of the last comments in the task for a description of the simple change that is expected. Some params are tunable in firmware/export/pcm-mixer.h as well. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30097 a1c6a512-1295-4272-9138-f99709370657 --- firmware/export/pcm_mixer.h | 102 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 firmware/export/pcm_mixer.h (limited to 'firmware/export/pcm_mixer.h') diff --git a/firmware/export/pcm_mixer.h b/firmware/export/pcm_mixer.h new file mode 100644 index 0000000000..3b420e1320 --- /dev/null +++ b/firmware/export/pcm_mixer.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 by Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef PCM_MIXER_H +#define PCM_MIXER_H + +/** Simple config **/ + +/* Length of PCM frames (always) */ +#if CONFIG_CPU == PP5002 +/* There's far less time to do mixing because HW FIFOs are short */ +#define MIX_FRAME_SAMPLES 64 +#else +/* Assume HW DMA engine is available or sufficient latency exists in the + PCM pathway */ +#define MIX_FRAME_SAMPLES 256 +#endif + +#if defined(CPU_COLDFIRE) || defined(CPU_PP) +/* For Coldfire, it's just faster + For PortalPlayer, this also avoids more expensive cache coherency */ +#define DOWNMIX_BUF_IBSS IBSS_ATTR +#else +/* Otherwise can't DMA from IRAM, IRAM is pointless or worse */ +#define DOWNMIX_BUF_IBSS +#endif + + +/** Definitions **/ + +/* Channels are preassigned for simplicity */ +enum pcm_mixer_channel +{ + PCM_MIXER_CHAN_PLAYBACK = 0, + PCM_MIXER_CHAN_VOICE, +#ifndef HAVE_HARDWARE_BEEP + PCM_MIXER_CHAN_BEEP, +#endif + /* Add new channel indexes above this line */ + PCM_MIXER_NUM_CHANNELS, +}; + +/* Channel playback states */ +enum channel_status +{ + CHANNEL_STOPPED = 0, + CHANNEL_PLAYING, + CHANNEL_PAUSED, +}; + +#define MIX_AMP_UNITY 0x00010000 +#define MIX_AMP_MUTE 0x00000000 + + +/** Public interfaces **/ + +/* Start playback on a channel */ +void mixer_channel_play_data(enum pcm_mixer_channel channel, + pcm_play_callback_type get_more, + unsigned char *start, size_t size); + +/* Pause or resume a channel (when started) */ +void mixer_channel_play_pause(enum pcm_mixer_channel channel, bool play); + +/* Stop playback on a channel */ +void mixer_channel_stop(enum pcm_mixer_channel channel); + +/* Set channel's amplitude factor */ +void mixer_channel_set_amplitude(enum pcm_mixer_channel channel, + unsigned int amplitude); + +/* Return channel's playback status */ +enum channel_status mixer_channel_status(enum pcm_mixer_channel channel); + +/* Returns amount data remaining in channel before next callback */ +size_t mixer_channel_get_bytes_waiting(enum pcm_mixer_channel channel); + +/* Return pointer to channel's playing audio data and the size remaining */ +void * mixer_channel_get_buffer(enum pcm_mixer_channel channel, int *count); + +/* Stop ALL channels and PCM and reset state */ +void mixer_reset(void); + +#endif /* PCM_MIXER_H */ -- cgit v1.2.3