Index: 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 (isize == 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; isize); + 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;