A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Audio signal path management APIs
11 *
12 * Copyright (C) 2007 by Michael Sevakis
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23#include "system.h"
24#include "cpu.h"
25#include "audio.h"
26#include "general.h"
27#include "settings.h"
28#if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT)
29#ifdef HAVE_SPDIF_POWER
30#include "power.h"
31#endif
32#include "spdif.h"
33#endif
34#if CONFIG_TUNER
35#include "radio.h"
36#endif
37#if defined(IPOD_ACCESSORY_PROTOCOL) && defined(HAVE_LINE_REC)
38#include "iap.h"
39#endif
40
41/* Some audio sources may require a boosted CPU */
42#ifdef HAVE_ADJUSTABLE_CPU_FREQ
43#ifdef HAVE_SPDIF_REC
44#define AUDIO_CPU_BOOST
45#endif
46#endif
47
48#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) \
49 || (defined(SONY_NWZ_LINUX) && !defined(SIMULATOR)))
50
51#ifdef AUDIO_CPU_BOOST
52static void audio_cpu_boost(bool state)
53{
54 static bool cpu_boosted = false;
55
56 if (state != cpu_boosted)
57 {
58 cpu_boost(state);
59 cpu_boosted = state;
60 }
61} /* audio_cpu_boost */
62#endif /* AUDIO_CPU_BOOST */
63
64/**
65 * Selects an audio source for recording or playback
66 * powers/unpowers related devices and sets up monitoring.
67 */
68void audio_set_input_source(int source, unsigned flags)
69{
70 /** Do power up/down of associated device(s) **/
71
72 /** SPDIF **/
73#ifdef AUDIO_CPU_BOOST
74 /* Always boost for SPDIF */
75 audio_cpu_boost(source == AUDIO_SRC_SPDIF);
76#endif /* AUDIO_CPU_BOOST */
77
78#ifdef HAVE_SPDIF_POWER
79 /* Check if S/PDIF output power should be switched off or on. NOTE: assumes
80 both optical in and out is controlled by the same power source, which is
81 the case on H1x0. */
82 spdif_power_enable((source == AUDIO_SRC_SPDIF) ||
83 global_settings.spdif_enable);
84#endif /* HAVE_SPDIF_POWER */
85 /* Set the appropriate feed for spdif output */
86#ifdef HAVE_SPDIF_OUT
87 spdif_set_output_source(source
88 IF_SPDIF_POWER_(, global_settings.spdif_enable));
89#endif /* HAVE_SPDIF_OUT */
90
91 /** Tuner **/
92#if CONFIG_TUNER
93 /* Switch radio off or on per source and flags. */
94 if (source != AUDIO_SRC_FMRADIO)
95 radio_stop();
96 else if (flags & SRCF_FMRADIO_PAUSED)
97 radio_pause();
98 else
99 radio_start();
100#endif
101
102#if defined(IPOD_ACCESSORY_PROTOCOL) && defined(HAVE_LINE_REC)
103 static bool last_rec_onoff = false;
104 bool onoff = (source == AUDIO_SRC_LINEIN) ? true : false;
105 if (last_rec_onoff != onoff)
106 last_rec_onoff = iap_record(onoff);
107#endif
108
109 /* set hardware inputs */
110 audio_input_mux(source, flags);
111} /* audio_set_source */
112
113#ifdef HAVE_SPDIF_IN
114/**
115 * Return SPDIF sample rate index in audio_master_sampr_list. Since we base
116 * our reading on the actual SPDIF sample rate (which might be a bit
117 * inaccurate), we round off to the closest sample rate that is supported by
118 * SPDIF.
119 */
120int audio_get_spdif_sample_rate(void)
121{
122 unsigned long measured_rate = spdif_measure_frequency();
123 /* Find which SPDIF sample rate we're closest to. */
124 return round_value_to_list32(measured_rate, audio_master_sampr_list,
125 SAMPR_NUM_FREQ, false);
126} /* audio_get_spdif_sample_rate */
127#endif /* HAVE_SPDIF_IN */
128
129#else /* PLATFORM_HOSTED */
130
131/** Sim stubs **/
132
133#ifdef AUDIO_CPU_BOOST
134static void audio_cpu_boost(bool state)
135{
136 (void)state;
137} /* audio_cpu_boost */
138#endif /* AUDIO_CPU_BOOST */
139
140void audio_set_output_source(int source)
141{
142 (void)source;
143} /* audio_set_output_source */
144
145void audio_set_input_source(int source, unsigned flags)
146{
147 (void)source;
148 (void)flags;
149#if CONFIG_TUNER
150 /* Switch radio off or on per source and flags. */
151 if (source != AUDIO_SRC_FMRADIO)
152 radio_stop();
153 else if (flags & SRCF_FMRADIO_PAUSED)
154 radio_pause();
155 else
156 radio_start();
157#endif
158} /* audio_set_input_source */
159
160#ifdef HAVE_SPDIF_IN
161int audio_get_spdif_sample_rate(void)
162{
163 return FREQ_44;
164} /* audio_get_spdif_sample_rate */
165#endif /* HAVE_SPDIF_IN */
166
167#endif /* PLATFORM_NATIVE */
168
169#ifdef HAVE_SPEAKER
170void audio_enable_speaker(int mode)
171{
172#if defined(HAVE_HEADPHONE_DETECTION) || defined(HAVE_LINEOUT_DETECTION)
173 /* if needed, query jack state */
174 if(mode == 2)
175 {
176#ifdef HAVE_HEADPHONE_DETECTION
177 if (headphones_inserted())
178 mode = 0;
179#endif
180#ifdef HAVE_LINEOUT_DETECTION
181 if (lineout_inserted())
182 mode = 0;
183#endif
184 }
185#endif
186 /* treat any nonzero value as enable */
187 audiohw_enable_speaker(mode);
188}
189#endif