summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2012-02-23 08:14:46 -0500
committerMichael Sevakis <jethead71@rockbox.org>2012-03-03 07:23:38 +0100
commit286a4c5caa1945c8d1cb365a3d90fb09d5700cb2 (patch)
tree4835f46d16ec78d035ec9f49333079fe618384c1 /apps
parent3f82f3aca14eb954e55f761721ffdd2684f0e812 (diff)
downloadrockbox-286a4c5caa1945c8d1cb365a3d90fb09d5700cb2.tar.gz
rockbox-286a4c5caa1945c8d1cb365a3d90fb09d5700cb2.zip
Revise the PCM callback system after adding multichannel audio.
Additional status callback is added to pcm_play/rec_data instead of using a special function to set it. Status includes DMA error reporting to the status callback. Playback and recording callback become more alike except playback uses "const void **addr" (because the data should not be altered) and recording uses "void **addr". "const" is put in place throughout where appropriate. Most changes are fairly trivial. One that should be checked in particular because it isn't so much is telechips, if anyone cares to bother. PP5002 is not so trivial either but that tested as working. Change-Id: I4928d69b3b3be7fb93e259f81635232df9bd1df2 Reviewed-on: http://gerrit.rockbox.org/166 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
Diffstat (limited to 'apps')
-rw-r--r--apps/beep.c4
-rw-r--r--apps/pcmbuf.c2
-rw-r--r--apps/plugin.h13
-rw-r--r--apps/plugins/beatbox/beatbox.c8
-rw-r--r--apps/plugins/doom/i_sound.c6
-rw-r--r--apps/plugins/fft/fft.c4
-rw-r--r--apps/plugins/metronome.c2
-rw-r--r--apps/plugins/midi/midiplay.c14
-rw-r--r--apps/plugins/mikmod/mikmod.c10
-rw-r--r--apps/plugins/mpegplayer/pcm_output.c2
-rw-r--r--apps/plugins/pacbox/pacbox.c6
-rw-r--r--apps/plugins/pdbox/PDa/src/s_audio_rockbox.c10
-rw-r--r--apps/plugins/pitch_detector.c7
-rw-r--r--apps/plugins/rockboy/rbsound.c6
-rw-r--r--apps/plugins/test_sampr.c6
-rw-r--r--apps/plugins/zxbox/spsound.c9
-rw-r--r--apps/recorder/pcm_record.c36
-rw-r--r--apps/voice_thread.c17
18 files changed, 85 insertions, 77 deletions
diff --git a/apps/beep.c b/apps/beep.c
index d3345afdf9..3b02e5d8a3 100644
--- a/apps/beep.c
+++ b/apps/beep.c
@@ -46,7 +46,7 @@ static int16_t beep_buf[BEEP_BUF_COUNT*2] IBSS_ATTR __attribute__((aligned(4)));
46/* Callback to generate the beep frames - also don't want inlining of 46/* Callback to generate the beep frames - also don't want inlining of
47 call below in beep_play */ 47 call below in beep_play */
48static void __attribute__((noinline)) 48static void __attribute__((noinline))
49beep_get_more(unsigned char **start, size_t *size) 49beep_get_more(const void **start, size_t *size)
50{ 50{
51 int count = beep_count; 51 int count = beep_count;
52 52
@@ -87,7 +87,7 @@ void beep_play(unsigned int frequency, unsigned int duration,
87#endif 87#endif
88 88
89 /* If it fits - avoid cb overhead */ 89 /* If it fits - avoid cb overhead */
90 unsigned char *start; 90 const void *start;
91 size_t size; 91 size_t size;
92 92
93 /* Generate first frame here */ 93 /* Generate first frame here */
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index e0bfa1f62a..7ba4eeef8e 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -694,7 +694,7 @@ void pcmbuf_start_track_change(enum pcm_track_change_type type)
694/** Playback */ 694/** Playback */
695 695
696/* PCM driver callback */ 696/* PCM driver callback */
697static void pcmbuf_pcm_callback(unsigned char **start, size_t *size) 697static void pcmbuf_pcm_callback(const void **start, size_t *size)
698{ 698{
699 /*- Process the chunk that just finished -*/ 699 /*- Process the chunk that just finished -*/
700 size_t index = chunk_ridx; 700 size_t index = chunk_ridx;
diff --git a/apps/plugin.h b/apps/plugin.h
index 2fb085de6d..e07ec92c08 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -153,12 +153,12 @@ void* plugin_get_buffer(size_t *buffer_size);
153#define PLUGIN_MAGIC 0x526F634B /* RocK */ 153#define PLUGIN_MAGIC 0x526F634B /* RocK */
154 154
155/* increase this every time the api struct changes */ 155/* increase this every time the api struct changes */
156#define PLUGIN_API_VERSION 216 156#define PLUGIN_API_VERSION 217
157 157
158/* update this to latest version if a change to the api struct breaks 158/* update this to latest version if a change to the api struct breaks
159 backwards compatibility (and please take the opportunity to sort in any 159 backwards compatibility (and please take the opportunity to sort in any
160 new function which are "waiting" at the end of the function table) */ 160 new function which are "waiting" at the end of the function table) */
161#define PLUGIN_MIN_API_VERSION 216 161#define PLUGIN_MIN_API_VERSION 217
162 162
163/* plugin return codes */ 163/* plugin return codes */
164/* internal returns start at 0x100 to make exit(1..255) work */ 164/* internal returns start at 0x100 to make exit(1..255) work */
@@ -651,7 +651,8 @@ struct plugin_api {
651 const unsigned long *hw_freq_sampr; 651 const unsigned long *hw_freq_sampr;
652 void (*pcm_apply_settings)(void); 652 void (*pcm_apply_settings)(void);
653 void (*pcm_play_data)(pcm_play_callback_type get_more, 653 void (*pcm_play_data)(pcm_play_callback_type get_more,
654 unsigned char* start, size_t size); 654 pcm_status_callback_type status_cb,
655 const void *start, size_t size);
655 void (*pcm_play_stop)(void); 656 void (*pcm_play_stop)(void);
656 void (*pcm_set_frequency)(unsigned int frequency); 657 void (*pcm_set_frequency)(unsigned int frequency);
657 bool (*pcm_is_playing)(void); 658 bool (*pcm_is_playing)(void);
@@ -669,6 +670,7 @@ struct plugin_api {
669 void (*pcm_init_recording)(void); 670 void (*pcm_init_recording)(void);
670 void (*pcm_close_recording)(void); 671 void (*pcm_close_recording)(void);
671 void (*pcm_record_data)(pcm_rec_callback_type more_ready, 672 void (*pcm_record_data)(pcm_rec_callback_type more_ready,
673 pcm_status_callback_type status_cb,
672 void *start, size_t size); 674 void *start, size_t size);
673 void (*pcm_stop_recording)(void); 675 void (*pcm_stop_recording)(void);
674 void (*pcm_calculate_rec_peaks)(int *left, int *right); 676 void (*pcm_calculate_rec_peaks)(int *left, int *right);
@@ -689,12 +691,13 @@ struct plugin_api {
689 int (*dsp_output_count)(struct dsp_config *dsp, int count); 691 int (*dsp_output_count)(struct dsp_config *dsp, int count);
690 692
691 enum channel_status (*mixer_channel_status)(enum pcm_mixer_channel channel); 693 enum channel_status (*mixer_channel_status)(enum pcm_mixer_channel channel);
692 void * (*mixer_channel_get_buffer)(enum pcm_mixer_channel channel, int *count); 694 const void * (*mixer_channel_get_buffer)(enum pcm_mixer_channel channel,
695 int *count);
693 void (*mixer_channel_calculate_peaks)(enum pcm_mixer_channel channel, 696 void (*mixer_channel_calculate_peaks)(enum pcm_mixer_channel channel,
694 int *left, int *right); 697 int *left, int *right);
695 void (*mixer_channel_play_data)(enum pcm_mixer_channel channel, 698 void (*mixer_channel_play_data)(enum pcm_mixer_channel channel,
696 pcm_play_callback_type get_more, 699 pcm_play_callback_type get_more,
697 unsigned char *start, size_t size); 700 const void *start, size_t size);
698 void (*mixer_channel_play_pause)(enum pcm_mixer_channel channel, bool play); 701 void (*mixer_channel_play_pause)(enum pcm_mixer_channel channel, bool play);
699 void (*mixer_channel_stop)(enum pcm_mixer_channel channel); 702 void (*mixer_channel_stop)(enum pcm_mixer_channel channel);
700 void (*mixer_channel_set_amplitude)(enum pcm_mixer_channel channel, 703 void (*mixer_channel_set_amplitude)(enum pcm_mixer_channel channel,
diff --git a/apps/plugins/beatbox/beatbox.c b/apps/plugins/beatbox/beatbox.c
index 8ecbabd1e5..8c7413cc99 100644
--- a/apps/plugins/beatbox/beatbox.c
+++ b/apps/plugins/beatbox/beatbox.c
@@ -509,7 +509,7 @@ void redrawScreen(unsigned char force)
509 rb->lcd_update(); 509 rb->lcd_update();
510} 510}
511 511
512void get_more(unsigned char** start, size_t* size) 512void get_more(const void** start, size_t* size)
513{ 513{
514#ifndef SYNC 514#ifndef SYNC
515 if(lastswap!=swap) 515 if(lastswap!=swap)
@@ -523,10 +523,10 @@ void get_more(unsigned char** start, size_t* size)
523 523
524 *size = BUF_SIZE*sizeof(short); 524 *size = BUF_SIZE*sizeof(short);
525#ifndef SYNC 525#ifndef SYNC
526 *start = (unsigned char*)((swap ? gmbuf : gmbuf + BUF_SIZE)); 526 *start = swap ? gmbuf : gmbuf + BUF_SIZE;
527 swap=!swap; 527 swap=!swap;
528#else 528#else
529 *start = (unsigned char*)(gmbuf); 529 *start = gmbuf;
530#endif 530#endif
531} 531}
532 532
@@ -537,7 +537,7 @@ int beatboxmain()
537 537
538 numberOfSamples=44100/10; 538 numberOfSamples=44100/10;
539 synthbuf(); 539 synthbuf();
540 rb->pcm_play_data(&get_more, NULL, 0); 540 rb->pcm_play_data(&get_more, NULL, NULL, 0);
541 541
542 rb->lcd_set_background(0x000000); 542 rb->lcd_set_background(0x000000);
543 rb->lcd_clear_display(); 543 rb->lcd_clear_display();
diff --git a/apps/plugins/doom/i_sound.c b/apps/plugins/doom/i_sound.c
index 2d7b592818..bdf70c1215 100644
--- a/apps/plugins/doom/i_sound.c
+++ b/apps/plugins/doom/i_sound.c
@@ -457,11 +457,11 @@ void I_UpdateSound( void )
457// only output be done asynchronous? 457// only output be done asynchronous?
458// 458//
459 459
460void get_more(unsigned char** start, size_t* size) 460void get_more(const void** start, size_t* size)
461{ 461{
462 I_UpdateSound(); // Force sound update 462 I_UpdateSound(); // Force sound update
463 463
464 *start = (unsigned char*)(mixbuffer); 464 *start = mixbuffer;
465 *size = SAMPLECOUNT*2*sizeof(short); 465 *size = SAMPLECOUNT*2*sizeof(short);
466} 466}
467 467
@@ -471,7 +471,7 @@ void I_SubmitSound(void)
471 if (!enable_sound) 471 if (!enable_sound)
472 return; 472 return;
473 473
474 rb->pcm_play_data(&get_more, NULL, 0); 474 rb->pcm_play_data(&get_more, NULL, NULL, 0);
475} 475}
476 476
477void I_ShutdownSound(void) 477void I_ShutdownSound(void)
diff --git a/apps/plugins/fft/fft.c b/apps/plugins/fft/fft.c
index 1c4e1b4c20..f7d8943576 100644
--- a/apps/plugins/fft/fft.c
+++ b/apps/plugins/fft/fft.c
@@ -1186,8 +1186,8 @@ static inline bool fft_init_fft_lib(void)
1186static inline bool fft_get_fft(void) 1186static inline bool fft_get_fft(void)
1187{ 1187{
1188 int count; 1188 int count;
1189 int16_t *value = 1189 const int16_t *value =
1190 (int16_t *) rb->mixer_channel_get_buffer(PCM_MIXER_CHAN_PLAYBACK, &count); 1190 rb->mixer_channel_get_buffer(PCM_MIXER_CHAN_PLAYBACK, &count);
1191 /* This block can introduce discontinuities in our data. Meaning, the 1191 /* This block can introduce discontinuities in our data. Meaning, the
1192 * FFT will not be done a continuous segment of the signal. Which can 1192 * FFT will not be done a continuous segment of the signal. Which can
1193 * be bad. Or not. 1193 * be bad. Or not.
diff --git a/apps/plugins/metronome.c b/apps/plugins/metronome.c
index da035a7688..297405571f 100644
--- a/apps/plugins/metronome.c
+++ b/apps/plugins/metronome.c
@@ -721,7 +721,7 @@ static void prepare_tock(void)
721 721
722static void play_tock(void) 722static void play_tock(void)
723{ 723{
724 rb->pcm_play_data(NULL,(unsigned char *)sndbuf,sizeof(sndbuf)); 724 rb->pcm_play_data(NULL, NULL, sndbuf, sizeof(sndbuf));
725} 725}
726 726
727#endif /* CONFIG_CODEC != SWCODEC */ 727#endif /* CONFIG_CODEC != SWCODEC */
diff --git a/apps/plugins/midi/midiplay.c b/apps/plugins/midi/midiplay.c
index 40b4f1c83c..1412d4c742 100644
--- a/apps/plugins/midi/midiplay.c
+++ b/apps/plugins/midi/midiplay.c
@@ -319,7 +319,7 @@ static inline void synthbuf(void)
319 samples_in_buf = BUF_SIZE-i; 319 samples_in_buf = BUF_SIZE-i;
320} 320}
321 321
322static void get_more(unsigned char** start, size_t* size) 322static void get_more(const void** start, size_t* size)
323{ 323{
324#ifndef SYNC 324#ifndef SYNC
325 if(lastswap != swap) 325 if(lastswap != swap)
@@ -333,10 +333,10 @@ static void get_more(unsigned char** start, size_t* size)
333 333
334 *size = samples_in_buf*sizeof(int32_t); 334 *size = samples_in_buf*sizeof(int32_t);
335#ifndef SYNC 335#ifndef SYNC
336 *start = (unsigned char*)((swap ? gmbuf : gmbuf + BUF_SIZE)); 336 *start = swap ? gmbuf : gmbuf + BUF_SIZE;
337 swap = !swap; 337 swap = !swap;
338#else 338#else
339 *start = (unsigned char*)(gmbuf); 339 *start = gmbuf;
340#endif 340#endif
341} 341}
342 342
@@ -396,7 +396,7 @@ static int midimain(const void * filename)
396 samples_this_second = 0; 396 samples_this_second = 0;
397 397
398 synthbuf(); 398 synthbuf();
399 rb->pcm_play_data(&get_more, NULL, 0); 399 rb->pcm_play_data(&get_more, NULL, NULL, 0);
400 400
401 while (!quit) 401 while (!quit)
402 { 402 {
@@ -445,7 +445,7 @@ static int midimain(const void * filename)
445 seekBackward(5); 445 seekBackward(5);
446 midi_debug("Rewind to %d:%02d\n", playing_time/60, playing_time%60); 446 midi_debug("Rewind to %d:%02d\n", playing_time/60, playing_time%60);
447 if (is_playing) 447 if (is_playing)
448 rb->pcm_play_data(&get_more, NULL, 0); 448 rb->pcm_play_data(&get_more, NULL, NULL, 0);
449 break; 449 break;
450 } 450 }
451 451
@@ -455,7 +455,7 @@ static int midimain(const void * filename)
455 seekForward(5); 455 seekForward(5);
456 midi_debug("Skip to %d:%02d\n", playing_time/60, playing_time%60); 456 midi_debug("Skip to %d:%02d\n", playing_time/60, playing_time%60);
457 if (is_playing) 457 if (is_playing)
458 rb->pcm_play_data(&get_more, NULL, 0); 458 rb->pcm_play_data(&get_more, NULL, NULL, 0);
459 break; 459 break;
460 } 460 }
461 461
@@ -470,7 +470,7 @@ static int midimain(const void * filename)
470 { 470 {
471 midi_debug("Playing from %d:%02d\n", playing_time/60, playing_time%60); 471 midi_debug("Playing from %d:%02d\n", playing_time/60, playing_time%60);
472 is_playing = true; 472 is_playing = true;
473 rb->pcm_play_data(&get_more, NULL, 0); 473 rb->pcm_play_data(&get_more, NULL, NULL, 0);
474 } 474 }
475 break; 475 break;
476 } 476 }
diff --git a/apps/plugins/mikmod/mikmod.c b/apps/plugins/mikmod/mikmod.c
index a7eeb5019f..eb3be13140 100644
--- a/apps/plugins/mikmod/mikmod.c
+++ b/apps/plugins/mikmod/mikmod.c
@@ -268,7 +268,7 @@ static inline void synthbuf(void)
268 VC_WriteBytes(outptr, BUF_SIZE); 268 VC_WriteBytes(outptr, BUF_SIZE);
269} 269}
270 270
271void get_more(unsigned char** start, size_t* size) 271void get_more(const void** start, size_t* size)
272{ 272{
273#ifndef SYNC 273#ifndef SYNC
274 if (lastswap != swap) 274 if (lastswap != swap)
@@ -282,10 +282,10 @@ void get_more(unsigned char** start, size_t* size)
282 282
283 *size = BUF_SIZE; 283 *size = BUF_SIZE;
284#ifndef SYNC 284#ifndef SYNC
285 *start = (unsigned char*)((swap ? gmbuf : gmbuf + BUF_SIZE)); 285 *start = swap ? gmbuf : gmbuf + BUF_SIZE;
286 swap = !swap; 286 swap = !swap;
287#else 287#else
288 *start = (unsigned char*)(gmbuf); 288 *start = gmbuf;
289#endif 289#endif
290} 290}
291 291
@@ -660,7 +660,7 @@ int playfile(char* filename)
660 { 660 {
661 display = DISPLAY_INFO; 661 display = DISPLAY_INFO;
662 Player_Start(module); 662 Player_Start(module);
663 rb->pcm_play_data(&get_more, NULL, 0); 663 rb->pcm_play_data(&get_more, NULL, NULL, 0);
664 } 664 }
665 665
666#ifdef HAVE_ADJUSTABLE_CPU_FREQ 666#ifdef HAVE_ADJUSTABLE_CPU_FREQ
@@ -804,7 +804,7 @@ int playfile(char* filename)
804 } 804 }
805 else 805 else
806 { 806 {
807 rb->pcm_play_data(&get_more, NULL, 0); 807 rb->pcm_play_data(&get_more, NULL, NULL, 0);
808 } 808 }
809 Player_TogglePause(); 809 Player_TogglePause();
810 break; 810 break;
diff --git a/apps/plugins/mpegplayer/pcm_output.c b/apps/plugins/mpegplayer/pcm_output.c
index 8db9531049..8694ae4a69 100644
--- a/apps/plugins/mpegplayer/pcm_output.c
+++ b/apps/plugins/mpegplayer/pcm_output.c
@@ -85,7 +85,7 @@ static inline ssize_t pcm_output_bytes_free(void)
85} 85}
86 86
87/* Audio DMA handler */ 87/* Audio DMA handler */
88static void get_more(unsigned char **start, size_t *size) 88static void get_more(const void **start, size_t *size)
89{ 89{
90 ssize_t sz; 90 ssize_t sz;
91 91
diff --git a/apps/plugins/pacbox/pacbox.c b/apps/plugins/pacbox/pacbox.c
index 5165ff3047..efba47b576 100644
--- a/apps/plugins/pacbox/pacbox.c
+++ b/apps/plugins/pacbox/pacbox.c
@@ -286,7 +286,7 @@ static int16_t raw_buf[NBSAMPLES] IBSS_ATTR;
286/* 286/*
287 Audio callback 287 Audio callback
288 */ 288 */
289static void get_more(unsigned char **start, size_t *size) 289static void get_more(const void **start, size_t *size)
290{ 290{
291 int32_t *out, *outend; 291 int32_t *out, *outend;
292 int16_t *raw; 292 int16_t *raw;
@@ -306,7 +306,7 @@ static void get_more(unsigned char **start, size_t *size)
306 } 306 }
307 while (out < outend); 307 while (out < outend);
308 308
309 *start = (unsigned char *)sound_buf; 309 *start = sound_buf;
310 *size = NBSAMPLES*sizeof(sound_buf[0]); 310 *size = NBSAMPLES*sizeof(sound_buf[0]);
311} 311}
312 312
@@ -339,7 +339,7 @@ static void start_sound(void)
339 wsg3_set_sampling_rate(rb->hw_freq_sampr[sr_index]); 339 wsg3_set_sampling_rate(rb->hw_freq_sampr[sr_index]);
340 340
341 rb->pcm_set_frequency(rb->hw_freq_sampr[sr_index]); 341 rb->pcm_set_frequency(rb->hw_freq_sampr[sr_index]);
342 rb->pcm_play_data(get_more, NULL, 0); 342 rb->pcm_play_data(get_more, NULL, NULL, 0);
343 343
344 sound_playing = true; 344 sound_playing = true;
345} 345}
diff --git a/apps/plugins/pdbox/PDa/src/s_audio_rockbox.c b/apps/plugins/pdbox/PDa/src/s_audio_rockbox.c
index 76a50fa075..6571f74edf 100644
--- a/apps/plugins/pdbox/PDa/src/s_audio_rockbox.c
+++ b/apps/plugins/pdbox/PDa/src/s_audio_rockbox.c
@@ -26,7 +26,7 @@
26#include "s_stuff.h" 26#include "s_stuff.h"
27 27
28/* Declare functions that go to IRAM. */ 28/* Declare functions that go to IRAM. */
29void pdbox_get_more(unsigned char** start, size_t* size) ICODE_ATTR; 29void pdbox_get_more(const void** start, size_t* size) ICODE_ATTR;
30int rockbox_send_dacs(void) ICODE_ATTR; 30int rockbox_send_dacs(void) ICODE_ATTR;
31 31
32/* Extern variables. */ 32/* Extern variables. */
@@ -90,12 +90,12 @@ void rockbox_close_audio(void)
90} 90}
91 91
92/* Rockbox audio callback. */ 92/* Rockbox audio callback. */
93void pdbox_get_more(unsigned char** start, size_t* size) 93void pdbox_get_more(const void** start, size_t* size)
94{ 94{
95 if(outbuf_fill > 0) 95 if(outbuf_fill > 0)
96 { 96 {
97 /* Store output data address and size. */ 97 /* Store output data address and size. */
98 *start = (unsigned char*) outbuf[outbuf_tail].data; 98 *start = outbuf[outbuf_tail].data;
99 *size = sizeof(outbuf[outbuf_tail].data); 99 *size = sizeof(outbuf[outbuf_tail].data);
100 100
101 /* Free this part of output buffer. */ 101 /* Free this part of output buffer. */
@@ -116,8 +116,6 @@ void pdbox_get_more(unsigned char** start, size_t* size)
116 playing = false; 116 playing = false;
117 117
118 /* Nothing to play. */ 118 /* Nothing to play. */
119 *start = NULL;
120 *size = 0;
121 } 119 }
122} 120}
123 121
@@ -185,7 +183,7 @@ int rockbox_send_dacs(void)
185 if(!playing && outbuf_fill > 0) 183 if(!playing && outbuf_fill > 0)
186 { 184 {
187 /* Start playing. */ 185 /* Start playing. */
188 rb->pcm_play_data(pdbox_get_more, NULL, 0); 186 rb->pcm_play_data(pdbox_get_more, NULL, NULL, 0);
189 187
190 /* Set status flag. */ 188 /* Set status flag. */
191 playing = true; 189 playing = true;
diff --git a/apps/plugins/pitch_detector.c b/apps/plugins/pitch_detector.c
index c30d48a025..4ae43b3236 100644
--- a/apps/plugins/pitch_detector.c
+++ b/apps/plugins/pitch_detector.c
@@ -952,7 +952,7 @@ static uint32_t ICODE_ATTR buffer_magnitude(int16_t *input)
952} 952}
953 953
954/* Stop the recording when the buffer is full */ 954/* Stop the recording when the buffer is full */
955static void recording_callback(int status, void **start, size_t *size) 955static void recording_callback(void **start, size_t *size)
956{ 956{
957 int tail = audio_tail ^ 1; 957 int tail = audio_tail ^ 1;
958 958
@@ -963,8 +963,6 @@ static void recording_callback(int status, void **start, size_t *size)
963 /* Always record full buffer, even if not required */ 963 /* Always record full buffer, even if not required */
964 *start = audio_data[tail]; 964 *start = audio_data[tail];
965 *size = BUFFER_SIZE * sizeof (int16_t); 965 *size = BUFFER_SIZE * sizeof (int16_t);
966
967 (void)status;
968} 966}
969#endif /* SIMULATOR */ 967#endif /* SIMULATOR */
970 968
@@ -973,7 +971,8 @@ static void record_data(void)
973{ 971{
974#ifndef SIMULATOR 972#ifndef SIMULATOR
975 /* Always record full buffer, even if not required */ 973 /* Always record full buffer, even if not required */
976 rb->pcm_record_data(recording_callback, audio_data[audio_tail], 974 rb->pcm_record_data(recording_callback, NULL,
975 audio_data[audio_tail],
977 BUFFER_SIZE * sizeof (int16_t)); 976 BUFFER_SIZE * sizeof (int16_t));
978#endif 977#endif
979} 978}
diff --git a/apps/plugins/rockboy/rbsound.c b/apps/plugins/rockboy/rbsound.c
index c0d0277915..628879b4b7 100644
--- a/apps/plugins/rockboy/rbsound.c
+++ b/apps/plugins/rockboy/rbsound.c
@@ -16,10 +16,10 @@ static unsigned short *buf=0, *hwbuf=0;
16 16
17static bool newly_started; 17static bool newly_started;
18 18
19static void get_more(unsigned char** start, size_t* size) 19static void get_more(const void** start, size_t* size)
20{ 20{
21 memcpy(hwbuf, &buf[pcm.len*doneplay], BUF_SIZE*sizeof(short)); 21 memcpy(hwbuf, &buf[pcm.len*doneplay], BUF_SIZE*sizeof(short));
22 *start = (unsigned char*)(hwbuf); 22 *start = hwbuf;
23 *size = BUF_SIZE*sizeof(short); 23 *size = BUF_SIZE*sizeof(short);
24 doneplay=1; 24 doneplay=1;
25} 25}
@@ -76,7 +76,7 @@ int rockboy_pcm_submit(void)
76 76
77 if(newly_started) 77 if(newly_started)
78 { 78 {
79 rb->pcm_play_data(&get_more,NULL,0); 79 rb->pcm_play_data(&get_more, NULL, NULL,0);
80 newly_started = false; 80 newly_started = false;
81 } 81 }
82 82
diff --git a/apps/plugins/test_sampr.c b/apps/plugins/test_sampr.c
index db8301bba6..fc2f695c70 100644
--- a/apps/plugins/test_sampr.c
+++ b/apps/plugins/test_sampr.c
@@ -90,13 +90,13 @@ static int16_t ICODE_ATTR fsin(uint32_t phase)
90} 90}
91 91
92/* ISR handler to get next block of data */ 92/* ISR handler to get next block of data */
93static void get_more(unsigned char **start, size_t *size) 93static void get_more(const void **start, size_t *size)
94{ 94{
95 /* Free previous buffer */ 95 /* Free previous buffer */
96 output_head += output_step; 96 output_head += output_step;
97 output_step = 0; 97 output_step = 0;
98 98
99 *start = (unsigned char *)output_buf[output_head & OUTPUT_CHUNK_MASK]; 99 *start = output_buf[output_head & OUTPUT_CHUNK_MASK];
100 *size = OUTPUT_CHUNK_SIZE; 100 *size = OUTPUT_CHUNK_SIZE;
101 101
102 /* Keep repeating previous if source runs low */ 102 /* Keep repeating previous if source runs low */
@@ -236,7 +236,7 @@ static void play_tone(bool volume_set)
236 IF_PRIO(, PRIORITY_PLAYBACK) 236 IF_PRIO(, PRIORITY_PLAYBACK)
237 IF_COP(, CPU)); 237 IF_COP(, CPU));
238 238
239 rb->pcm_play_data(get_more, NULL, 0); 239 rb->pcm_play_data(get_more, NULL, NULL, 0);
240 240
241#ifndef HAVE_VOLUME_IN_LIST 241#ifndef HAVE_VOLUME_IN_LIST
242 if (volume_set) 242 if (volume_set)
diff --git a/apps/plugins/zxbox/spsound.c b/apps/plugins/zxbox/spsound.c
index 8b3aa3d84f..9d3eefa87f 100644
--- a/apps/plugins/zxbox/spsound.c
+++ b/apps/plugins/zxbox/spsound.c
@@ -189,12 +189,11 @@ void autoclose_sound(void)
189 } 189 }
190#endif 190#endif
191} 191}
192static void get_more(unsigned char** start, size_t* size) 192static void get_more(const void** start, size_t* size)
193{ 193{
194 doneplay = 1; 194 doneplay = 1;
195 rb->pcm_play_stop(); 195 (void)start;
196 (void)*start; 196 (void)size;
197 (void)*size;
198} 197}
199 198
200/* sp_sound_buf is Unsigned 8 bit, Rate 8000 Hz, Mono */ 199/* sp_sound_buf is Unsigned 8 bit, Rate 8000 Hz, Mono */
@@ -219,7 +218,7 @@ static void write_buf(void){
219 = my_buf[j+10] = my_buf[j+11] \ 218 = my_buf[j+10] = my_buf[j+11] \
220 = (((byte)sp_sound_buf[i])<<8) >> settings.volume; 219 = (((byte)sp_sound_buf[i])<<8) >> settings.volume;
221 220
222 rb->pcm_play_data(&get_more,(unsigned char*)(my_buf),TMNUM*4*3*2); 221 rb->pcm_play_data(&get_more,NULL,(unsigned char*)(my_buf),TMNUM*4*3*2);
223 222
224#if 0 223#if 0
225 /* can use to save and later analyze what we produce */ 224 /* can use to save and later analyze what we produce */
diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c
index 90a6163b8f..d904be9a4e 100644
--- a/apps/recorder/pcm_record.c
+++ b/apps/recorder/pcm_record.c
@@ -257,20 +257,9 @@ enum
257/*******************************************************************/ 257/*******************************************************************/
258 258
259/* Callback for when more data is ready - called in interrupt context */ 259/* Callback for when more data is ready - called in interrupt context */
260static void pcm_rec_have_more(int status, void **start, size_t *size) 260static void pcm_rec_have_more(void **start, size_t *size)
261{ 261{
262 if (status < 0) 262 if (!dma_lock)
263 {
264 /* some error condition */
265 if (status == DMA_REC_ERROR_DMA)
266 {
267 /* Flush recorded data to disk and stop recording */
268 queue_post(&pcmrec_queue, PCMREC_STOP, 0);
269 return;
270 }
271 /* else try again next transmission - frame is invalid */
272 }
273 else if (!dma_lock)
274 { 263 {
275 /* advance write position */ 264 /* advance write position */
276 int next_pos = (dma_wr_pos + PCM_CHUNK_SIZE) & PCM_CHUNK_MASK; 265 int next_pos = (dma_wr_pos + PCM_CHUNK_SIZE) & PCM_CHUNK_MASK;
@@ -287,6 +276,23 @@ static void pcm_rec_have_more(int status, void **start, size_t *size)
287 *size = PCM_CHUNK_SIZE; 276 *size = PCM_CHUNK_SIZE;
288} /* pcm_rec_have_more */ 277} /* pcm_rec_have_more */
289 278
279static enum pcm_dma_status pcm_rec_status_callback(enum pcm_dma_status status)
280{
281 if (status < PCM_DMAST_OK)
282 {
283 /* some error condition */
284 if (status == PCM_DMAST_ERR_DMA)
285 {
286 /* Flush recorded data to disk and stop recording */
287 queue_post(&pcmrec_queue, PCMREC_STOP, 0);
288 return status;
289 }
290 /* else try again next transmission - frame is invalid */
291 }
292
293 return PCM_DMAST_OK;
294} /* pcm_rec_status_callback */
295
290static void reset_hardware(void) 296static void reset_hardware(void)
291{ 297{
292 /* reset pcm to defaults */ 298 /* reset pcm to defaults */
@@ -1239,8 +1245,8 @@ static void pcmrec_set_recording_options(
1239 { 1245 {
1240 /* start DMA transfer */ 1246 /* start DMA transfer */
1241 dma_lock = pre_record_ticks == 0; 1247 dma_lock = pre_record_ticks == 0;
1242 pcm_record_data(pcm_rec_have_more, GET_PCM_CHUNK(dma_wr_pos), 1248 pcm_record_data(pcm_rec_have_more, pcm_rec_status_callback,
1243 PCM_CHUNK_SIZE); 1249 GET_PCM_CHUNK(dma_wr_pos), PCM_CHUNK_SIZE);
1244 } 1250 }
1245 else 1251 else
1246 { 1252 {
diff --git a/apps/voice_thread.c b/apps/voice_thread.c
index 2f216cde9d..5d23a74cbc 100644
--- a/apps/voice_thread.c
+++ b/apps/voice_thread.c
@@ -116,9 +116,12 @@ enum voice_thread_messages
116/* Structure to store clip data callback info */ 116/* Structure to store clip data callback info */
117struct voice_info 117struct voice_info
118{ 118{
119 pcm_play_callback_type get_more; /* Callback to get more clips */ 119 /* Callback to get more clips */
120 unsigned char *start; /* Start of clip */ 120 void (*get_more)(unsigned char** start, size_t* size);
121 size_t size; /* Size of clip */ 121 /* Start of clip */
122 unsigned char *start;
123 /* Size of clip */
124 size_t size;
122}; 125};
123 126
124/* Private thread data for its current state that must be passed to its 127/* Private thread data for its current state that must be passed to its
@@ -148,14 +151,14 @@ static inline int voice_unplayed_frames(void)
148} 151}
149 152
150/* Mixer channel callback */ 153/* Mixer channel callback */
151static void voice_pcm_callback(unsigned char **start, size_t *size) 154static void voice_pcm_callback(const void **start, size_t *size)
152{ 155{
153 if (voice_unplayed_frames() == 0) 156 if (voice_unplayed_frames() == 0)
154 return; /* Done! */ 157 return; /* Done! */
155 158
156 unsigned int i = ++cur_buf_out % VOICE_FRAMES; 159 unsigned int i = ++cur_buf_out % VOICE_FRAMES;
157 160
158 *start = (unsigned char *)voicebuf[i]; 161 *start = voicebuf[i];
159 *size = voicebuf_sizes[i]; 162 *size = voicebuf_sizes[i];
160} 163}
161 164
@@ -167,7 +170,7 @@ static void voice_start_playback(void)
167 170
168 unsigned int i = cur_buf_out % VOICE_FRAMES; 171 unsigned int i = cur_buf_out % VOICE_FRAMES;
169 mixer_channel_play_data(PCM_MIXER_CHAN_VOICE, voice_pcm_callback, 172 mixer_channel_play_data(PCM_MIXER_CHAN_VOICE, voice_pcm_callback,
170 (unsigned char *)voicebuf[i], voicebuf_sizes[i]); 173 voicebuf[i], voicebuf_sizes[i]);
171} 174}
172 175
173/* Stop the voice channel */ 176/* Stop the voice channel */
@@ -198,7 +201,7 @@ static void voice_buf_commit(size_t size)
198 201
199/* Stop any current clip and start playing a new one */ 202/* Stop any current clip and start playing a new one */
200void mp3_play_data(const unsigned char* start, int size, 203void mp3_play_data(const unsigned char* start, int size,
201 pcm_play_callback_type get_more) 204 void (*get_more)(unsigned char** start, size_t* size))
202{ 205{
203 if (get_more != NULL && start != NULL && (ssize_t)size > 0) 206 if (get_more != NULL && start != NULL && (ssize_t)size > 0)
204 { 207 {