From 2d48d0ffa6baddd19e6ff077f25068f90af7be3d Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Fri, 8 Jun 2007 23:42:04 +0000 Subject: Straighten out some audio path APIs and misc. audio stuff. Having recording is not a prerequisite to having input/output source selection which is probably most useful when adding a audio input features like FM to a new port without forcing recording to be implemented first. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13599 a1c6a512-1295-4272-9138-f99709370657 --- apps/SOURCES | 3 + apps/audio_path.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++ apps/debug_menu.c | 4 +- apps/playback.c | 4 +- apps/plugin.c | 7 ++- apps/plugin.h | 7 ++- apps/plugins/test_sampr.c | 6 +- apps/recorder/radio.c | 8 +-- apps/recorder/recording.c | 107 +++++----------------------------- apps/recorder/recording.h | 4 +- 10 files changed, 184 insertions(+), 111 deletions(-) create mode 100644 apps/audio_path.c (limited to 'apps') diff --git a/apps/SOURCES b/apps/SOURCES index ccc481b07b..ccb9ca2772 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -86,6 +86,9 @@ recorder/radio.c recorder/recording.c #endif #if CONFIG_CODEC == SWCODEC +#if INPUT_SRC_CAPS != 0 +audio_path.c +#endif /* INPUT_SRC_CAPS != 0 */ pcmbuf.c playback.c codecs.c diff --git a/apps/audio_path.c b/apps/audio_path.c new file mode 100644 index 0000000000..998b2988c9 --- /dev/null +++ b/apps/audio_path.c @@ -0,0 +1,145 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Audio signal path management APIs + * + * Copyright (C) 2007 by Michael Sevakis + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "system.h" +#include "cpu.h" +#include "audio.h" +#include "general.h" +#include "settings.h" +#if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT) +#ifdef HAVE_SPDIF_POWER +#include "power.h" +#endif +#include "spdif.h" +#endif +#if CONFIG_TUNER +#include "radio.h" +#endif + +/* Some audio sources may require a boosted CPU */ +#ifdef HAVE_ADJUSTABLE_CPU_FREQ +#ifdef HAVE_SPDIF_REC +#define AUDIO_CPU_BOOST +#endif +#endif + +#ifndef SIMULATOR + +#ifdef AUDIO_CPU_BOOST +static void audio_cpu_boost(bool state) +{ + static bool cpu_boosted = false; + + if (state != cpu_boosted) + { + cpu_boost(state); + cpu_boosted = state; + } +} /* audio_cpu_boost */ +#endif /* AUDIO_CPU_BOOST */ + +/** + * Selects an audio source for recording or playback + * powers/unpowers related devices and sets up monitoring. + */ +void audio_set_input_source(int source, unsigned flags) +{ + /** Do power up/down of associated device(s) **/ + + /** SPDIF **/ +#ifdef AUDIO_CPU_BOOST + /* Always boost for SPDIF */ + audio_cpu_boost(source == AUDIO_SRC_SPDIF); +#endif /* AUDIO_CPU_BOOST */ + +#ifdef HAVE_SPDIF_POWER + /* Check if S/PDIF output power should be switched off or on. NOTE: assumes + both optical in and out is controlled by the same power source, which is + the case on H1x0. */ + spdif_power_enable((source == AUDIO_SRC_SPDIF) || + global_settings.spdif_enable); +#endif /* HAVE_SPDIF_POWER */ + /* Set the appropriate feed for spdif output */ +#ifdef HAVE_SPDIF_OUT + spdif_set_output_source(source + IF_SPDIF_POWER_(, global_settings.spdif_enable)); +#endif /* HAVE_SPDIF_OUT */ + + /** Tuner **/ +#if CONFIG_TUNER + /* Switch radio off or on per source and flags. */ + if (source != AUDIO_SRC_FMRADIO) + radio_stop(); + else if (flags & SRCF_FMRADIO_PAUSED) + radio_pause(); + else + radio_start(); +#endif + + /* set hardware inputs */ + audio_input_mux(source, flags); +} /* audio_set_source */ + +#ifdef HAVE_SPDIF_IN +/** + * Return SPDIF sample rate index in audio_master_sampr_list. Since we base + * our reading on the actual SPDIF sample rate (which might be a bit + * inaccurate), we round off to the closest sample rate that is supported by + * SPDIF. + */ +int audio_get_spdif_sample_rate(void) +{ + unsigned long measured_rate = spdif_measure_frequency(); + /* Find which SPDIF sample rate we're closest to. */ + return round_value_to_list32(measured_rate, audio_master_sampr_list, + SAMPR_NUM_FREQ, false); +} /* audio_get_spdif_sample_rate */ +#endif /* HAVE_SPDIF_IN */ + +#else /* SIMULATOR */ + +/** Sim stubs **/ + +#ifdef AUDIO_CPU_BOOST +static void audio_cpu_boost(bool state) +{ + (void)state; +} /* audio_cpu_boost */ +#endif /* AUDIO_CPU_BOOST */ + +void audio_set_output_source(int source) +{ + (void)source; +} /* audio_set_output_source */ + +void audio_set_input_source(int source, unsigned flags) +{ + (void)source; + (void)flags; +} /* audio_set_input_source */ + +#ifdef HAVE_SPDIF_IN +int audio_get_spdif_sample_rate(void) +{ + return FREQ_44; +} /* audio_get_spdif_sample_rate */ +#endif /* HAVE_SPDIF_IN */ + +#endif /* !SIMULATOR */ diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 404d82c63e..691e9f5070 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -693,7 +693,7 @@ static bool dbg_spdif(void) bool done = false; bool spdif_src_on; int spdif_source = spdif_get_output_source(&spdif_src_on); - spdif_set_output_source(AUDIO_SRC_SPDIF, true); + spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true)); lcd_setmargins(0, 0); lcd_clear_display(); @@ -844,7 +844,7 @@ static bool dbg_spdif(void) break; } - spdif_set_output_source(spdif_source, spdif_src_on); + spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on)); #ifdef HAVE_SPDIF_POWER spdif_power_enable(global_settings.spdif_enable); diff --git a/apps/playback.c b/apps/playback.c index b48bcc8c26..9cd82de9b6 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -3301,8 +3301,8 @@ static void audio_stop_playback(void) static void audio_play_start(size_t offset) { -#if defined(HAVE_RECORDING) || CONFIG_TUNER - rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); +#if INPUT_SRC_CAPS != 0 + audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); #endif /* Wait for any previously playing audio to flush - TODO: Not necessary? */ diff --git a/apps/plugin.c b/apps/plugin.c index a63e5cd6ee..79ecae9a1f 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -349,11 +349,12 @@ static const struct plugin_api rockbox_api = { pcm_stop_recording, pcm_calculate_rec_peaks, audio_set_recording_gain, - audio_set_output_source, - rec_set_source, #endif /* HAVE_RECORDING */ - +#if INPUT_SRC_CAPS != 0 + audio_set_output_source, + audio_set_input_source, #endif +#endif /* CONFIG_CODEC == SWCODEC */ /* playback control */ playlist_amount, diff --git a/apps/plugin.h b/apps/plugin.h index 2c8b328fe1..bc6adffab2 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -448,11 +448,12 @@ struct plugin_api { void (*pcm_stop_recording)(void); void (*pcm_calculate_rec_peaks)(int *left, int *right); void (*audio_set_recording_gain)(int left, int right, int type); - void (*audio_set_output_source)(int monitor); - void (*rec_set_source)(int source, unsigned flags); #endif /* HAVE_RECORDING */ - +#if INPUT_SRC_CAPS != 0 + void (*audio_set_output_source)(int monitor); + void (*audio_set_input_source)(int source, unsigned flags); #endif +#endif /* CONFIG_CODEC == SWCODC */ /* playback control */ int (*playlist_amount)(void); diff --git a/apps/plugins/test_sampr.c b/apps/plugins/test_sampr.c index 253c592eaa..e1511e3dfd 100644 --- a/apps/plugins/test_sampr.c +++ b/apps/plugins/test_sampr.c @@ -199,9 +199,9 @@ void play_waveform(void) rb->audio_stop(); rb->sound_set(SOUND_VOLUME, rb->sound_default(SOUND_VOLUME)); -#ifdef HAVE_RECORDING +#ifdef INPUT_SRC_CAPS != 0 /* Select playback */ - rb->rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); + rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); #endif #ifdef HAVE_ADJUSTABLE_CPU_FREQ @@ -210,7 +210,7 @@ void play_waveform(void) rb->pcm_set_frequency(rb->hw_freq_sampr[freq]); -#ifdef HAVE_RECORDING +#ifdef INPUT_SRC_CAPS != 0 /* Recordable targets can play back from other sources */ rb->audio_set_output_source(AUDIO_SRC_PLAYBACK); #endif diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index 9f3228be1f..23e820e835 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c @@ -509,9 +509,9 @@ int radio_screen(void) /* turn on radio */ #if CONFIG_CODEC == SWCODEC - rec_set_source(AUDIO_SRC_FMRADIO, - (radio_status == FMRADIO_PAUSED) ? - SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING); + audio_set_input_source(AUDIO_SRC_FMRADIO, + (radio_status == FMRADIO_PAUSED) ? + SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING); #else if (radio_status == FMRADIO_OFF) radio_start(); @@ -985,7 +985,7 @@ int radio_screen(void) else { #if CONFIG_CODEC == SWCODEC - rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); + audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); #else radio_stop(); #endif diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c index 5738a34949..226ff9a17f 100644 --- a/apps/recorder/recording.c +++ b/apps/recorder/recording.c @@ -547,80 +547,6 @@ int rec_create_directory(void) return 0; } -#if CONFIG_CODEC == SWCODEC && !defined(SIMULATOR) - -# ifdef HAVE_SPDIF_REC -# ifdef HAVE_ADJUSTABLE_CPU_FREQ -static void rec_boost(bool state) -{ - static bool cpu_boosted = false; - - if (state != cpu_boosted) - { - cpu_boost(state); - cpu_boosted = state; - } -} -# endif -# endif - -/** - * Selects an audio source for recording or playback - * powers/unpowers related devices and sets up monitoring. - * Here because it calls app code and used only for HAVE_RECORDING atm. - * Would like it in pcm_record.c. - * - * Behaves like a firmware function in that it does not use global settings - * to determine the state. - * - * The order of setting monitoring may need tweaking dependent upon the - * selected source to get the smoothest transition. - */ -void rec_set_source(int source, unsigned flags) -{ - /** Do power up/down of associated device(s) **/ - - /** SPDIF **/ -#ifdef HAVE_SPDIF_REC - /* Always boost for SPDIF */ - rec_boost(source == AUDIO_SRC_SPDIF); -#endif /* HAVE_SPDIF_IN */ - -#ifdef HAVE_SPDIF_POWER - /* Check if S/PDIF output power should be switched off or on. NOTE: assumes - both optical in and out is controlled by the same power source, which is - the case on H1x0. */ - spdif_power_enable((source == AUDIO_SRC_SPDIF) || - global_settings.spdif_enable); - /* Set the appropriate feed for spdif output */ -#ifdef HAVE_SPDIF_OUT - spdif_set_output_source(source, global_settings.spdif_enable); -#endif -#else /* !HAVE_SPDIF_POWER */ -#ifdef HAVE_SPDIF_OUT - spdif_set_output_source(source, true); -#endif -#endif /* !HAVE_SPDIF_POWER */ - - /** Tuner **/ -#if CONFIG_TUNER - /* Switch radio off or on per source and flags. */ - if (source != AUDIO_SRC_FMRADIO) - radio_stop(); - else if (flags & SRCF_FMRADIO_PAUSED) - radio_pause(); - else - radio_start(); -#endif - - /* set hardware inputs */ - audio_set_source(source, flags); - - peak_meter_playback((flags & SRCF_RECORDING) == 0); - peak_meter_enabled = true; -} /* rec_set_source */ -#endif /* CONFIG_CODEC == SWCODEC && !defined(SIMULATOR) */ - void rec_init_recording_options(struct audio_recording_options *options) { options->rec_source = global_settings.rec_source; @@ -637,6 +563,18 @@ void rec_init_recording_options(struct audio_recording_options *options) #endif } +#if CONFIG_CODEC == SWCODEC && !defined (SIMULATOR) +void rec_set_source(int source, unsigned flags) +{ + /* Set audio input source, power up/down devices */ + audio_set_input_source(source, flags); + + /* Set peakmeters for recording or reset to playback */ + peak_meter_playback((flags & SRCF_RECORDING) == 0); + peak_meter_enabled = true; +} +#endif /* CONFIG_CODEC == SWCODEC && !defined (SIMULATOR) */ + void rec_set_recording_options(struct audio_recording_options *options) { #if CONFIG_CODEC != SWCODEC @@ -2062,20 +2000,6 @@ void rec_set_source(int source, unsigned flags) flags = flags; } -#ifdef HAVE_SPDIF_IN -#ifdef HAVE_SPDIF_POWER -void audio_set_spdif_power_setting(bool on) -{ - on = on; -} - -bool audio_get_spdif_power_setting(void) -{ - return true; -} -#endif /* HAVE_SPDIF_POWER */ -#endif /* HAVE_SPDIF_IN */ - void audio_set_recording_options(struct audio_recording_options *options) { options = options; @@ -2088,13 +2012,12 @@ void audio_set_recording_gain(int left, int right, int type) type = type; } -void audio_set_output_source(int source) +void audio_record(const char *filename) { - source = source; + filename = filename; } - -void audio_record(const char *filename) +void audio_new_file(const char *filename) { filename = filename; } diff --git a/apps/recorder/recording.h b/apps/recorder/recording.h index 3ca1f35834..50a73856cf 100644 --- a/apps/recorder/recording.h +++ b/apps/recorder/recording.h @@ -29,7 +29,7 @@ int rec_create_directory(void); extern bool recording_start_automatic; #if CONFIG_CODEC == SWCODEC -/* handles device powerup and sets audio source */ +/* handles device powerup, sets audio source and peakmeter mode */ void rec_set_source(int source, unsigned flags); #endif /* CONFIG_CODEC == SW_CODEC */ @@ -47,4 +47,4 @@ void rec_record(void); /* creates unique filename and starts recording */ void rec_new_file(void); -#endif +#endif /* RECORDING_H */ -- cgit v1.2.3