summaryrefslogtreecommitdiff
path: root/apps/audio_path.c
blob: 6417adadb995ab59b95ef94365c626ea3e64f796 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/***************************************************************************
 *             __________               __   ___.
 *   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