Make PCM->driver interface about as simple as it will get. Registered callback, zero data, alignment and stops are handled entirely inside pcm.c; driver merely calls fixed pcm.c callback. Remove pcm_record_more and do it just like playback; the original reason behind it isn't very practical in general. Everything checks out on supported targets. There wer some compat changes I can't check out on many unsupoorted but if there's a problem it will be a minor oops. Plugins become incompatible due to recording tweak-- full update. Sorted API.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26253 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
6688988ec4
commit
d56999890f
19 changed files with 277 additions and 460 deletions
|
@ -177,6 +177,9 @@ static const struct plugin_api rockbox_api = {
|
|||
&button_queue,
|
||||
#endif
|
||||
bidi_l2v,
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
is_diacritic,
|
||||
#endif
|
||||
font_get_bits,
|
||||
font_load,
|
||||
font_get,
|
||||
|
@ -461,6 +464,9 @@ static const struct plugin_api rockbox_api = {
|
|||
sound_max,
|
||||
sound_unit,
|
||||
sound_val2phys,
|
||||
#ifdef AUDIOHW_HAVE_EQ
|
||||
sound_enum_hw_eq_band_setting,
|
||||
#endif
|
||||
#ifndef SIMULATOR
|
||||
mp3_play_data,
|
||||
mp3_play_pause,
|
||||
|
@ -491,7 +497,6 @@ static const struct plugin_api rockbox_api = {
|
|||
pcm_init_recording,
|
||||
pcm_close_recording,
|
||||
pcm_record_data,
|
||||
pcm_record_more,
|
||||
pcm_stop_recording,
|
||||
pcm_calculate_rec_peaks,
|
||||
audio_set_recording_gain,
|
||||
|
@ -630,7 +635,12 @@ static const struct plugin_api rockbox_api = {
|
|||
codec_thread_do_callback,
|
||||
codec_load_file,
|
||||
get_codec_filename,
|
||||
find_array_ptr,
|
||||
remove_array_ptr,
|
||||
#if defined(HAVE_RECORDING) && (defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN))
|
||||
round_value_to_list32,
|
||||
#endif
|
||||
#endif /* CONFIG_CODEC == SWCODEC */
|
||||
get_metadata,
|
||||
mp3info,
|
||||
count_mp3_frames,
|
||||
|
@ -711,24 +721,6 @@ static const struct plugin_api rockbox_api = {
|
|||
appsversion,
|
||||
/* new stuff at the end, sort into place next time
|
||||
the API gets incompatible */
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
is_diacritic,
|
||||
#endif
|
||||
|
||||
#if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && \
|
||||
(defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN))
|
||||
round_value_to_list32,
|
||||
#endif
|
||||
|
||||
#ifdef AUDIOHW_HAVE_EQ
|
||||
sound_enum_hw_eq_band_setting,
|
||||
#endif
|
||||
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
find_array_ptr,
|
||||
remove_array_ptr,
|
||||
#endif
|
||||
};
|
||||
|
||||
int plugin_load(const char* plugin, const void* parameter)
|
||||
|
|
|
@ -144,12 +144,12 @@ void* plugin_get_buffer(size_t *buffer_size);
|
|||
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
||||
|
||||
/* increase this every time the api struct changes */
|
||||
#define PLUGIN_API_VERSION 186
|
||||
#define PLUGIN_API_VERSION 187
|
||||
|
||||
/* update this to latest version if a change to the api struct breaks
|
||||
backwards compatibility (and please take the opportunity to sort in any
|
||||
new function which are "waiting" at the end of the function table) */
|
||||
#define PLUGIN_MIN_API_VERSION 182
|
||||
#define PLUGIN_MIN_API_VERSION 187
|
||||
|
||||
/* plugin return codes */
|
||||
enum plugin_status {
|
||||
|
@ -259,6 +259,9 @@ struct plugin_api {
|
|||
struct event_queue *button_queue;
|
||||
#endif
|
||||
unsigned short *(*bidi_l2v)( const unsigned char *str, int orientation );
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
bool (*is_diacritic)(const unsigned short char_code, bool *is_rtl);
|
||||
#endif
|
||||
const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code );
|
||||
int (*font_load)(struct font*, const char *path);
|
||||
struct font* (*font_get)(int font);
|
||||
|
@ -577,6 +580,10 @@ struct plugin_api {
|
|||
int (*sound_max)(int setting);
|
||||
const char * (*sound_unit)(int setting);
|
||||
int (*sound_val2phys)(int setting, int value);
|
||||
#ifdef AUDIOHW_HAVE_EQ
|
||||
int (*sound_enum_hw_eq_band_setting)(unsigned int band,
|
||||
unsigned int band_setting);
|
||||
#endif /* AUDIOHW_HAVE_EQ */
|
||||
#ifndef SIMULATOR
|
||||
void (*mp3_play_data)(const unsigned char* start, int size,
|
||||
void (*get_more)(unsigned char** start, size_t* size));
|
||||
|
@ -591,7 +598,7 @@ struct plugin_api {
|
|||
const unsigned long *audio_master_sampr_list;
|
||||
const unsigned long *hw_freq_sampr;
|
||||
void (*pcm_apply_settings)(void);
|
||||
void (*pcm_play_data)(pcm_more_callback_type get_more,
|
||||
void (*pcm_play_data)(pcm_play_callback_type get_more,
|
||||
unsigned char* start, size_t size);
|
||||
void (*pcm_play_stop)(void);
|
||||
void (*pcm_set_frequency)(unsigned int frequency);
|
||||
|
@ -610,9 +617,8 @@ struct plugin_api {
|
|||
const unsigned long *rec_freq_sampr;
|
||||
void (*pcm_init_recording)(void);
|
||||
void (*pcm_close_recording)(void);
|
||||
void (*pcm_record_data)(pcm_more_callback_type2 more_ready,
|
||||
void (*pcm_record_data)(pcm_rec_callback_type more_ready,
|
||||
void *start, size_t size);
|
||||
void (*pcm_record_more)(void *start, size_t size);
|
||||
void (*pcm_stop_recording)(void);
|
||||
void (*pcm_calculate_rec_peaks)(int *left, int *right);
|
||||
void (*audio_set_recording_gain)(int left, int right, int type);
|
||||
|
@ -774,7 +780,15 @@ struct plugin_api {
|
|||
unsigned int *audio_thread_id);
|
||||
int (*codec_load_file)(const char* codec, struct codec_api *api);
|
||||
const char *(*get_codec_filename)(int cod_spec);
|
||||
void ** (*find_array_ptr)(void **arr, void *ptr);
|
||||
int (*remove_array_ptr)(void **arr, void *ptr);
|
||||
#if defined(HAVE_RECORDING) && (defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN))
|
||||
int (*round_value_to_list32)(unsigned long value,
|
||||
const unsigned long list[],
|
||||
int count,
|
||||
bool signd);
|
||||
#endif
|
||||
#endif /* CONFIG_CODEC == SWCODEC */
|
||||
bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname);
|
||||
bool (*mp3info)(struct mp3entry *entry, const char *filename);
|
||||
int (*count_mp3_frames)(int fd, int startpos, int filesize,
|
||||
|
@ -874,28 +888,6 @@ struct plugin_api {
|
|||
const char *appsversion;
|
||||
/* new stuff at the end, sort into place next time
|
||||
the API gets incompatible */
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
bool (*is_diacritic)(const unsigned short char_code, bool *is_rtl);
|
||||
#endif
|
||||
|
||||
#if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && \
|
||||
(defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN))
|
||||
int (*round_value_to_list32)(unsigned long value,
|
||||
const unsigned long list[],
|
||||
int count,
|
||||
bool signd);
|
||||
#endif
|
||||
|
||||
#ifdef AUDIOHW_HAVE_EQ
|
||||
int (*sound_enum_hw_eq_band_setting)(unsigned int band,
|
||||
unsigned int band_setting);
|
||||
#endif /* AUDIOHW_HAVE_EQ */
|
||||
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
void ** (*find_array_ptr)(void **arr, void *ptr);
|
||||
int (*remove_array_ptr)(void **arr, void *ptr);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* plugin header */
|
||||
|
|
|
@ -982,7 +982,7 @@ uint32_t ICODE_ATTR buffer_magnitude(int16_t *input)
|
|||
|
||||
/* Stop the recording when the buffer is full */
|
||||
#ifndef SIMULATOR
|
||||
int recording_callback(int status)
|
||||
void recording_callback(int status, void **start, size_t *size)
|
||||
{
|
||||
int tail = audio_tail ^ 1;
|
||||
|
||||
|
@ -991,10 +991,9 @@ int recording_callback(int status)
|
|||
audio_tail = tail;
|
||||
|
||||
/* Always record full buffer, even if not required */
|
||||
rb->pcm_record_more(audio_data[tail],
|
||||
BUFFER_SIZE * sizeof (int16_t));
|
||||
*start = audio_data[tail];
|
||||
*size = BUFFER_SIZE * sizeof (int16_t);
|
||||
|
||||
return 0;
|
||||
(void)status;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -256,7 +256,7 @@ enum
|
|||
/*******************************************************************/
|
||||
|
||||
/* Callback for when more data is ready - called in interrupt context */
|
||||
static int pcm_rec_have_more(int status)
|
||||
static void pcm_rec_have_more(int status, void **start, size_t *size)
|
||||
{
|
||||
if (status < 0)
|
||||
{
|
||||
|
@ -265,9 +265,9 @@ static int pcm_rec_have_more(int status)
|
|||
{
|
||||
/* Flush recorded data to disk and stop recording */
|
||||
queue_post(&pcmrec_queue, PCMREC_STOP, 0);
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
/* else try again next transmission */
|
||||
/* else try again next transmission - frame is invalid */
|
||||
}
|
||||
else if (!dma_lock)
|
||||
{
|
||||
|
@ -282,8 +282,8 @@ static int pcm_rec_have_more(int status)
|
|||
dma_wr_pos = next_pos;
|
||||
}
|
||||
|
||||
pcm_record_more(GET_PCM_CHUNK(dma_wr_pos), PCM_CHUNK_SIZE);
|
||||
return 0;
|
||||
*start = GET_PCM_CHUNK(dma_wr_pos);
|
||||
*size = PCM_CHUNK_SIZE;
|
||||
} /* pcm_rec_have_more */
|
||||
|
||||
static void reset_hardware(void)
|
||||
|
|
|
@ -89,7 +89,7 @@ enum voice_thread_messages
|
|||
/* Structure to store clip data callback info */
|
||||
struct voice_info
|
||||
{
|
||||
pcm_more_callback_type get_more; /* Callback to get more clips */
|
||||
pcm_play_callback_type get_more; /* Callback to get more clips */
|
||||
unsigned char *start; /* Start of clip */
|
||||
size_t size; /* Size of clip */
|
||||
};
|
||||
|
@ -117,7 +117,7 @@ static inline bool playback_is_playing(void)
|
|||
|
||||
/* Stop any current clip and start playing a new one */
|
||||
void mp3_play_data(const unsigned char* start, int size,
|
||||
pcm_more_callback_type get_more)
|
||||
pcm_play_callback_type get_more)
|
||||
{
|
||||
/* Shared struct to get data to the thread - once it replies, it has
|
||||
* safely cached it in its own private data */
|
||||
|
|
|
@ -50,9 +50,9 @@
|
|||
/** RAW PCM routines used with playback and recording **/
|
||||
|
||||
/* Typedef for registered callback */
|
||||
typedef void (*pcm_more_callback_type)(unsigned char **start,
|
||||
typedef void (*pcm_play_callback_type)(unsigned char **start,
|
||||
size_t *size);
|
||||
typedef int (*pcm_more_callback_type2)(int status);
|
||||
typedef void (*pcm_rec_callback_type)(int status, void **start, size_t *size);
|
||||
|
||||
/* set the pcm frequency - use values in hw_sampr_list
|
||||
* use -1 for the default frequency
|
||||
|
@ -71,7 +71,7 @@ void pcm_init(void);
|
|||
void pcm_postinit(void);
|
||||
|
||||
/* This is for playing "raw" PCM data */
|
||||
void pcm_play_data(pcm_more_callback_type get_more,
|
||||
void pcm_play_data(pcm_play_callback_type get_more,
|
||||
unsigned char* start, size_t size);
|
||||
|
||||
void pcm_calculate_peaks(int *left, int *right);
|
||||
|
@ -86,6 +86,11 @@ bool pcm_is_playing(void);
|
|||
/** The following are for internal use between pcm.c and target-
|
||||
specific portion **/
|
||||
|
||||
/* Called by the bottom layer ISR when more data is needed. Returns non-
|
||||
* zero size if more data is to be played. Setting start to NULL
|
||||
* forces stop. */
|
||||
void pcm_play_get_more_callback(void **start, size_t *size);
|
||||
|
||||
extern unsigned long pcm_curr_sampr;
|
||||
extern unsigned long pcm_sampr;
|
||||
extern int pcm_fsel;
|
||||
|
@ -94,10 +99,8 @@ extern int pcm_fsel;
|
|||
void * pcm_dma_addr(void *addr);
|
||||
#endif
|
||||
|
||||
/* the registered callback function to ask for more mp3 data */
|
||||
extern volatile pcm_more_callback_type pcm_callback_for_more;
|
||||
extern volatile bool pcm_playing;
|
||||
extern volatile bool pcm_paused;
|
||||
extern volatile bool pcm_playing;
|
||||
extern volatile bool pcm_paused;
|
||||
|
||||
void pcm_play_dma_lock(void);
|
||||
void pcm_play_dma_unlock(void);
|
||||
|
@ -105,7 +108,6 @@ void pcm_play_dma_init(void);
|
|||
void pcm_play_dma_start(const void *addr, size_t size);
|
||||
void pcm_play_dma_stop(void);
|
||||
void pcm_play_dma_pause(bool pause);
|
||||
void pcm_play_dma_stopped_callback(void);
|
||||
const void * pcm_play_dma_get_peak_buffer(int *count);
|
||||
|
||||
void pcm_dma_apply_settings(void);
|
||||
|
@ -124,7 +126,7 @@ void pcm_init_recording(void);
|
|||
void pcm_close_recording(void);
|
||||
|
||||
/* Start recording "raw" PCM data */
|
||||
void pcm_record_data(pcm_more_callback_type2 more_ready,
|
||||
void pcm_record_data(pcm_rec_callback_type more_ready,
|
||||
void *start, size_t size);
|
||||
|
||||
/* Stop tranferring data into supplied buffer */
|
||||
|
@ -133,17 +135,16 @@ void pcm_stop_recording(void);
|
|||
/* Is pcm currently recording? */
|
||||
bool pcm_is_recording(void);
|
||||
|
||||
/* Continue transferring data in - call during interrupt handler */
|
||||
void pcm_record_more(void *start, size_t size);
|
||||
/* Called by bottom layer ISR when transfer is complete. Returns non-zero
|
||||
* size if successful. Setting start to NULL forces stop. */
|
||||
void pcm_rec_more_ready_callback(int status, void **start, size_t *size);
|
||||
|
||||
void pcm_calculate_rec_peaks(int *left, int *right);
|
||||
|
||||
/** The following are for internal use between pcm.c and target-
|
||||
specific portion **/
|
||||
/* the registered callback function for when more data is available */
|
||||
extern volatile pcm_more_callback_type2 pcm_callback_more_ready;
|
||||
/* DMA transfer in is currently active */
|
||||
extern volatile bool pcm_recording;
|
||||
extern volatile bool pcm_recording;
|
||||
|
||||
/* APIs implemented in the target-specific portion */
|
||||
void pcm_rec_dma_init(void);
|
||||
|
@ -151,7 +152,6 @@ void pcm_rec_dma_close(void);
|
|||
void pcm_rec_dma_start(void *addr, size_t size);
|
||||
void pcm_rec_dma_record_more(void *start, size_t size);
|
||||
void pcm_rec_dma_stop(void);
|
||||
void pcm_rec_dma_stopped_callback(void);
|
||||
const void * pcm_rec_dma_get_peak_buffer(void);
|
||||
|
||||
#endif /* HAVE_RECORDING */
|
||||
|
|
150
firmware/pcm.c
150
firmware/pcm.c
|
@ -39,6 +39,7 @@
|
|||
* pcm_play_lock
|
||||
* pcm_play_unlock
|
||||
* Semi-private -
|
||||
* pcm_play_get_more_callback
|
||||
* pcm_play_dma_init
|
||||
* pcm_play_dma_start
|
||||
* pcm_play_dma_stop
|
||||
|
@ -48,28 +49,27 @@
|
|||
* pcm_sampr (R)
|
||||
* pcm_fsel (R)
|
||||
* pcm_curr_sampr (R)
|
||||
* pcm_callback_for_more (R)
|
||||
* pcm_playing (R)
|
||||
* pcm_paused (R)
|
||||
*
|
||||
* ==Playback/Recording==
|
||||
* Public -
|
||||
* pcm_dma_addr
|
||||
* Semi-private -
|
||||
* pcm_dma_apply_settings
|
||||
* pcm_dma_addr
|
||||
*
|
||||
* ==Recording==
|
||||
* Public -
|
||||
* pcm_rec_lock
|
||||
* pcm_rec_unlock
|
||||
* Semi-private -
|
||||
* pcm_rec_more_ready_callback
|
||||
* pcm_rec_dma_init
|
||||
* pcm_rec_dma_close
|
||||
* pcm_rec_dma_start
|
||||
* pcm_rec_dma_record_more
|
||||
* pcm_rec_dma_stop
|
||||
* pcm_rec_dma_get_peak_buffer
|
||||
* Data Read/Written within TSP -
|
||||
* pcm_callback_more_ready (R)
|
||||
* pcm_recording (R)
|
||||
*
|
||||
* States are set _after_ the target's pcm driver is called so that it may
|
||||
|
@ -78,7 +78,7 @@
|
|||
*/
|
||||
|
||||
/* the registered callback function to ask for more mp3 data */
|
||||
volatile pcm_more_callback_type pcm_callback_for_more
|
||||
static volatile pcm_play_callback_type pcm_callback_for_more
|
||||
SHAREDBSS_ATTR = NULL;
|
||||
/* PCM playback state */
|
||||
volatile bool pcm_playing SHAREDBSS_ATTR = false;
|
||||
|
@ -91,6 +91,14 @@ unsigned long pcm_sampr SHAREDBSS_ATTR = HW_SAMPR_DEFAULT;
|
|||
/* samplerate frequency selection index */
|
||||
int pcm_fsel SHAREDBSS_ATTR = HW_FREQ_DEFAULT;
|
||||
|
||||
/* Called internally by functions to reset the state */
|
||||
static void pcm_play_stopped(void)
|
||||
{
|
||||
pcm_callback_for_more = NULL;
|
||||
pcm_paused = false;
|
||||
pcm_playing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform peak calculation on a buffer of packed 16-bit samples.
|
||||
*
|
||||
|
@ -187,6 +195,16 @@ const void* pcm_get_peak_buffer(int * count)
|
|||
return pcm_play_dma_get_peak_buffer(count);
|
||||
}
|
||||
|
||||
bool pcm_is_playing(void)
|
||||
{
|
||||
return pcm_playing;
|
||||
}
|
||||
|
||||
bool pcm_is_paused(void)
|
||||
{
|
||||
return pcm_paused;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Functions that do not require targeted implementation but only a targeted
|
||||
* interface
|
||||
|
@ -198,7 +216,7 @@ void pcm_init(void)
|
|||
{
|
||||
logf("pcm_init");
|
||||
|
||||
pcm_play_dma_stopped_callback();
|
||||
pcm_play_stopped();
|
||||
|
||||
pcm_set_frequency(HW_SAMPR_DEFAULT);
|
||||
|
||||
|
@ -214,7 +232,7 @@ static void pcm_play_data_start(unsigned char *start, size_t size)
|
|||
|
||||
if (!(start && size))
|
||||
{
|
||||
pcm_more_callback_type get_more = pcm_callback_for_more;
|
||||
pcm_play_callback_type get_more = pcm_callback_for_more;
|
||||
size = 0;
|
||||
if (get_more)
|
||||
{
|
||||
|
@ -239,10 +257,10 @@ static void pcm_play_data_start(unsigned char *start, size_t size)
|
|||
/* Force a stop */
|
||||
logf(" pcm_play_dma_stop");
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
pcm_play_stopped();
|
||||
}
|
||||
|
||||
void pcm_play_data(pcm_more_callback_type get_more,
|
||||
void pcm_play_data(pcm_play_callback_type get_more,
|
||||
unsigned char *start, size_t size)
|
||||
{
|
||||
logf("pcm_play_data");
|
||||
|
@ -257,6 +275,29 @@ void pcm_play_data(pcm_more_callback_type get_more,
|
|||
pcm_play_unlock();
|
||||
}
|
||||
|
||||
void pcm_play_get_more_callback(void **start, size_t *size)
|
||||
{
|
||||
pcm_play_callback_type get_more = pcm_callback_for_more;
|
||||
|
||||
*size = 0;
|
||||
|
||||
if (get_more && start)
|
||||
{
|
||||
/* Call registered callback */
|
||||
get_more((unsigned char **)start, size);
|
||||
|
||||
*start = (void *)(((uintptr_t)*start + 3) & ~3);
|
||||
*size &= ~3;
|
||||
|
||||
if (*start && *size)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Error, callback missing or no more DMA to do */
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_stopped();
|
||||
}
|
||||
|
||||
void pcm_play_pause(bool play)
|
||||
{
|
||||
logf("pcm_play_pause: %s", play ? "play" : "pause");
|
||||
|
@ -302,7 +343,7 @@ void pcm_play_stop(void)
|
|||
{
|
||||
logf(" pcm_play_dma_stop");
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
pcm_play_stopped();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -312,13 +353,6 @@ void pcm_play_stop(void)
|
|||
pcm_play_unlock();
|
||||
}
|
||||
|
||||
void pcm_play_dma_stopped_callback(void)
|
||||
{
|
||||
pcm_callback_for_more = NULL;
|
||||
pcm_paused = false;
|
||||
pcm_playing = false;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
/* set frequency next frequency used by the audio hardware -
|
||||
|
@ -350,27 +384,24 @@ void pcm_apply_settings(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool pcm_is_playing(void)
|
||||
{
|
||||
return pcm_playing;
|
||||
}
|
||||
|
||||
bool pcm_is_paused(void)
|
||||
{
|
||||
return pcm_paused;
|
||||
}
|
||||
|
||||
#ifdef HAVE_RECORDING
|
||||
/** Low level pcm recording apis **/
|
||||
|
||||
/* Next start for recording peaks */
|
||||
static const void * volatile pcm_rec_peak_addr SHAREDBSS_ATTR = NULL;
|
||||
/* the registered callback function for when more data is available */
|
||||
volatile pcm_more_callback_type2
|
||||
static volatile pcm_rec_callback_type
|
||||
pcm_callback_more_ready SHAREDBSS_ATTR = NULL;
|
||||
/* DMA transfer in is currently active */
|
||||
volatile bool pcm_recording SHAREDBSS_ATTR = false;
|
||||
|
||||
/* Called internally by functions to reset the state */
|
||||
static void pcm_recording_stopped(void)
|
||||
{
|
||||
pcm_recording = false;
|
||||
pcm_callback_more_ready = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return recording peaks - From the end of the last peak up to
|
||||
* current write position.
|
||||
|
@ -410,10 +441,16 @@ void pcm_calculate_rec_peaks(int *left, int *right)
|
|||
*right = peaks[1];
|
||||
} /* pcm_calculate_rec_peaks */
|
||||
|
||||
bool pcm_is_recording(void)
|
||||
{
|
||||
return pcm_recording;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Functions that do not require targeted implementation but only a targeted
|
||||
* interface
|
||||
*/
|
||||
|
||||
void pcm_init_recording(void)
|
||||
{
|
||||
logf("pcm_init_recording");
|
||||
|
@ -424,7 +461,7 @@ void pcm_init_recording(void)
|
|||
pcm_rec_lock();
|
||||
|
||||
logf(" pcm_rec_dma_init");
|
||||
pcm_rec_dma_stopped_callback();
|
||||
pcm_recording_stopped();
|
||||
pcm_rec_dma_init();
|
||||
|
||||
pcm_rec_unlock();
|
||||
|
@ -440,7 +477,7 @@ void pcm_close_recording(void)
|
|||
{
|
||||
logf(" pcm_rec_dma_stop");
|
||||
pcm_rec_dma_stop();
|
||||
pcm_rec_dma_stopped_callback();
|
||||
pcm_recording_stopped();
|
||||
}
|
||||
|
||||
logf(" pcm_rec_dma_close");
|
||||
|
@ -449,7 +486,7 @@ void pcm_close_recording(void)
|
|||
pcm_rec_unlock();
|
||||
}
|
||||
|
||||
void pcm_record_data(pcm_more_callback_type2 more_ready,
|
||||
void pcm_record_data(pcm_rec_callback_type more_ready,
|
||||
void *start, size_t size)
|
||||
{
|
||||
logf("pcm_record_data");
|
||||
|
@ -493,43 +530,40 @@ void pcm_stop_recording(void)
|
|||
{
|
||||
logf(" pcm_rec_dma_stop");
|
||||
pcm_rec_dma_stop();
|
||||
pcm_rec_dma_stopped_callback();
|
||||
pcm_recording_stopped();
|
||||
}
|
||||
|
||||
pcm_rec_unlock();
|
||||
} /* pcm_stop_recording */
|
||||
|
||||
void pcm_record_more(void *start, size_t size)
|
||||
void pcm_rec_more_ready_callback(int status, void **start, size_t *size)
|
||||
{
|
||||
start = (void *)(((uintptr_t)start + 3) & ~3);
|
||||
size = size & ~3;
|
||||
pcm_rec_callback_type have_more = pcm_callback_more_ready;
|
||||
|
||||
if (!size)
|
||||
*size = 0;
|
||||
|
||||
if (have_more && start)
|
||||
{
|
||||
pcm_rec_dma_stop();
|
||||
pcm_rec_dma_stopped_callback();
|
||||
return;
|
||||
have_more(status, start, size);
|
||||
*start = (void *)(((uintptr_t)*start + 3) & ~3);
|
||||
*size &= ~3;
|
||||
|
||||
if (*start && *size)
|
||||
{
|
||||
#ifdef HAVE_PCM_REC_DMA_ADDRESS
|
||||
/* Need a physical DMA address translation, if not already
|
||||
* physical. */
|
||||
pcm_rec_peak_addr = pcm_dma_addr(*start);
|
||||
#else
|
||||
pcm_rec_peak_addr = *start;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_PCM_REC_DMA_ADDRESS
|
||||
/* Need a physical DMA address translation, if not already physical. */
|
||||
pcm_rec_peak_addr = pcm_dma_addr(start);
|
||||
#else
|
||||
pcm_rec_peak_addr = start;
|
||||
#endif
|
||||
|
||||
pcm_rec_dma_record_more(start, size);
|
||||
}
|
||||
|
||||
bool pcm_is_recording(void)
|
||||
{
|
||||
return pcm_recording;
|
||||
}
|
||||
|
||||
void pcm_rec_dma_stopped_callback(void)
|
||||
{
|
||||
pcm_recording = false;
|
||||
pcm_callback_more_ready = NULL;
|
||||
/* Error, callback missing or no more DMA to do */
|
||||
pcm_rec_dma_stop();
|
||||
pcm_recording_stopped();
|
||||
}
|
||||
|
||||
#endif /* HAVE_RECORDING */
|
||||
|
|
|
@ -74,18 +74,13 @@ static void dma_callback(void)
|
|||
{
|
||||
if(!dma_size)
|
||||
{
|
||||
register pcm_more_callback_type get_more = pcm_callback_for_more;
|
||||
if(get_more)
|
||||
get_more(&dma_start_addr, &dma_size);
|
||||
pcm_play_get_more_callback(&dma_start_addr, &dma_size);
|
||||
|
||||
if (!dma_size)
|
||||
return;
|
||||
}
|
||||
|
||||
if(!dma_size)
|
||||
{
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
}
|
||||
else
|
||||
play_start_pcm();
|
||||
play_start_pcm();
|
||||
}
|
||||
|
||||
void pcm_play_dma_start(const void *addr, size_t size)
|
||||
|
@ -275,31 +270,19 @@ static void rec_dma_callback(void)
|
|||
|
||||
if(!rec_dma_size)
|
||||
{
|
||||
register pcm_more_callback_type2 more_ready = pcm_callback_more_ready;
|
||||
if (!more_ready || more_ready(0) < 0)
|
||||
pcm_rec_more_ready_callback(0, &rec_dma_start_addr, &rec_dma_size);
|
||||
|
||||
if(rec_dma_size != 0)
|
||||
{
|
||||
/* Finished recording */
|
||||
pcm_rec_dma_stop();
|
||||
pcm_rec_dma_stopped_callback();
|
||||
return;
|
||||
dump_dcache_range(rec_dma_start_addr, rec_dma_size);
|
||||
#if CONFIG_CPU == AS3525
|
||||
mono_samples = AS3525_UNCACHED_ADDR(rec_dma_start_addr);
|
||||
#endif
|
||||
rec_dma_start();
|
||||
}
|
||||
}
|
||||
|
||||
rec_dma_start();
|
||||
}
|
||||
|
||||
|
||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
||||
{
|
||||
dump_dcache_range(start, size);
|
||||
rec_dma_start_addr = start;
|
||||
#if CONFIG_CPU == AS3525
|
||||
mono_samples = AS3525_UNCACHED_ADDR(start);
|
||||
#endif
|
||||
rec_dma_size = size;
|
||||
}
|
||||
|
||||
|
||||
void pcm_rec_dma_stop(void)
|
||||
{
|
||||
dma_disable_channel(1);
|
||||
|
|
|
@ -52,9 +52,9 @@ static struct dma_data dma_play_data =
|
|||
|
||||
static void play_dma_callback(void)
|
||||
{
|
||||
unsigned char *start;
|
||||
size_t size = 0;
|
||||
pcm_more_callback_type get_more = pcm_callback_for_more;
|
||||
void *start;
|
||||
size_t size;
|
||||
bool rror;
|
||||
|
||||
if (dma_play_data.locked != 0)
|
||||
{
|
||||
|
@ -63,28 +63,20 @@ static void play_dma_callback(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (dma_play_bd.mode.status & BD_RROR)
|
||||
{
|
||||
/* Stop on error */
|
||||
}
|
||||
else if (get_more != NULL && (get_more(&start, &size), size != 0))
|
||||
{
|
||||
start = (void*)(((unsigned long)start + 3) & ~3);
|
||||
size &= ~3;
|
||||
rror = dma_play_bd.mode.status & BD_RROR;
|
||||
|
||||
/* Flush any pending cache writes */
|
||||
clean_dcache_range(start, size);
|
||||
dma_play_bd.buf_addr = (void *)addr_virt_to_phys((unsigned long)start);
|
||||
dma_play_bd.mode.count = size;
|
||||
dma_play_bd.mode.command = TRANSFER_16BIT;
|
||||
dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
|
||||
sdma_channel_run(DMA_PLAY_CH_NUM);
|
||||
pcm_play_get_more_callback(rror ? NULL : &start, &size);
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Error, callback missing or no more DMA to do */
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
/* Flush any pending cache writes */
|
||||
clean_dcache_range(start, size);
|
||||
dma_play_bd.buf_addr = (void *)addr_virt_to_phys((unsigned long)start);
|
||||
dma_play_bd.mode.count = size;
|
||||
dma_play_bd.mode.command = TRANSFER_16BIT;
|
||||
dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
|
||||
sdma_channel_run(DMA_PLAY_CH_NUM);
|
||||
}
|
||||
|
||||
void pcm_play_lock(void)
|
||||
|
@ -272,12 +264,6 @@ void pcm_play_dma_start(const void *addr, size_t size)
|
|||
SSI_STCR2 &= ~SSI_STCR_TFEN0;
|
||||
SSI_SCR2 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN);
|
||||
|
||||
addr = (void *)(((unsigned long)addr + 3) & ~3);
|
||||
size &= ~3;
|
||||
|
||||
if (size <= 0)
|
||||
return;
|
||||
|
||||
if (!sdma_channel_reset(DMA_PLAY_CH_NUM))
|
||||
return;
|
||||
|
||||
|
@ -383,8 +369,9 @@ static struct dma_data dma_rec_data =
|
|||
|
||||
static void rec_dma_callback(void)
|
||||
{
|
||||
pcm_more_callback_type2 more_ready;
|
||||
int status = 0;
|
||||
void *start;
|
||||
size_t size;
|
||||
|
||||
if (dma_rec_data.locked != 0)
|
||||
{
|
||||
|
@ -395,17 +382,22 @@ static void rec_dma_callback(void)
|
|||
if (dma_rec_bd.mode.status & BD_RROR)
|
||||
status = DMA_REC_ERROR_DMA;
|
||||
|
||||
more_ready = pcm_callback_more_ready;
|
||||
pcm_rec_more_ready_callback(status, &start, &size);
|
||||
|
||||
if (more_ready != NULL && more_ready(status) >= 0)
|
||||
{
|
||||
sdma_channel_run(DMA_REC_CH_NUM);
|
||||
if (size == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Finished recording */
|
||||
pcm_rec_dma_stop();
|
||||
pcm_rec_dma_stopped_callback();
|
||||
/* Invalidate - buffer must be coherent */
|
||||
dump_dcache_range(start, size);
|
||||
|
||||
start = (void *)addr_virt_to_phys((unsigned long)start);
|
||||
|
||||
dma_rec_bd.buf_addr = start;
|
||||
dma_rec_bd.mode.count = size;
|
||||
dma_rec_bd.mode.command = TRANSFER_16BIT;
|
||||
dma_rec_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
|
||||
|
||||
sdma_channel_run(DMA_REC_CH_NUM);
|
||||
}
|
||||
|
||||
void pcm_rec_lock(void)
|
||||
|
@ -432,19 +424,6 @@ void pcm_rec_unlock(void)
|
|||
}
|
||||
}
|
||||
|
||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
||||
{
|
||||
/* Invalidate - buffer must be coherent */
|
||||
dump_dcache_range(start, size);
|
||||
|
||||
start = (void *)addr_virt_to_phys((unsigned long)start);
|
||||
|
||||
dma_rec_bd.buf_addr = start;
|
||||
dma_rec_bd.mode.count = size;
|
||||
dma_rec_bd.mode.command = TRANSFER_16BIT;
|
||||
dma_rec_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
|
||||
}
|
||||
|
||||
void pcm_rec_dma_stop(void)
|
||||
{
|
||||
/* Stop receiving data */
|
||||
|
|
|
@ -115,7 +115,6 @@ void pcm_dma_apply_settings(void)
|
|||
/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */
|
||||
void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void)
|
||||
{
|
||||
register pcm_more_callback_type get_more;
|
||||
register size_t size;
|
||||
|
||||
DMA0_STATUS; /* Clear any pending interrupt */
|
||||
|
@ -141,15 +140,12 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void)
|
|||
}
|
||||
|
||||
/* Buffer empty. Try to get more. */
|
||||
get_more = pcm_callback_for_more;
|
||||
if (get_more) {
|
||||
get_more((unsigned char **)&dma_play_data.addr, &dma_play_data.size);
|
||||
dma_play_data.addr = (dma_play_data.addr + 2) & ~3;
|
||||
dma_play_data.size &= ~3;
|
||||
}
|
||||
pcm_play_get_more_callback((void **)&dma_play_data.addr,
|
||||
&dma_play_data.size);
|
||||
|
||||
if (dma_play_data.size == 0) {
|
||||
break;
|
||||
/* No more data */
|
||||
return;
|
||||
}
|
||||
|
||||
if (dma_play_data.addr < UNCACHED_BASE_ADDR) {
|
||||
|
@ -158,10 +154,6 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void)
|
|||
cpucache_flush();
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback missing or no more DMA to do */
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
}
|
||||
#else
|
||||
/* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by
|
||||
|
@ -247,28 +239,16 @@ void fiq_playback(void)
|
|||
#endif
|
||||
|
||||
".more_data: \n"
|
||||
"ldr r2, =pcm_callback_for_more \n"
|
||||
"ldr r2, [r2] \n" /* get callback address */
|
||||
"cmp r2, #0 \n" /* check for null pointer */
|
||||
"beq .stop \n" /* callback removed, stop */
|
||||
"stmia r11, { r8-r9 } \n" /* save internal copies of variables back */
|
||||
"ldr r2, =pcm_play_get_more_callback \n"
|
||||
"mov r0, r11 \n" /* r0 = &p */
|
||||
"add r1, r11, #4 \n" /* r1 = &size */
|
||||
"mov lr, pc \n" /* call pcm_callback_for_more */
|
||||
"mov lr, pc \n" /* call pcm_play_get_more_callback */
|
||||
"bx r2 \n"
|
||||
"ldmia r11, { r8-r9 } \n" /* reload p and size */
|
||||
"cmp r9, #0 \n" /* did we actually get more data? */
|
||||
"bne .check_fifo \n"
|
||||
"ldmia r11, { r8-r9 } \n" /* load new p and size */
|
||||
"cmp r9, #0 \n"
|
||||
"bne .check_fifo \n" /* size != 0? refill */
|
||||
|
||||
".stop: \n" /* call termination routines */
|
||||
"ldr r12, =pcm_play_dma_stop \n"
|
||||
"mov lr, pc \n"
|
||||
"bx r12 \n"
|
||||
"ldr r12, =pcm_play_dma_stopped_callback \n"
|
||||
"mov lr, pc \n"
|
||||
"bx r12 \n"
|
||||
|
||||
".exit: \n" /* (r8=0 if stopping, look above) */
|
||||
".exit: \n" /* (r9=0 if stopping, look above) */
|
||||
"stmia r11, { r8-r9 } \n" /* save p and size */
|
||||
"ldmfd sp!, { r0-r3, lr } \n"
|
||||
"subs pc, lr, #4 \n" /* FIQ specific return sequence */
|
||||
|
@ -284,8 +264,6 @@ void fiq_playback(void) __attribute__((interrupt ("FIQ"))) ICODE_ATTR;
|
|||
/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */
|
||||
void fiq_playback(void)
|
||||
{
|
||||
register pcm_more_callback_type get_more;
|
||||
|
||||
#if CONFIG_CPU == PP5002
|
||||
inl(0xcf001040);
|
||||
#endif
|
||||
|
@ -305,16 +283,11 @@ void fiq_playback(void)
|
|||
}
|
||||
|
||||
/* p is empty, get some more data */
|
||||
get_more = pcm_callback_for_more;
|
||||
if (get_more) {
|
||||
get_more((unsigned char**)&dma_play_data.addr,
|
||||
&dma_play_data.size);
|
||||
}
|
||||
pcm_play_get_more_callback((void **)&dma_play_data.addr,
|
||||
&dma_play_data.size);
|
||||
} while (dma_play_data.size);
|
||||
|
||||
/* No more data, so disable the FIFO/interrupt */
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
/* No more data */
|
||||
}
|
||||
#endif /* ASM / C selection */
|
||||
#endif /* CPU_PP502x */
|
||||
|
@ -589,7 +562,6 @@ void fiq_record(void) ICODE_ATTR __attribute__((interrupt ("FIQ")));
|
|||
#if defined(SANSA_C200) || defined(SANSA_E200)
|
||||
void fiq_record(void)
|
||||
{
|
||||
register pcm_more_callback_type2 more_ready;
|
||||
register int32_t value;
|
||||
|
||||
if (audio_channels == 2) {
|
||||
|
@ -648,20 +620,13 @@ void fiq_record(void)
|
|||
}
|
||||
}
|
||||
|
||||
more_ready = pcm_callback_more_ready;
|
||||
|
||||
if (more_ready == NULL || more_ready(0) < 0) {
|
||||
/* Finished recording */
|
||||
pcm_rec_dma_stop();
|
||||
pcm_rec_dma_stopped_callback();
|
||||
}
|
||||
pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr,
|
||||
&dma_rec_data.size);
|
||||
}
|
||||
|
||||
#else
|
||||
void fiq_record(void)
|
||||
{
|
||||
register pcm_more_callback_type2 more_ready;
|
||||
|
||||
while (dma_rec_data.size > 0) {
|
||||
if (IIS_RX_FULL_COUNT < 2) {
|
||||
return;
|
||||
|
@ -676,24 +641,12 @@ void fiq_record(void)
|
|||
dma_rec_data.size -= 4;
|
||||
}
|
||||
|
||||
more_ready = pcm_callback_more_ready;
|
||||
|
||||
if (more_ready == NULL || more_ready(0) < 0) {
|
||||
/* Finished recording */
|
||||
pcm_rec_dma_stop();
|
||||
pcm_rec_dma_stopped_callback();
|
||||
}
|
||||
pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr,
|
||||
&dma_rec_data.size);
|
||||
}
|
||||
|
||||
#endif /* SANSA_E200 */
|
||||
|
||||
/* Continue transferring data in */
|
||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
||||
{
|
||||
dma_rec_data.addr = (unsigned long)start; /* Start of RX buffer */
|
||||
dma_rec_data.size = size; /* Bytes to transfer */
|
||||
}
|
||||
|
||||
void pcm_rec_dma_stop(void)
|
||||
{
|
||||
/* disable interrupt */
|
||||
|
|
|
@ -233,12 +233,6 @@ const void * pcm_rec_dma_get_peak_buffer(void)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pcm_record_more(void *start, size_t size)
|
||||
{
|
||||
(void) start;
|
||||
(void) size;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CPU_TCC77X) || defined(CPU_TCC780X)
|
||||
|
@ -289,21 +283,14 @@ void fiq_handler(void)
|
|||
|
||||
".more_data: \n"
|
||||
"stmfd sp!, { r0-r3, lr } \n" /* stack scratch regs and lr */
|
||||
"ldr r2, =pcm_callback_for_more \n"
|
||||
"ldr r2, [r2] \n" /* get callback address */
|
||||
"cmp r2, #0 \n" /* check for null pointer */
|
||||
"movne r0, r11 \n" /* r0 = &p */
|
||||
"addne r1, r11, #4 \n" /* r1 = &size */
|
||||
"blxne r2 \n" /* call pcm_callback_for_more */
|
||||
"ldmia r11, { r8-r9 } \n" /* reload p and size */
|
||||
"cmp r9, #0x10 \n" /* did we actually get more data? */
|
||||
"ldmgefd sp!, { r0-r3, lr } \n"
|
||||
"bge .fill_fifo \n" /* yes: fill the fifo */
|
||||
"ldr r12, =pcm_play_dma_stop \n"
|
||||
"blx r12 \n" /* no: stop playback */
|
||||
"ldr r12, =pcm_play_dma_stopped_callback \n"
|
||||
"blx r12 \n"
|
||||
"ldr r2, =pcm_play_get_more_callback \n"
|
||||
"mov r0, r11 \n" /* r0 = &p */
|
||||
"add r1, r11, #4 \n" /* r1 = &size */
|
||||
"blx r2 \n" /* call pcm_play_get_more_callback */
|
||||
"ldmia r11, { r8-r9 } \n" /* load new p and size */
|
||||
"cmp r9, #0x10 \n" /* did we actually get enough data? */
|
||||
"ldmfd sp!, { r0-r3, lr } \n"
|
||||
"bpl .fill_fifo \n" /* not stop and enough? refill */
|
||||
"b .exit \n"
|
||||
".ltorg \n"
|
||||
);
|
||||
|
@ -315,17 +302,11 @@ void fiq_handler(void)
|
|||
asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */
|
||||
"sub sp, sp, #8 \n"); /* Reserve stack */
|
||||
|
||||
register pcm_more_callback_type get_more;
|
||||
|
||||
if (dma_play_data.size < 16)
|
||||
{
|
||||
/* p is empty, get some more data */
|
||||
get_more = pcm_callback_for_more;
|
||||
if (get_more)
|
||||
{
|
||||
get_more((unsigned char**)&dma_play_data.p,
|
||||
&dma_play_data.size);
|
||||
}
|
||||
pcm_play_get_more_callback((void**)&dma_play_data.p,
|
||||
&dma_play_data.size);
|
||||
}
|
||||
|
||||
if (dma_play_data.size >= 16)
|
||||
|
@ -341,12 +322,6 @@ void fiq_handler(void)
|
|||
|
||||
dma_play_data.size -= 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No more data, so disable the FIFO/interrupt */
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
}
|
||||
|
||||
/* Clear FIQ status */
|
||||
CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK;
|
||||
|
|
|
@ -104,13 +104,10 @@ static inline void fill_dma_buf(int offset)
|
|||
p = tmp_p;
|
||||
if (l >= lend)
|
||||
return;
|
||||
else if (pcm_callback_for_more)
|
||||
pcm_callback_for_more((unsigned char**)&p,
|
||||
&p_size);
|
||||
|
||||
pcm_play_get_more_callback((void**)&p, &p_size);
|
||||
}
|
||||
while (p_size);
|
||||
|
||||
pcm_play_dma_stopped_callback();
|
||||
}
|
||||
|
||||
if (l < lend)
|
||||
|
|
|
@ -214,35 +214,27 @@ void pcm_play_dma_pause(bool pause)
|
|||
|
||||
void fiq_handler(void)
|
||||
{
|
||||
static unsigned char *start;
|
||||
static size_t size;
|
||||
register pcm_more_callback_type get_more; /* No stack for this */
|
||||
static void *start;
|
||||
static size_t size;
|
||||
|
||||
/* clear any pending interrupt */
|
||||
SRCPND = DMA2_MASK;
|
||||
|
||||
/* Buffer empty. Try to get more. */
|
||||
get_more = pcm_callback_for_more;
|
||||
size = 0;
|
||||
pcm_play_get_more_callback(&start, &size);
|
||||
|
||||
if (get_more == NULL || (get_more(&start, &size), size == 0))
|
||||
{
|
||||
/* Callback missing or no more DMA to do */
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Flush any pending cache writes */
|
||||
clean_dcache_range(start, size);
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
/* set the new DMA values */
|
||||
DCON2 = DMA_CONTROL_SETUP | (size >> 1);
|
||||
DISRC2 = (unsigned int)start + 0x30000000;
|
||||
/* Flush any pending cache writes */
|
||||
clean_dcache_range(start, size);
|
||||
|
||||
/* Re-Activate the channel */
|
||||
DMASKTRIG2 = 0x2;
|
||||
}
|
||||
/* set the new DMA values */
|
||||
DCON2 = DMA_CONTROL_SETUP | (size >> 1);
|
||||
DISRC2 = (unsigned int)start + 0x30000000;
|
||||
|
||||
/* Re-Activate the channel */
|
||||
DMASKTRIG2 = 0x2;
|
||||
}
|
||||
|
||||
size_t pcm_get_bytes_waiting(void)
|
||||
|
|
|
@ -254,35 +254,27 @@ void pcm_play_dma_pause(bool pause)
|
|||
|
||||
void fiq_handler(void)
|
||||
{
|
||||
static unsigned char *start;
|
||||
static size_t size;
|
||||
register pcm_more_callback_type get_more; /* No stack for this */
|
||||
static void *start;
|
||||
static size_t size;
|
||||
|
||||
/* clear any pending interrupt */
|
||||
SRCPND = DMA2_MASK;
|
||||
|
||||
/* Buffer empty. Try to get more. */
|
||||
get_more = pcm_callback_for_more;
|
||||
size = 0;
|
||||
pcm_play_get_more_callback(&start, &size);
|
||||
|
||||
if (get_more == NULL || (get_more(&start, &size), size == 0))
|
||||
{
|
||||
/* Callback missing or no more DMA to do */
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Flush any pending cache writes */
|
||||
clean_dcache_range(start, size);
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
/* set the new DMA values */
|
||||
DCON2 = DMA_CONTROL_SETUP | (size >> 1);
|
||||
DISRC2 = (unsigned int)start + 0x30000000;
|
||||
/* Flush any pending cache writes */
|
||||
clean_dcache_range(start, size);
|
||||
|
||||
/* Re-Activate the channel */
|
||||
DMASKTRIG2 = 0x2;
|
||||
}
|
||||
/* set the new DMA values */
|
||||
DCON2 = DMA_CONTROL_SETUP | (size >> 1);
|
||||
DISRC2 = (unsigned int)start + 0x30000000;
|
||||
|
||||
/* Re-Activate the channel */
|
||||
DMASKTRIG2 = 0x2;
|
||||
}
|
||||
|
||||
size_t pcm_get_bytes_waiting(void)
|
||||
|
|
|
@ -102,11 +102,11 @@ static const void* dma_callback(void)
|
|||
{
|
||||
if (dmamode)
|
||||
{
|
||||
unsigned char *dma_start_addr;
|
||||
register pcm_more_callback_type get_more = pcm_callback_for_more;
|
||||
if (get_more)
|
||||
void *dma_start_addr;
|
||||
pcm_play_get_more_callback(&dma_start_addr, &nextsize);
|
||||
|
||||
if (nextsize != 0)
|
||||
{
|
||||
get_more(&dma_start_addr, &nextsize);
|
||||
if (nextsize >= 4096)
|
||||
{
|
||||
dblbufsize = (nextsize >> 4) & ~3;
|
||||
|
@ -148,7 +148,6 @@ void fiq_handler(void)
|
|||
"mov r10, #0x00000400 \n" /* INT_DMA */
|
||||
"str r10, [r11] \n" /* ACK FIQ */
|
||||
"stmfd sp!, {r0-r3,lr} \n"
|
||||
"ldreq r0, =pcm_play_dma_stopped_callback \n"
|
||||
"ldrne r0, =dma_callback \n"
|
||||
"mov lr, pc \n"
|
||||
"bx r0 \n"
|
||||
|
@ -225,13 +224,6 @@ void pcm_play_dma_start(const void *addr_in, size_t size)
|
|||
#endif
|
||||
|
||||
/* S3: DMA channel 0 on */
|
||||
if (!size)
|
||||
{
|
||||
register pcm_more_callback_type get_more = pcm_callback_for_more;
|
||||
if (get_more) get_more(&addr, &size);
|
||||
else return; /* Nothing to play!? */
|
||||
}
|
||||
if (!size) return; /* Nothing to play!? */
|
||||
clean_dcache();
|
||||
if (size >= 4096)
|
||||
{
|
||||
|
@ -367,12 +359,6 @@ void pcm_rec_unlock(void)
|
|||
{
|
||||
}
|
||||
|
||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
||||
{
|
||||
(void)start;
|
||||
(void)size;
|
||||
}
|
||||
|
||||
void pcm_rec_dma_stop(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -132,8 +132,6 @@ char buffer[80];
|
|||
void DSPHINT(void) __attribute__ ((section(".icode")));
|
||||
void DSPHINT(void)
|
||||
{
|
||||
register pcm_more_callback_type get_more; /* No stack for this */
|
||||
|
||||
unsigned int i;
|
||||
|
||||
IO_INTC_FIQ0 = 1 << 11;
|
||||
|
@ -152,16 +150,9 @@ void DSPHINT(void)
|
|||
|
||||
case MSG_REFILL:
|
||||
/* Buffer empty. Try to get more. */
|
||||
get_more = pcm_callback_for_more;
|
||||
size = 0;
|
||||
|
||||
if (get_more == NULL || (get_more(&start, &size), size == 0))
|
||||
{
|
||||
/* Callback missing or no more DMA to do */
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
}
|
||||
|
||||
pcm_play_get_more_callback(&start, &size);
|
||||
|
||||
if (size != 0)
|
||||
{
|
||||
unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START;
|
||||
/* Flush any pending cache writes */
|
||||
|
|
|
@ -288,13 +288,14 @@ void DMA0(void) __attribute__ ((interrupt_handler, section(".icode")));
|
|||
void DMA0(void)
|
||||
{
|
||||
unsigned long res = DSR0;
|
||||
void *start;
|
||||
size_t size;
|
||||
|
||||
and_l(~(DMA_EEXT | DMA_INT), &DCR0); /* per request and int OFF */
|
||||
DSR0 = 1; /* Clear interrupt and errors */
|
||||
|
||||
if (res & 0x70)
|
||||
{
|
||||
/* Stop on error */
|
||||
logf("DMA0 err: %02x", res);
|
||||
#if 0
|
||||
logf(" SAR0: %08x", SAR0);
|
||||
|
@ -303,32 +304,17 @@ void DMA0(void)
|
|||
logf(" DCR0: %08x", DCR0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
||||
/* Force stop on error */
|
||||
pcm_play_get_more_callback((res & 0x70) ? NULL : &start, &size);
|
||||
|
||||
if (size != 0)
|
||||
{
|
||||
pcm_more_callback_type get_more = pcm_callback_for_more;
|
||||
unsigned char *start;
|
||||
size_t size = 0;
|
||||
|
||||
if (get_more)
|
||||
get_more(&start, &size);
|
||||
|
||||
start = (unsigned char *)(((long)start + 3) & ~3);
|
||||
size &= ~3;
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
SAR0 = (unsigned long)start; /* Source address */
|
||||
BCR0 = size; /* Bytes to transfer */
|
||||
or_l(DMA_EEXT | DMA_INT, &DCR0); /* per request and int ON */
|
||||
return;
|
||||
}
|
||||
/* Finished playing */
|
||||
SAR0 = (unsigned long)start; /* Source address */
|
||||
BCR0 = size; /* Bytes to transfer */
|
||||
or_l(DMA_EEXT | DMA_INT, &DCR0); /* per request and int ON */
|
||||
}
|
||||
|
||||
/* Stop interrupt and futher transfers */
|
||||
pcm_play_dma_stop();
|
||||
/* Inform PCM that we're done */
|
||||
pcm_play_dma_stopped_callback();
|
||||
/* else inished playing */
|
||||
} /* DMA0 */
|
||||
|
||||
const void * pcm_play_dma_get_peak_buffer(int *count)
|
||||
|
@ -436,7 +422,8 @@ void DMA1(void)
|
|||
{
|
||||
unsigned long res = DSR1;
|
||||
int status = 0;
|
||||
pcm_more_callback_type2 more_ready;
|
||||
void *start;
|
||||
size_t size;
|
||||
|
||||
and_l(~(DMA_EEXT | DMA_INT), &DCR1); /* per request and int OFF */
|
||||
DSR1 = 1; /* Clear interrupt and errors */
|
||||
|
@ -465,25 +452,17 @@ void DMA1(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
more_ready = pcm_callback_more_ready;
|
||||
/* Inform PCM we have more data (or error) */
|
||||
pcm_rec_more_ready_callback(status, &start, &size);
|
||||
|
||||
if (more_ready != NULL && more_ready(status) >= 0)
|
||||
return;
|
||||
|
||||
/* Finished recording */
|
||||
pcm_rec_dma_stop();
|
||||
/* Inform PCM that we're done */
|
||||
pcm_rec_dma_stopped_callback();
|
||||
if (size != 0)
|
||||
{
|
||||
DAR1 = (unsigned long)start; /* Destination address */
|
||||
BCR1 = (unsigned long)size; /* Bytes to transfer */
|
||||
or_l(DMA_EEXT | DMA_INT, &DCR1); /* per request and int ON */
|
||||
}
|
||||
} /* DMA1 */
|
||||
|
||||
/* Continue transferring data in - call from interrupt callback */
|
||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
||||
{
|
||||
DAR1 = (unsigned long)start; /* Destination address */
|
||||
BCR1 = (unsigned long)size; /* Bytes to transfer */
|
||||
or_l(DMA_EEXT | DMA_INT, &DCR1); /* per request and int ON */
|
||||
} /* pcm_record_more */
|
||||
|
||||
const void * pcm_rec_dma_get_peak_buffer(void)
|
||||
{
|
||||
return (void *)(DAR1 & ~3);
|
||||
|
|
|
@ -228,15 +228,9 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
|
|||
|
||||
/* Audio card wants more? Get some more then. */
|
||||
while (len > 0) {
|
||||
if ((ssize_t)pcm_data_size <= 0) {
|
||||
pcm_data_size = 0;
|
||||
|
||||
if (pcm_callback_for_more)
|
||||
pcm_callback_for_more(&pcm_data, &pcm_data_size);
|
||||
}
|
||||
|
||||
if (pcm_data_size > 0) {
|
||||
pcm_play_get_more_callback(&pcm_data, &pcm_data_size);
|
||||
start:
|
||||
if (pcm_data_size != 0) {
|
||||
udata->num_in = pcm_data_size / pcm_sample_bytes;
|
||||
udata->num_out = len / pcm_sample_bytes;
|
||||
|
||||
|
@ -251,8 +245,6 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
|
|||
len -= udata->num_out;
|
||||
} else {
|
||||
DEBUGF("sdl_audio_callback: No Data.\n");
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -292,12 +284,6 @@ void pcm_rec_dma_stop(void)
|
|||
{
|
||||
}
|
||||
|
||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
||||
{
|
||||
(void)start;
|
||||
(void)size;
|
||||
}
|
||||
|
||||
unsigned long pcm_rec_status(void)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -100,23 +100,16 @@ static inline void set_dma(const void *addr, size_t size)
|
|||
|
||||
static inline void play_dma_callback(void)
|
||||
{
|
||||
unsigned char *start = NULL;
|
||||
size_t size = 0;
|
||||
unsigned char *start;
|
||||
size_t size;
|
||||
|
||||
if(pcm_callback_for_more)
|
||||
pcm_callback_for_more(&start, &size);
|
||||
pcm_play_get_more_callback(&start, &size);
|
||||
|
||||
if(LIKELY(size > 0 && start))
|
||||
if (size != 0)
|
||||
{
|
||||
set_dma(start, size);
|
||||
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error, callback missing or no more DMA to do */
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
}
|
||||
}
|
||||
|
||||
void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void) __attribute__ ((section(".icode")));
|
||||
|
@ -292,10 +285,4 @@ const void * pcm_rec_dma_get_peak_buffer(void)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
||||
{
|
||||
(void) start;
|
||||
(void) size;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue