All pastes #1234716 Raw Edit

Anonymous

public text v1 · immutable
#1234716 ·published 2008-10-23 14:48 UTC
rendered paste body
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 (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;