rendered paste bodyIndex: apps/pcmbuf.c
===================================================================
--- apps/pcmbuf.c (revision 18859)
+++ apps/pcmbuf.c (working copy)
@@ -142,6 +142,7 @@
* to the DMA. Finally the function checks the status of the buffer and
* boosts if necessary */
static void pcmbuf_callback(unsigned char** start, size_t* size) ICODE_ATTR;
+#if 0
static void pcmbuf_callback(unsigned char** start, size_t* size)
{
{
@@ -189,7 +190,7 @@
}
}
}
-
+#endif
void pcmbuf_set_position_callback(void (*callback)(size_t size))
{
position_callback = callback;
@@ -320,6 +321,7 @@
bool pcmbuf_is_lowdata(void)
{
+ return true;
if (!pcm_is_playing() || pcm_is_paused() ||
crossfade_init || crossfade_active)
return false;
@@ -474,7 +476,7 @@
pcmbuf_crossfade_enable_finished();
pcmbuf_play_stop();
-
+ pcm_mixer_init();
return pcmbuf_bufend - audiobuffer;
}
@@ -513,6 +515,8 @@
/* Force playback. */
void pcmbuf_play_start(void)
{
+ pcm_mixer_play();
+ /*
if (!pcm_is_playing() && pcmbuf_unplayed_bytes && pcmbuf_read != NULL)
{
last_chunksize = pcmbuf_read->size;
@@ -520,6 +524,7 @@
pcm_play_data(pcmbuf_callback,
(unsigned char *)pcmbuf_read->addr, last_chunksize);
}
+ */
}
/**
@@ -861,7 +866,7 @@
return true;
}
-
+#if 0
void* pcmbuf_request_buffer(int *count)
{
if (crossfade_init)
@@ -895,7 +900,7 @@
}
}
}
-
+#endif
void * pcmbuf_request_voice_buffer(int *count)
{
/* A get-it-to-work-for-now hack (audio status could change by
@@ -927,7 +932,7 @@
{
return crossfade_active || crossfade_init;
}
-
+#if 0
void pcmbuf_write_complete(int count)
{
size_t length = (size_t)(unsigned int)count << 2;
@@ -946,7 +951,7 @@
pcmbuf_flush_fillpos();
}
}
-
+#endif
#if 0
bool pcmbuf_insert_buffer(char *buf, int count)
{
@@ -1114,3 +1119,154 @@
return crossfade_enabled;
}
+
+/* stuff that needs reimplementing:
+ pcmbuf_request_buffer() - called to get a block to write to
+ pcmbuf_write_complete() - called once a pcm block has been finished writing to by the codec
+ pcmbuf_callback() - called by the ISR to get some pcm to output
+ */
+
+#define PCM_BLOCK_SIZE 8*1024*2*2 /* 8K samples */
+#define MAX_PCM_BLOCKS 32
+struct pcm_block {
+ unsigned char buf[PCM_BLOCK_SIZE];
+ unsigned int size;
+ struct pcm_block *next;
+};
+static struct pcm_block pcm_block_buffer[MAX_PCM_BLOCKS];
+static int block_count = 0;
+enum {
+ CHANNEL_AUDIO = 0,
+ // CHANNEL_VOICE,
+
+ PCM_CHANNEL_COUNT,
+};
+struct pcm_mixer_channel {
+ struct pcm_block *head;
+ struct pcm_block *tail;
+ bool paused;
+};
+struct pcm_mixer_channel channels[PCM_CHANNEL_COUNT];
+
+struct pcm_block *get_free_block(void)
+{
+ int i = 0;
+ struct pcm_block *ret;
+ while (i<MAX_PCM_BLOCKS)
+ {
+ ret = &pcm_block_buffer[i];
+ if (ret->size == 0) {
+ // printf("block %d\n", i);
+ return ret;
+ }
+ i++;
+ }
+ pcmbuf_play_start();
+ return NULL;
+}
+
+void pcm_mixer_init(void)
+{
+ int i = 0;
+ for (i=0; i<PCM_CHANNEL_COUNT; i++)
+ {
+ channels[i].head = NULL;
+ channels[i].tail = NULL;
+ channels[i].paused = false;
+ }
+ for (i=0; i<MAX_PCM_BLOCKS; i++)
+ {
+ pcm_block_buffer[i].size = 0;
+ }
+}
+
+void* pcmbuf_request_buffer(int *count)
+{
+ struct pcm_block *block, *tail;
+ int bytes = *count<<2;
+ tail = channels[CHANNEL_AUDIO].tail;
+ // printf("pcmbuf_request_buffer\n");
+ //printf("%d: \n", PCM_BLOCK_SIZE-tail->size);
+ if (tail && (PCM_BLOCK_SIZE-tail->size > 0))
+ {
+ bytes = MIN(bytes, (PCM_BLOCK_SIZE-tail->size));
+ *count = bytes>>2;
+ printf("%d %d\n", *count, bytes);
+ tail->size += bytes;
+ return tail->buf + tail->size;
+ }
+ block = get_free_block();
+ if (block == NULL)
+ return NULL;
+ block->next = NULL;
+ bytes = MIN(bytes, 512<<2);
+ //printf("%d %d\n", *count, *count>>2);
+ block->size = bytes;
+ *count = bytes>>2;
+ if (channels[CHANNEL_AUDIO].head == NULL)
+ channels[CHANNEL_AUDIO].head = block;
+ if (channels[CHANNEL_AUDIO].tail == NULL)
+ channels[CHANNEL_AUDIO].tail = block;
+ else
+ {
+ channels[CHANNEL_AUDIO].tail->next = block;
+ channels[CHANNEL_AUDIO].tail = block;
+ }
+ return block->buf;
+}
+
+void pcmbuf_write_complete(int count)
+{
+ // printf("pcmbuf_write_complete, %d\n", count);
+ block_count++;
+ //channels[CHANNEL_AUDIO].tail->size = count;
+}
+static bool playing = false;
+void pcm_mixer_play(void)
+{
+ struct pcm_mixer_channel *c = &channels[CHANNEL_AUDIO];
+ if (!c->paused && c->head != NULL && !playing && block_count > 0)
+ {
+ if (c->head == c->tail)
+ return;
+ pcm_play_data(pcmbuf_callback, channels[CHANNEL_AUDIO].head->buf, channels[CHANNEL_AUDIO].head->size);
+ playing = true;
+ }
+}
+
+static void pcmbuf_callback(unsigned char** start, size_t* size)
+{
+ struct pcm_block *block = NULL;
+ {
+ int last_size = channels[CHANNEL_AUDIO].head->size;
+ channels[CHANNEL_AUDIO].head->size = 0;
+ block = channels[CHANNEL_AUDIO].head->next;
+ channels[CHANNEL_AUDIO].head = block;
+ /* The buffer is finished, call the callback functions */
+ CALL_IF_EXISTS(position_callback, last_size);
+ CALL_IF_EXISTS(pcmbuf_event_handler);
+ block_count--;
+ }
+ {
+ /* mix all the channels that are ready */
+ // ... TODO
+ struct pcm_mixer_channel *c = &channels[CHANNEL_AUDIO];
+ if (!c->paused && c->head != NULL)
+ {
+ *start = c->head->buf;
+ *size = c->head->size;
+ }
+ else
+ {
+ *start = NULL;
+ *size = 0;
+ playing = false;
+ }
+ }
+}
+
+
+
+
+
+
\ No newline at end of file
Index: apps/playback.c
===================================================================
--- apps/playback.c (revision 18860)
+++ apps/playback.c (working copy)
@@ -904,7 +904,7 @@
if (inp_count <= 0)
return true;
-
+
/* Input size has grown, no error, just don't write more than length */
if (inp_count > count)
inp_count = count;