Linus Nielsen Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
| 10 | * Copyright (C) 2005 by Linus Nielsen Feltzing |
| 11 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame^] | 12 | * 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 Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 16 | * |
| 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 Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 25 | #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 Sevakis | 6077e5b | 2007-10-06 22:27:27 +0000 | [diff] [blame] | 31 | #include "pcm.h" |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 32 | #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 Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 39 | |
| 40 | #ifdef SIMULATOR |
| 41 | #define audio_play(x) sim_audio_play(x) |
| 42 | #endif |
| 43 | |
Michael Sevakis | eca9f7f | 2006-12-10 14:21:31 +0000 | [diff] [blame] | 44 | #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 Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 50 | |
Michael Sevakis | eca9f7f | 2006-12-10 14:21:31 +0000 | [diff] [blame] | 51 | #define AUDIOERR_DISK_FULL 1 |
Linus Nielsen Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 52 | |
Michael Sevakis | eca9f7f | 2006-12-10 14:21:31 +0000 | [diff] [blame] | 53 | #define AUDIO_GAIN_LINEIN 0 |
| 54 | #define AUDIO_GAIN_MIC 1 |
Andy | e6e5496 | 2005-11-12 04:00:56 +0000 | [diff] [blame] | 55 | |
| 56 | |
Linus Nielsen Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 57 | struct audio_debug |
| 58 | { |
Linus Nielsen Feltzing | d34865a | 2005-04-05 11:33:58 +0000 | [diff] [blame] | 59 | int audiobuflen; |
| 60 | int audiobuf_write; |
| 61 | int audiobuf_swapwrite; |
| 62 | int audiobuf_read; |
Linus Nielsen Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 63 | |
| 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 | |
| 81 | void audio_init(void); |
Steve Bavin | 135cc75 | 2008-03-28 12:51:33 +0000 | [diff] [blame] | 82 | void audio_play(long offset); |
Linus Nielsen Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 83 | void audio_stop(void); |
| 84 | void audio_pause(void); |
| 85 | void audio_resume(void); |
| 86 | void audio_next(void); |
| 87 | void audio_prev(void); |
| 88 | int audio_status(void); |
Steve Bavin | 135cc75 | 2008-03-28 12:51:33 +0000 | [diff] [blame] | 89 | void audio_ff_rewind(long newtime); |
Linus Nielsen Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 90 | void audio_flush_and_reload_tracks(void); |
| 91 | struct mp3entry* audio_current_track(void); |
| 92 | struct mp3entry* audio_next_track(void); |
| 93 | bool audio_has_changed_track(void); |
| 94 | void audio_get_debugdata(struct audio_debug *dbgdata); |
Nils Wallménius | 0bfa3e7 | 2007-08-01 08:50:44 +0000 | [diff] [blame] | 95 | #ifndef HAVE_FLASH_STORAGE |
Steve Bavin | 135cc75 | 2008-03-28 12:51:33 +0000 | [diff] [blame] | 96 | void audio_set_buffer_margin(int seconds); |
Nils Wallménius | 0bfa3e7 | 2007-08-01 08:50:44 +0000 | [diff] [blame] | 97 | #endif |
Linus Nielsen Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 98 | unsigned int audio_error(void); |
| 99 | void audio_error_clear(void); |
| 100 | int audio_get_file_pos(void); |
| 101 | void audio_beep(int duration); |
| 102 | void audio_init_playback(void); |
Michael Sevakis | 99617d7 | 2007-11-18 17:12:19 +0000 | [diff] [blame] | 103 | |
Steve Bavin | c9df8fd | 2008-03-28 11:24:24 +0000 | [diff] [blame] | 104 | /* Required call when audio buffer is required for some other purpose */ |
Steve Bavin | 135cc75 | 2008-03-28 12:51:33 +0000 | [diff] [blame] | 105 | unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size); |
Steve Bavin | c9df8fd | 2008-03-28 11:24:24 +0000 | [diff] [blame] | 106 | /* only implemented in playback.c, but called from firmware */ |
Linus Nielsen Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 107 | |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 108 | /* channel modes */ |
| 109 | enum 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 Sevakis | 4fc717a | 2006-08-28 22:38:41 +0000 | [diff] [blame] | 125 | |
Peter D'Hoye | c21abdd | 2007-08-02 18:45:38 +0000 | [diff] [blame] | 126 | /* the enums below must match prestr[] in recording.c */ |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 127 | enum audio_sources |
Michael Sevakis | 4fc717a | 2006-08-28 22:38:41 +0000 | [diff] [blame] | 128 | { |
Michael Sevakis | 8f659ae | 2007-05-20 20:26:36 +0000 | [diff] [blame] | 129 | 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 Sevakis | 4fc717a | 2006-08-28 22:38:41 +0000 | [diff] [blame] | 137 | }; |
| 138 | |
Michael Sevakis | bcb8a88 | 2007-06-05 07:03:30 +0000 | [diff] [blame] | 139 | extern int audio_channels; |
| 140 | extern int audio_output_source; |
| 141 | |
Michael Sevakis | 8f659ae | 2007-05-20 20:26:36 +0000 | [diff] [blame] | 142 | #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. */ |
| 148 | enum 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 Sevakis | ab1861a | 2006-11-23 19:21:15 +0000 | [diff] [blame] | 159 | #if CONFIG_CODEC == SWCODEC |
Michael Sevakis | 8f659ae | 2007-05-20 20:26:36 +0000 | [diff] [blame] | 160 | /* selects a source to monitor for recording or playback */ |
Michael Sevakis | ab1861a | 2006-11-23 19:21:15 +0000 | [diff] [blame] | 161 | #define SRCF_PLAYBACK 0x0000 /* default */ |
| 162 | #define SRCF_RECORDING 0x1000 |
Jens Arnold | c652218 | 2007-02-18 08:46:12 +0000 | [diff] [blame] | 163 | #if CONFIG_TUNER |
Michael Sevakis | ab1861a | 2006-11-23 19:21:15 +0000 | [diff] [blame] | 164 | /* for AUDIO_SRC_FMRADIO */ |
| 165 | #define SRCF_FMRADIO_PLAYING 0x0000 /* default */ |
| 166 | #define SRCF_FMRADIO_PAUSED 0x2000 |
| 167 | #endif |
| 168 | #endif |
| 169 | |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 170 | #ifdef HAVE_RECORDING |
| 171 | /* parameters for audio_set_recording_options */ |
| 172 | struct audio_recording_options |
Michael Sevakis | 4fc717a | 2006-08-28 22:38:41 +0000 | [diff] [blame] | 173 | { |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 174 | 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 Sevakis | 4fc717a | 2006-08-28 22:38:41 +0000 | [diff] [blame] | 185 | }; |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 186 | |
| 187 | /* audio recording functions */ |
| 188 | void audio_init_recording(unsigned int buffer_offset); |
| 189 | void audio_close_recording(void); |
| 190 | void audio_record(const char *filename); |
| 191 | void audio_stop_recording(void); |
| 192 | void audio_pause_recording(void); |
| 193 | void audio_resume_recording(void); |
| 194 | void audio_new_file(const char *filename); |
| 195 | void audio_set_recording_options(struct audio_recording_options *options); |
Andy | e6e5496 | 2005-11-12 04:00:56 +0000 | [diff] [blame] | 196 | void audio_set_recording_gain(int left, int right, int type); |
| 197 | unsigned long audio_recorded_time(void); |
| 198 | unsigned long audio_num_recorded_bytes(void); |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 199 | |
| 200 | #if CONFIG_CODEC == SWCODEC |
Steve Bavin | 135cc75 | 2008-03-28 12:51:33 +0000 | [diff] [blame] | 201 | /* SWCODEC recording functions */ |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 202 | /* playback.c */ |
| 203 | bool audio_load_encoder(int afmt); |
| 204 | void audio_remove_encoder(void); |
| 205 | unsigned char *audio_get_recording_buffer(size_t *buffer_size); |
| 206 | #endif /* CONFIG_CODEC == SWCODEC */ |
Michael Sevakis | 2d48d0f | 2007-06-08 23:42:04 +0000 | [diff] [blame] | 207 | |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 208 | #endif /* HAVE_RECORDING */ |
| 209 | |
Michael Sevakis | 2d48d0f | 2007-06-08 23:42:04 +0000 | [diff] [blame] | 210 | #if CONFIG_CODEC == SWCODEC |
| 211 | /* SWCODEC misc. audio functions */ |
| 212 | #if INPUT_SRC_CAPS != 0 |
| 213 | /* audio.c */ |
| 214 | void 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 */ |
| 217 | void audio_input_mux(int source, unsigned flags); |
| 218 | void audio_set_output_source(int source); |
| 219 | #endif /* INPUT_SRC_CAPS */ |
| 220 | #endif /* CONFIG_CODEC == SWCODEC */ |
| 221 | |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 222 | #ifdef HAVE_SPDIF_IN |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 223 | /* returns index into rec_master_sampr_list */ |
| 224 | int audio_get_spdif_sample_rate(void); |
| 225 | /* > 0: monitor EBUin, 0: Monitor IISrecv, <0: reset only */ |
| 226 | void audio_spdif_set_monitor(int monitor_spdif); |
| 227 | #endif /* HAVE_SPDIF_IN */ |
| 228 | |
Linus Nielsen Feltzing | da153da | 2006-10-19 09:42:58 +0000 | [diff] [blame] | 229 | unsigned long audio_prev_elapsed(void); |
Andy | e6e5496 | 2005-11-12 04:00:56 +0000 | [diff] [blame] | 230 | |
| 231 | |
Linus Nielsen Feltzing | 0ad617c | 2005-08-21 23:01:12 +0000 | [diff] [blame] | 232 | /***********************************************************************/ |
| 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 | |
| 240 | typedef int (*AUDIO_EVENT_HANDLER)(unsigned short event, unsigned long data); |
| 241 | |
| 242 | void 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 Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 272 | #endif |