summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugin.c1
-rw-r--r--apps/plugin.h5
-rw-r--r--firmware/export/pcm_playback.h1
-rw-r--r--firmware/export/pcm_record.h17
-rw-r--r--firmware/pcm_record.c42
-rw-r--r--firmware/target/coldfire/pcm-coldfire.c68
6 files changed, 61 insertions, 73 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 268fee5..b129493 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -482,6 +482,7 @@ static const struct plugin_api rockbox_api = {
#if CONFIG_CODEC == SWCODEC && defined(HAVE_RECORDING) && !defined(SIMULATOR)
sound_default,
+ pcm_record_more,
#endif
};
diff --git a/apps/plugin.h b/apps/plugin.h
index 22f6b97..68841e8 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -580,8 +580,8 @@ struct plugin_api {
#ifndef SIMULATOR
void (*pcm_init_recording)(void);
void (*pcm_close_recording)(void);
- void (*pcm_record_data)(pcm_more_callback_type more_ready,
- unsigned char *start, size_t size);
+ void (*pcm_record_data)(pcm_more_callback_type2 more_ready,
+ 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);
@@ -598,6 +598,7 @@ struct plugin_api {
#if CONFIG_CODEC == SWCODEC && defined(HAVE_RECORDING) && !defined(SIMULATOR)
int (*sound_default)(int setting);
+ void (*pcm_record_more)(void *start, size_t size);
#endif
};
diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h
index e7c00ed..80a1f55 100644
--- a/firmware/export/pcm_playback.h
+++ b/firmware/export/pcm_playback.h
@@ -24,6 +24,7 @@
/* Typedef for registered callback (play and record) */
typedef void (*pcm_more_callback_type)(unsigned char **start,
size_t *size);
+typedef int (*pcm_more_callback_type2)(int status);
void pcm_init(void);
diff --git a/firmware/export/pcm_record.h b/firmware/export/pcm_record.h
index 30d2dc7..f6dddb3 100644
--- a/firmware/export/pcm_record.h
+++ b/firmware/export/pcm_record.h
@@ -20,9 +20,9 @@
#ifndef PCM_RECORD_H
#define PCM_RECORD_H
-#define DMA_REC_ERROR_DMA ((size_t)-1)
+#define DMA_REC_ERROR_DMA (-1)
#ifdef HAVE_SPDIF_IN
-#define DMA_REC_ERROR_SPDIF ((size_t)-2)
+#define DMA_REC_ERROR_SPDIF (-2)
#endif
/**
@@ -36,12 +36,15 @@ void pcm_init_recording(void);
void pcm_close_recording(void);
/* Start recording "raw" PCM data */
-void pcm_record_data(pcm_more_callback_type more_ready,
- unsigned char *start, size_t size);
+void pcm_record_data(pcm_more_callback_type2 more_ready,
+ void *start, size_t size);
/* Stop tranferring data into supplied buffer */
void pcm_stop_recording(void);
+/* Continue transferring data in - call during interrupt handler */
+void pcm_record_more(void *start, size_t size);
+
void pcm_calculate_rec_peaks(int *left, int *right);
/** General functions for high level codec recording **/
@@ -64,12 +67,12 @@ int pcm_get_num_unprocessed(void);
/** The following are for internal use between pcm_record.c and target-
specific portion **/
/* the registered callback function for when more data is available */
-extern volatile pcm_more_callback_type pcm_callback_more_ready;
+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 */
-extern void pcm_rec_dma_start(const void *addr, size_t size);
+extern void pcm_rec_dma_start(void *addr, size_t size);
extern void pcm_rec_dma_stop(void);
#endif /* PCM_RECORD_H */
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c
index 379adc3..a72641b 100644
--- a/firmware/pcm_record.c
+++ b/firmware/pcm_record.c
@@ -55,13 +55,9 @@
be shared semi-privately **/
/* the registered callback function for when more data is available */
-volatile pcm_more_callback_type pcm_callback_more_ready = NULL;
+volatile pcm_more_callback_type2 pcm_callback_more_ready = NULL;
/* DMA transfer in is currently active */
-volatile bool pcm_recording = false;
-
-/* APIs implemented in the target-specific portion */
-void pcm_rec_dma_start(const void *addr, size_t size);
-void pcm_rec_dma_stop(void);
+volatile bool pcm_recording = false;
/** General recording state **/
static bool is_recording; /* We are recording */
@@ -225,16 +221,16 @@ static void pcm_thread_wait_for_stop(void)
/*******************************************************************/
/* Callback for when more data is ready */
-static void pcm_rec_have_more(unsigned char **data, size_t *size)
+static int pcm_rec_have_more(int status)
{
- if (*size != 0)
+ if (status < 0)
{
/* some error condition */
- if (*size == DMA_REC_ERROR_DMA)
+ if (status == DMA_REC_ERROR_DMA)
{
/* Flush recorded data to disk and stop recording */
queue_post(&pcmrec_queue, PCMREC_STOP, NULL);
- return;
+ return -1;
}
/* else try again next transmission */
}
@@ -243,9 +239,9 @@ static void pcm_rec_have_more(unsigned char **data, size_t *size)
/* advance write position */
dma_wr_pos = (dma_wr_pos + PCM_CHUNK_SIZE) & PCM_CHUNK_MASK;
}
-
- *data = (unsigned char *)GET_PCM_CHUNK(dma_wr_pos);
- *size = PCM_CHUNK_SIZE;
+
+ pcm_record_more(GET_PCM_CHUNK(dma_wr_pos), PCM_CHUNK_SIZE);
+ return 0;
} /* pcm_rec_have_more */
/** pcm_rec_* group **/
@@ -423,9 +419,9 @@ void audio_set_recording_options(struct audio_recording_options *options)
if (audio_load_encoder(enc_config.afmt))
{
/* start DMA transfer */
- pcm_record_data(pcm_rec_have_more, NULL, 0);
- /* do unlock after starting to prevent preincrement of dma_wr_pos */
dma_lock = pre_record_ticks == 0;
+ pcm_record_data(pcm_rec_have_more, GET_PCM_CHUNK(dma_wr_pos),
+ PCM_CHUNK_SIZE);
}
else
{
@@ -1621,20 +1617,14 @@ size_t enc_unget_pcm_data(size_t size)
* Functions that do not require targeted implementation but only a targeted
* interface
*/
-void pcm_record_data(pcm_more_callback_type more_ready,
- unsigned char *start, size_t size)
+void pcm_record_data(pcm_more_callback_type2 more_ready,
+ void *start, size_t size)
{
- pcm_callback_more_ready = more_ready;
-
if (!(start && size))
- {
- size = 0;
- if (more_ready)
- more_ready(&start, &size);
- }
+ return;
- if (start && size)
- pcm_rec_dma_start(start, size);
+ pcm_callback_more_ready = more_ready;
+ pcm_rec_dma_start(start, size);
} /* pcm_record_data */
void pcm_stop_recording(void)
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c
index 917800d..4e4e557 100644
--- a/firmware/target/coldfire/pcm-coldfire.c
+++ b/firmware/target/coldfire/pcm-coldfire.c
@@ -287,7 +287,7 @@ void DMA0(void)
/****************************************************************************
** Recording DMA transfer
**/
-void pcm_rec_dma_start(const void *addr, size_t size)
+void pcm_rec_dma_start(void *addr, size_t size)
{
logf("pcm_rec_dma_start");
@@ -296,12 +296,6 @@ void pcm_rec_dma_start(const void *addr, size_t size)
pcm_recording = true;
- DAR1 = (unsigned long)addr; /* Destination address */
- SAR1 = (unsigned long)&PDIR2; /* Source address */
- BCR1 = size; /* Bytes to transfer */
-
- rec_peak_addr = (unsigned long *)addr;
-
pcm_apply_settings(false);
/* Start the DMA transfer.. */
@@ -309,18 +303,22 @@ void pcm_rec_dma_start(const void *addr, size_t size)
INTERRUPTCLEAR = 0x03c00000;
#endif
- DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_DINC |
- DMA_DSIZE(3) | DMA_START;
+ SAR1 = (unsigned long)&PDIR2; /* Source address */
+ DCR1 = DMA_INT | DMA_CS | DMA_AA | DMA_DINC | DMA_DSIZE(3);
+
+ pcm_record_more(addr, size);
+
+ DCR1 |= DMA_START;
} /* pcm_dma_start */
void pcm_rec_dma_stop(void)
{
logf("pcm_rec_dma_stop");
- pcm_recording = false;
-
- DCR1 = 0;
DSR1 = 1; /* Clear interrupt */
+ DCR1 = 0;
+
+ pcm_recording = false;
} /* pcm_dma_stop */
void pcm_init_recording(void)
@@ -338,7 +336,7 @@ void pcm_init_recording(void)
pcm_rec_dma_stop();
- ICR7 = (7 << 2); /* Enable interrupt at level 7, priority 0 */
+ ICR7 = (6 << 2); /* Enable interrupt at level 6, priority 0 */
IMR &= ~(1 << 15); /* bit 15 is DMA1 */
} /* pcm_init_recording */
@@ -359,17 +357,15 @@ void DMA1(void) __attribute__ ((interrupt_handler, section(".icode")));
void DMA1(void)
{
int res = DSR1;
- pcm_more_callback_type more_ready;
- unsigned char *next_start;
- ssize_t next_size = 0; /* passing <> 0 is indicates
- an error condition */
+ int status = 0;
+ pcm_more_callback_type2 more_ready;
- DSR1 = 1; /* Clear interrupt */
- DCR1 &= ~DMA_EEXT;
+ DSR1 = 1; /* Clear interrupt */
+ DCR1 &= ~DMA_EEXT; /* Disable peripheral request */
if (res & 0x70)
{
- next_size = DMA_REC_ERROR_DMA;
+ status = DMA_REC_ERROR_DMA;
logf("DMA1 err: 0x%x", res);
}
#ifdef HAVE_SPDIF_IN
@@ -377,37 +373,33 @@ void DMA1(void)
(INTERRUPTSTAT & 0x01c00000)) /* valnogood, symbolerr, parityerr */
{
INTERRUPTCLEAR = 0x03c00000;
- next_size = DMA_REC_ERROR_SPDIF;
+ status = DMA_REC_ERROR_SPDIF;
logf("spdif err");
}
#endif
more_ready = pcm_callback_more_ready;
- if (more_ready)
- more_ready(&next_start, &next_size);
-
- if (next_size > 0)
- {
- /* Start peaking at dest */
- rec_peak_addr = (unsigned long *)next_start;
- DAR1 = (unsigned long)next_start; /* Destination address */
- BCR1 = (unsigned long)next_size; /* Bytes to transfer */
- DCR1 |= DMA_EEXT;
+ if (more_ready != NULL && more_ready(status) >= 0)
return;
- }
- else
- {
+
#if 0
- /* int. logfs can trash the display */
- logf("DMA1 No Data:0x%04x", res);
+ /* int. logfs can trash the display */
+ logf("DMA1 done:%04x %d", res, status);
#endif
- }
-
/* Finished recording */
pcm_rec_dma_stop();
} /* DMA1 */
+/* Continue transferring data in */
+void pcm_record_more(void *start, size_t size)
+{
+ rec_peak_addr = (unsigned long *)start; /* Start peaking at dest */
+ DAR1 = (unsigned long)start; /* Destination address */
+ BCR1 = (unsigned long)size; /* Bytes to transfer */
+ DCR1 |= DMA_EEXT;
+}
+
void pcm_mute(bool mute)
{
ac_mute(mute);