rockbox/apps/audio_path.c

190 lines
5.2 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Audio signal path management APIs
*
* Copyright (C) 2007 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.
*
****************************************************************************/
#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
#if defined(IPOD_ACCESSORY_PROTOCOL) && defined(HAVE_LINE_REC)
#include "iap.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
#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) \
|| (defined(SONY_NWZ_LINUX) && !defined(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
#if defined(IPOD_ACCESSORY_PROTOCOL) && defined(HAVE_LINE_REC)
static bool last_rec_onoff = false;
bool onoff = (source == AUDIO_SRC_LINEIN) ? true : false;
if (last_rec_onoff != onoff)
last_rec_onoff = iap_record(onoff);
#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 /* PLATFORM_HOSTED */
/** 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;
#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
} /* 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 /* PLATFORM_NATIVE */
#ifdef HAVE_SPEAKER
void audio_enable_speaker(int mode)
{
#if defined(HAVE_HEADPHONE_DETECTION) || defined(HAVE_LINEOUT_DETECTION)
/* if needed, query jack state */
if(mode == 2)
{
#ifdef HAVE_HEADPHONE_DETECTION
if (headphones_inserted())
mode = 0;
#endif
#ifdef HAVE_LINEOUT_DETECTION
if (lineout_inserted())
mode = 0;
#endif
}
#endif
/* treat any nonzero value as enable */
audiohw_enable_speaker(mode);
}
#endif