blob: b10d5863d77fa2b140691c5b75cf7bba62a0141f [file] [log] [blame]
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef AUDIO_H
22#define AUDIO_H
23
24#include <stdbool.h>
Michael Sevakis0f5cb942006-11-06 18:07:30 +000025#include <sys/types.h>
26/* These must always be included with audio.h for this to compile under
27 cetain conditions. Do it here or else spread the complication around to
28 many files. */
29#if CONFIG_CODEC == SWCODEC
30#include "pcm_sampr.h"
Michael Sevakis6077e5b2007-10-06 22:27:27 +000031#include "pcm.h"
Michael Sevakis0f5cb942006-11-06 18:07:30 +000032#ifdef HAVE_RECORDING
33#include "pcm_record.h"
34#include "id3.h"
35#include "enc_base.h"
36#endif /* HAVE_RECORDING */
37#endif /* CONFIG_CODEC == SWCODEC */
38
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +000039
40#ifdef SIMULATOR
41#define audio_play(x) sim_audio_play(x)
42#endif
43
Michael Sevakiseca9f7f2006-12-10 14:21:31 +000044#define AUDIO_STATUS_PLAY 0x0001
45#define AUDIO_STATUS_PAUSE 0x0002
46#define AUDIO_STATUS_RECORD 0x0004
47#define AUDIO_STATUS_PRERECORD 0x0008
48#define AUDIO_STATUS_ERROR 0x0010
49#define AUDIO_STATUS_WARNING 0x0020
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +000050
Michael Sevakiseca9f7f2006-12-10 14:21:31 +000051#define AUDIOERR_DISK_FULL 1
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +000052
Michael Sevakiseca9f7f2006-12-10 14:21:31 +000053#define AUDIO_GAIN_LINEIN 0
54#define AUDIO_GAIN_MIC 1
Andye6e54962005-11-12 04:00:56 +000055
56
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +000057struct audio_debug
58{
Linus Nielsen Feltzingd34865a2005-04-05 11:33:58 +000059 int audiobuflen;
60 int audiobuf_write;
61 int audiobuf_swapwrite;
62 int audiobuf_read;
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +000063
64 int last_dma_chunk_size;
65
66 bool dma_on;
67 bool playing;
68 bool play_pending;
69 bool is_playing;
70 bool filling;
71 bool dma_underrun;
72
73 int unplayed_space;
74 int playable_space;
75 int unswapped_space;
76
77 int low_watermark_level;
78 int lowest_watermark_level;
79};
80
81void audio_init(void);
Steve Bavin135cc752008-03-28 12:51:33 +000082void audio_play(long offset);
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +000083void audio_stop(void);
84void audio_pause(void);
85void audio_resume(void);
86void audio_next(void);
87void audio_prev(void);
88int audio_status(void);
Steve Bavin135cc752008-03-28 12:51:33 +000089void audio_ff_rewind(long newtime);
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +000090void audio_flush_and_reload_tracks(void);
91struct mp3entry* audio_current_track(void);
92struct mp3entry* audio_next_track(void);
93bool audio_has_changed_track(void);
94void audio_get_debugdata(struct audio_debug *dbgdata);
Nils Wallménius0bfa3e72007-08-01 08:50:44 +000095#ifndef HAVE_FLASH_STORAGE
Steve Bavin135cc752008-03-28 12:51:33 +000096void audio_set_buffer_margin(int seconds);
Nils Wallménius0bfa3e72007-08-01 08:50:44 +000097#endif
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +000098unsigned int audio_error(void);
99void audio_error_clear(void);
100int audio_get_file_pos(void);
101void audio_beep(int duration);
102void audio_init_playback(void);
Michael Sevakis99617d72007-11-18 17:12:19 +0000103
Steve Bavinc9df8fd2008-03-28 11:24:24 +0000104/* Required call when audio buffer is required for some other purpose */
Steve Bavin135cc752008-03-28 12:51:33 +0000105unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size);
Steve Bavinc9df8fd2008-03-28 11:24:24 +0000106/* only implemented in playback.c, but called from firmware */
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +0000107
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000108/* channel modes */
109enum rec_channel_modes
110{
111 __CHN_MODE_START_INDEX = -1,
112
113 CHN_MODE_STEREO,
114 CHN_MODE_MONO,
115
116 CHN_NUM_MODES
117};
118
119#if CONFIG_CODEC == SWCODEC
120/* channel mode capability bits */
121#define CHN_CAP_STEREO (1 << CHN_MODE_STEREO)
122#define CHN_CAP_MONO (1 << CHN_MODE_MONO)
123#define CHN_CAP_ALL (CHN_CAP_STEREO | CHN_CAP_MONO)
124#endif /* CONFIG_CODEC == SWCODEC */
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000125
Peter D'Hoyec21abdd2007-08-02 18:45:38 +0000126/* the enums below must match prestr[] in recording.c */
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000127enum audio_sources
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000128{
Michael Sevakis8f659ae2007-05-20 20:26:36 +0000129 AUDIO_SRC_PLAYBACK = -1, /* Virtual source */
130 HAVE_MIC_IN_(AUDIO_SRC_MIC,)
131 HAVE_LINE_IN_(AUDIO_SRC_LINEIN,)
132 HAVE_SPDIF_IN_(AUDIO_SRC_SPDIF,)
133 HAVE_FMRADIO_IN_(AUDIO_SRC_FMRADIO,)
134 AUDIO_NUM_SOURCES,
135 AUDIO_SRC_MAX = AUDIO_NUM_SOURCES-1,
136 AUDIO_SRC_DEFAULT = AUDIO_SRC_PLAYBACK
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000137};
138
Michael Sevakisbcb8a882007-06-05 07:03:30 +0000139extern int audio_channels;
140extern int audio_output_source;
141
Michael Sevakis8f659ae2007-05-20 20:26:36 +0000142#ifdef HAVE_RECORDING
143/* Recordable source implies it has the input as well */
144
145/* For now there's no restrictions on any targets with which inputs
146 are recordable so define them as equivalent - if they do differ,
147 special handling is needed right now. */
148enum rec_sources
149{
150 __REC_SRC_FIRST = -1,
151 HAVE_MIC_REC_(REC_SRC_MIC,)
152 HAVE_LINE_REC_(REC_SRC_LINEIN,)
153 HAVE_SPDIF_REC_(REC_SRC_SPDIF,)
154 HAVE_FMRADIO_REC_(REC_SRC_FMRADIO,)
155 REC_NUM_SOURCES
156};
157#endif /* HAVE_RECORDING */
158
Michael Sevakisab1861a2006-11-23 19:21:15 +0000159#if CONFIG_CODEC == SWCODEC
Michael Sevakis8f659ae2007-05-20 20:26:36 +0000160/* selects a source to monitor for recording or playback */
Michael Sevakisab1861a2006-11-23 19:21:15 +0000161#define SRCF_PLAYBACK 0x0000 /* default */
162#define SRCF_RECORDING 0x1000
Jens Arnoldc6522182007-02-18 08:46:12 +0000163#if CONFIG_TUNER
Michael Sevakisab1861a2006-11-23 19:21:15 +0000164/* for AUDIO_SRC_FMRADIO */
165#define SRCF_FMRADIO_PLAYING 0x0000 /* default */
166#define SRCF_FMRADIO_PAUSED 0x2000
167#endif
168#endif
169
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000170#ifdef HAVE_RECORDING
171/* parameters for audio_set_recording_options */
172struct audio_recording_options
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000173{
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000174 int rec_source;
175 int rec_frequency;
176 int rec_channels;
177 int rec_prerecord_time;
178#if CONFIG_CODEC == SWCODEC
179 int rec_source_flags; /* for rec_set_source */
180 struct encoder_config enc_config;
181#else
182 int rec_quality;
183 bool rec_editable;
184#endif
Michael Sevakis4fc717a2006-08-28 22:38:41 +0000185};
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000186
187/* audio recording functions */
188void audio_init_recording(unsigned int buffer_offset);
189void audio_close_recording(void);
190void audio_record(const char *filename);
191void audio_stop_recording(void);
192void audio_pause_recording(void);
193void audio_resume_recording(void);
194void audio_new_file(const char *filename);
195void audio_set_recording_options(struct audio_recording_options *options);
Andye6e54962005-11-12 04:00:56 +0000196void audio_set_recording_gain(int left, int right, int type);
197unsigned long audio_recorded_time(void);
198unsigned long audio_num_recorded_bytes(void);
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000199
200#if CONFIG_CODEC == SWCODEC
Steve Bavin135cc752008-03-28 12:51:33 +0000201/* SWCODEC recording functions */
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000202/* playback.c */
203bool audio_load_encoder(int afmt);
204void audio_remove_encoder(void);
205unsigned char *audio_get_recording_buffer(size_t *buffer_size);
206#endif /* CONFIG_CODEC == SWCODEC */
Michael Sevakis2d48d0f2007-06-08 23:42:04 +0000207
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000208#endif /* HAVE_RECORDING */
209
Michael Sevakis2d48d0f2007-06-08 23:42:04 +0000210#if CONFIG_CODEC == SWCODEC
211/* SWCODEC misc. audio functions */
212#if INPUT_SRC_CAPS != 0
213/* audio.c */
214void audio_set_input_source(int source, unsigned flags);
215/* audio_input_mux: target-specific implementation used by audio_set_source
216 to set hardware inputs and audio paths */
217void audio_input_mux(int source, unsigned flags);
218void audio_set_output_source(int source);
219#endif /* INPUT_SRC_CAPS */
220#endif /* CONFIG_CODEC == SWCODEC */
221
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000222#ifdef HAVE_SPDIF_IN
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000223/* returns index into rec_master_sampr_list */
224int audio_get_spdif_sample_rate(void);
225/* > 0: monitor EBUin, 0: Monitor IISrecv, <0: reset only */
226void audio_spdif_set_monitor(int monitor_spdif);
227#endif /* HAVE_SPDIF_IN */
228
Linus Nielsen Feltzingda153da2006-10-19 09:42:58 +0000229unsigned long audio_prev_elapsed(void);
Andye6e54962005-11-12 04:00:56 +0000230
231
Linus Nielsen Feltzing0ad617c2005-08-21 23:01:12 +0000232/***********************************************************************/
233/* audio event handling */
234
235/* subscribe to one or more audio event(s) by OR'ing together the desired */
236/* event IDs (defined below); a handler is called with a solitary event ID */
237/* (so switch() is okay) and possibly some useful data (depending on the */
238/* event); a handler must return one of the return codes defined below */
239
240typedef int (*AUDIO_EVENT_HANDLER)(unsigned short event, unsigned long data);
241
242void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask);
243
244/***********************************************************************/
245/* handler return codes */
246
247#define AUDIO_EVENT_RC_IGNORED 200
248 /* indicates that no action was taken or the event was not recognized */
249
250#define AUDIO_EVENT_RC_HANDLED 201
251 /* indicates that the event was handled and some action was taken which renders
252 the original event invalid; USE WITH CARE!; this return code aborts all further
253 processing of the given event */
254
255/***********************************************************************/
256/* audio event IDs */
257
258#define AUDIO_EVENT_POS_REPORT (1<<0)
259 /* sends a periodic song position report to handlers; a report is sent on
260 each kernal tick; the number of ticks per second is defined by HZ; on each
261 report the current song position is passed in 'data'; if a handler takes an
262 action that changes the song or the song position it must return
263 AUDIO_EVENT_RC_HANDLED which suppresses the event for any remaining handlers */
264
265#define AUDIO_EVENT_END_OF_TRACK (1<<1)
266 /* generated when the end of the currently playing track is reached; no
267 data is passed; if the handler implements some alternate end-of-track
268 processing it should return AUDIO_EVENT_RC_HANDLED which suppresses the
269 event for any remaining handlers as well as the normal end-of-track
270 processing */
271
Linus Nielsen Feltzing8a237a82005-04-04 12:06:29 +0000272#endif