MP3 Player without external hardware MP3 Player without external hardware. A software based MP3 player based on a modified version of libmad. Mono output (at the moment) via AnalogOut. Files are read from an USB drive. This is a demo program, it plays only one file at the moment. Documentation is in "main.cpp" and "config.h"

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
Gruenfrosch
Date:
Sat Nov 27 17:27:33 2010 +0000
Parent:
1:7c923cbe9f1d
Commit message:
Version 3:
* moved another memory block into AHB RAM, giving more room for
* stereo buffer.
* moved content of decode() to main()
* decoding is now safe to be called multiple times (bug in older versions)
* Output routine now fills stereo buffer, DAC output sums channels,
* just for demonstration that stereo output could go here

Changed in this revision

config.h Show annotated file Show diff for this revision Revisions of this file
decoder.cpp Show annotated file Show diff for this revision Revisions of this file
decoder.h Show annotated file Show diff for this revision Revisions of this file
frame.cpp Show annotated file Show diff for this revision Revisions of this file
frame.h Show annotated file Show diff for this revision Revisions of this file
global.h Show annotated file Show diff for this revision Revisions of this file
layer3.cpp Show annotated file Show diff for this revision Revisions of this file
lpc1768_mem.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
stream.cpp Show annotated file Show diff for this revision Revisions of this file
timer.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 7c923cbe9f1d -r f28cf0afd021 config.h
--- a/config.h	Fri Nov 26 13:05:34 2010 +0000
+++ b/config.h	Sat Nov 27 17:27:33 2010 +0000
@@ -42,7 +42,12 @@
 
 # ifndef LIBMAD_CONFIG_H
 # define LIBMAD_CONFIG_H
+
+#if defined(TARGET_LPC1768)
 #include "mbed.h"
+void *mad_malloc(unsigned int sz);
+void reset_ahb_mem(void);
+#endif
 
 /* config.h.  Generated by configure.  */
 /* config.h.in.  Generated from configure.ac by autoheader.  */
@@ -53,6 +58,7 @@
 
 /* used by ethernet */
 #define AHBMEM ((void *)0x20080000)
+#define AHBMEMSIZE 16300
 
 #define FPM_DEFAULT
 /* Define to enable diagnostic debugging support. */
@@ -131,10 +137,10 @@
 /* #undef OPT_ACCURACY */
 
 /* Define to optimize for speed over accuracy. */
-/* #undef OPT_SPEED */
+/* #define OPT_SPEED */
 
 /* Define to enable a fast subband synthesis approximation optimization. */
-/* #undef OPT_SSO */
+/* #define OPT_SSO */
 
 /* Define to influence a strict interpretation of the ISO/IEC standards, even
    if this is in opposition with best accepted practices. */
@@ -182,4 +188,8 @@
 
 /* Define to `int' if <sys/types.h> does not define. */
 /* #undef pid_t */
+
+
+/* Define mad_malloc to malloc if no special mem handling required */
+
 #endif
diff -r 7c923cbe9f1d -r f28cf0afd021 decoder.cpp
--- a/decoder.cpp	Fri Nov 26 13:05:34 2010 +0000
+++ b/decoder.cpp	Sat Nov 27 17:27:33 2010 +0000
@@ -76,9 +76,6 @@
 
   decoder->options      = 0;
 
-  decoder->async.pid    = 0;
-  decoder->async.in     = -1;
-  decoder->async.out    = -1;
 
   decoder->sync         = 0;
 
@@ -94,202 +91,9 @@
 
 int mad_decoder_finish(struct mad_decoder *decoder)
 {
-# if defined(USE_ASYNC)
-  if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) {
-    pid_t pid;
-    int status;
-
-    close(decoder->async.in);
-
-    do
-      pid = waitpid(decoder->async.pid, &status, 0);
-    while (pid == -1 && errno == EINTR);
-
-    decoder->mode = -1;
-
-    close(decoder->async.out);
-
-    decoder->async.pid = 0;
-    decoder->async.in  = -1;
-    decoder->async.out = -1;
-
-    if (pid == -1)
-      return -1;
-
-    return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0;
-  }
-# endif
-
   return 0;
 }
 
-# if defined(USE_ASYNC)
-static
-enum mad_flow send_io(int fd, void const *data, size_t len)
-{
-  char const *ptr = data;
-  ssize_t count;
-
-  while (len) {
-    do
-      count = write(fd, ptr, len);
-    while (count == -1 && errno == EINTR);
-
-    if (count == -1)
-      return MAD_FLOW_BREAK;
-
-    len -= count;
-    ptr += count;
-  }
-
-  return MAD_FLOW_CONTINUE;
-}
-
-static
-enum mad_flow receive_io(int fd, void *buffer, size_t len)
-{
-  char *ptr = buffer;
-  ssize_t count;
-
-  while (len) {
-    do
-      count = read(fd, ptr, len);
-    while (count == -1 && errno == EINTR);
-
-    if (count == -1)
-      return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK;
-    else if (count == 0)
-      return MAD_FLOW_STOP;
-
-    len -= count;
-    ptr += count;
-  }
-
-  return MAD_FLOW_CONTINUE;
-}
-
-static
-enum mad_flow receive_io_blocking(int fd, void *buffer, size_t len)
-{
-  int flags, blocking;
-  enum mad_flow result;
-
-  flags = fcntl(fd, F_GETFL);
-  if (flags == -1)
-    return MAD_FLOW_BREAK;
-
-  blocking = flags & ~O_NONBLOCK;
-
-  if (blocking != flags &&
-      fcntl(fd, F_SETFL, blocking) == -1)
-    return MAD_FLOW_BREAK;
-
-  result = receive_io(fd, buffer, len);
-
-  if (flags != blocking &&
-      fcntl(fd, F_SETFL, flags) == -1)
-    return MAD_FLOW_BREAK;
-
-  return result;
-}
-
-static
-enum mad_flow send(int fd, void const *message, unsigned int size)
-{
-  enum mad_flow result;
-
-  /* send size */
-
-  result = send_io(fd, &size, sizeof(size));
-
-  /* send message */
-
-  if (result == MAD_FLOW_CONTINUE)
-    result = send_io(fd, message, size);
-
-  return result;
-}
-
-static
-enum mad_flow receive(int fd, void **message, unsigned int *size)
-{
-  enum mad_flow result;
-  unsigned int actual;
-
-  if (*message == 0)
-    *size = 0;
-
-  /* receive size */
-
-  result = receive_io(fd, &actual, sizeof(actual));
-
-  /* receive message */
-
-  if (result == MAD_FLOW_CONTINUE) {
-    if (actual > *size)
-      actual -= *size;
-    else {
-      *size  = actual;
-      actual = 0;
-    }
-
-    if (*size > 0) {
-      if (*message == 0) {
-        *message = malloc(*size);
-        if (*message == 0)
-          return MAD_FLOW_BREAK;
-      }
-
-      result = receive_io_blocking(fd, *message, *size);
-    }
-
-    /* throw away remainder of message */
-
-    while (actual && result == MAD_FLOW_CONTINUE) {
-      char sink[256];
-      unsigned int len;
-
-      len = actual > sizeof(sink) ? sizeof(sink) : actual;
-
-      result = receive_io_blocking(fd, sink, len);
-
-      actual -= len;
-    }
-  }
-
-  return result;
-}
-
-static
-enum mad_flow check_message(struct mad_decoder *decoder)
-{
-  enum mad_flow result;
-  void *message = 0;
-  unsigned int size;
-
-  result = receive(decoder->async.in, &message, &size);
-
-  if (result == MAD_FLOW_CONTINUE) {
-    if (decoder->message_func == 0)
-      size = 0;
-    else {
-      result = decoder->message_func(decoder->cb_data, message, &size);
-
-      if (result == MAD_FLOW_IGNORE ||
-          result == MAD_FLOW_BREAK)
-        size = 0;
-    }
-
-    if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE)
-      result = MAD_FLOW_BREAK;
-  }
-
-  if (message)
-    free(message);
-
-  return result;
-}
-# endif
 
 static
 enum mad_flow error_default(void *data, struct mad_stream *stream,
@@ -357,20 +161,6 @@
     }
 
     while (1) {
-# if defined(USE_ASYNC)
-      if (decoder->mode == MAD_DECODER_MODE_ASYNC) {
-        switch (check_message(decoder)) {
-        case MAD_FLOW_IGNORE:
-        case MAD_FLOW_CONTINUE:
-          break;
-        case MAD_FLOW_BREAK:
-          goto fail;
-        case MAD_FLOW_STOP:
-          goto done;
-        }
-      }
-# endif
-
       if (decoder->header_func) {
         if (mad_header_decode(&frame->header, stream) == -1) {
           if (!MAD_RECOVERABLE(stream->error))
@@ -461,69 +251,6 @@
   return result;
 }
 
-# if defined(USE_ASYNC)
-static
-int run_async(struct mad_decoder *decoder)
-{
-  pid_t pid;
-  int ptoc[2], ctop[2], flags;
-
-  if (pipe(ptoc) == -1)
-    return -1;
-
-  if (pipe(ctop) == -1) {
-    close(ptoc[0]);
-    close(ptoc[1]);
-    return -1;
-  }
-
-  flags = fcntl(ptoc[0], F_GETFL);
-  if (flags == -1 ||
-      fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) {
-    close(ctop[0]);
-    close(ctop[1]);
-    close(ptoc[0]);
-    close(ptoc[1]);
-    return -1;
-  }
-
-  pid = fork();
-  if (pid == -1) {
-    close(ctop[0]);
-    close(ctop[1]);
-    close(ptoc[0]);
-    close(ptoc[1]);
-    return -1;
-  }
-
-  decoder->async.pid = pid;
-
-  if (pid) {
-    /* parent */
-
-    close(ptoc[0]);
-    close(ctop[1]);
-
-    decoder->async.in  = ctop[0];
-    decoder->async.out = ptoc[1];
-
-    return 0;
-  }
-
-  /* child */
-
-  close(ptoc[1]);
-  close(ctop[0]);
-
-  decoder->async.in  = ptoc[0];
-  decoder->async.out = ctop[1];
-
-  _exit(run_sync(decoder));
-
-  /* not reached */
-  return -1;
-}
-# endif
 
 /*
  * NAME:        decoder->run()
@@ -540,25 +267,28 @@
     break;
 
   case MAD_DECODER_MODE_ASYNC:
-# if defined(USE_ASYNC)
-    run = run_async;
-# endif
     break;
   }
 
   if (run == 0)
     return -1;
-
+  // static struct mad_sync_s sync_mem;
   decoder->sync = (struct mad_sync_s *)malloc(sizeof(*decoder->sync));
-  decoder->sync->synth = (struct mad_synth *)AHBMEM;   // 12kb in upper memory
+#if defined(TARGET_LPC1768)  
+  decoder->sync->synth = (struct mad_synth *)mad_malloc(sizeof(struct mad_synth));
+#else
+  decoder->sync->synth = (struct mad_synth *)malloc(sizeof(struct mad_synth));
+#endif
   if (decoder->sync == 0)
     return -1;
 
   result = run(decoder);
-
+#if !defined(TARGET_LPC1768)  
+  free(decoder->sync->synth);
+#endif  
   free(decoder->sync);
   decoder->sync = 0;
-
+  reset_ahb_mem();
   return result;
 }
 
@@ -569,14 +299,5 @@
 int mad_decoder_message(struct mad_decoder *decoder,
                         void *message, unsigned int *len)
 {
-# if defined(USE_ASYNC)
-  if (decoder->mode != MAD_DECODER_MODE_ASYNC ||
-      send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE ||
-      receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE)
-    return -1;
-
-  return 0;
-# else
   return -1;
-# endif
 }
diff -r 7c923cbe9f1d -r f28cf0afd021 decoder.h
--- a/decoder.h	Fri Nov 26 13:05:34 2010 +0000
+++ b/decoder.h	Sat Nov 27 17:27:33 2010 +0000
@@ -49,12 +49,6 @@
 
   int options;
 
-  struct {
-    long pid;
-    int in;
-    int out;
-  } async;
-
   struct mad_sync_s *sync;
 
   void *cb_data;
diff -r 7c923cbe9f1d -r f28cf0afd021 frame.cpp
--- a/frame.cpp	Fri Nov 26 13:05:34 2010 +0000
+++ b/frame.cpp	Sat Nov 27 17:27:33 2010 +0000
@@ -92,7 +92,7 @@
 
   frame->options = 0;
 
-  frame->overlap = 0;
+//###  frame->overlap = 0;
   mad_frame_mute(frame);
 }
 
@@ -103,11 +103,12 @@
 void mad_frame_finish(struct mad_frame *frame)
 {
   mad_header_finish(&frame->header);
-
+/* ###
   if (frame->overlap) {
     free(frame->overlap);
     frame->overlap = 0;
   }
+  */
 }
 
 /*
@@ -493,8 +494,8 @@
   if (frame->overlap) {
     for (s = 0; s < 18; ++s) {
       for (sb = 0; sb < 32; ++sb) {
-	(*frame->overlap)[0][sb][s] =
-	(*frame->overlap)[1][sb][s] = 0;
+	(frame->overlap)[0][sb][s] =
+	(frame->overlap)[1][sb][s] = 0;
       }
     }
   }
diff -r 7c923cbe9f1d -r f28cf0afd021 frame.h
--- a/frame.h	Fri Nov 26 13:05:34 2010 +0000
+++ b/frame.h	Sat Nov 27 17:27:33 2010 +0000
@@ -70,7 +70,7 @@
   int options;				/* decoding options (from stream) */
 
   mad_fixed_t sbsample[2][36][32];	/* synthesis subband filter samples */
-  mad_fixed_t (*overlap)[2][32][18];	/* Layer III block overlap data */
+  mad_fixed_t overlap[2][32][18];	/* Layer III block overlap data */
 };
 
 # define MAD_NCHANNELS(header)		((header)->mode ? 2 : 1)
diff -r 7c923cbe9f1d -r f28cf0afd021 global.h
--- a/global.h	Fri Nov 26 13:05:34 2010 +0000
+++ b/global.h	Sat Nov 27 17:27:33 2010 +0000
@@ -42,17 +42,4 @@
 #  define OPT_SSO
 # endif
 
-# if defined(HAVE_UNISTD_H) && defined(HAVE_WAITPID) &&  \
-    defined(HAVE_FCNTL) && defined(HAVE_PIPE) && defined(HAVE_FORK)
-#  define USE_ASYNC
 # endif
-
-# if !defined(HAVE_ASSERT_H)
-#  if defined(NDEBUG)
-#   define assert(x)	/* nothing */
-#  else
-#   define assert(x)	do { if (!(x)) abort(); } while (0)
-#  endif
-# endif
-
-# endif
diff -r 7c923cbe9f1d -r f28cf0afd021 layer3.cpp
--- a/layer3.cpp	Fri Nov 26 13:05:34 2010 +0000
+++ b/layer3.cpp	Sat Nov 27 17:27:33 2010 +0000
@@ -26,10 +26,6 @@
 # include <stdlib.h>
 # include <string.h>
 
-# ifdef HAVE_ASSERT_H
-#  include <assert.h>
-# endif
-
 # ifdef HAVE_LIMITS_H
 #  include <limits.h>
 # else
@@ -1253,7 +1249,7 @@
     }
   }
 
-  assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);
+  /* assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);*/
 
 # if 0 && defined(DEBUG)
   if (bits_left < 0)
@@ -2456,14 +2452,14 @@
 	/* long blocks */
 	for (sb = 0; sb < 2; ++sb, l += 18) {
 	  III_imdct_l(&xr[ch][l], output, block_type);
-	  III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
+	  III_overlap(output, (frame->overlap)[ch][sb], sample, sb);
 	}
       }
       else {
 	/* short blocks */
 	for (sb = 0; sb < 2; ++sb, l += 18) {
 	  III_imdct_s(&xr[ch][l], output);
-	  III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
+	  III_overlap(output, (frame->overlap)[ch][sb], sample, sb);
 	}
       }
 
@@ -2481,7 +2477,7 @@
 	/* long blocks */
 	for (sb = 2; sb < sblimit; ++sb, l += 18) {
 	  III_imdct_l(&xr[ch][l], output, channel->block_type);
-	  III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
+	  III_overlap(output, (frame->overlap)[ch][sb], sample, sb);
 
 	  if (sb & 1)
 	    III_freqinver(sample, sb);
@@ -2491,7 +2487,7 @@
 	/* short blocks */
 	for (sb = 2; sb < sblimit; ++sb, l += 18) {
 	  III_imdct_s(&xr[ch][l], output);
-	  III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
+	  III_overlap(output, (frame->overlap)[ch][sb], sample, sb);
 
 	  if (sb & 1)
 	    III_freqinver(sample, sb);
@@ -2501,7 +2497,7 @@
       /* remaining (zero) subbands */
 
       for (sb = sblimit; sb < 32; ++sb) {
-	III_overlap_z((*frame->overlap)[ch][sb], sample, sb);
+	III_overlap_z((frame->overlap)[ch][sb], sample, sb);
 
 	if (sb & 1)
 	  III_freqinver(sample, sb);
@@ -2530,21 +2526,17 @@
   /* allocate Layer III dynamic structures */
 
   if (stream->main_data == 0) {
+#if defined(TARGET_LPC1768)
+    stream->main_data = (unsigned char (*)[MAD_BUFFER_MDLEN])mad_malloc(MAD_BUFFER_MDLEN);
+#else
     stream->main_data = (unsigned char (*)[MAD_BUFFER_MDLEN])malloc(MAD_BUFFER_MDLEN);
+#endif
     if (stream->main_data == 0) {
       stream->error = MAD_ERROR_NOMEM;
       return -1;
     }
   }
 
-  if (frame->overlap == 0) {
-    frame->overlap = (mad_fixed_t (*)[2][32][18])calloc(2 * 32 * 18, sizeof(mad_fixed_t));
-    if (frame->overlap == 0) {
-      stream->error = MAD_ERROR_NOMEM;
-      return -1;
-    }
-  }
-
   nch = MAD_NCHANNELS(header);
   si_len = (header->flags & MAD_FLAG_LSF_EXT) ?
     (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32);
@@ -2632,8 +2624,7 @@
 		   *stream->main_data + stream->md_len - si.main_data_begin);
 
       if (md_len > si.main_data_begin) {
-	assert(stream->md_len + md_len -
-	       si.main_data_begin <= MAD_BUFFER_MDLEN);
+	/*assert(stream->md_len + md_len -si.main_data_begin <= MAD_BUFFER_MDLEN); */
 
 	memcpy(*stream->main_data + stream->md_len,
 	       mad_bit_nextbyte(&stream->ptr),
diff -r 7c923cbe9f1d -r f28cf0afd021 lpc1768_mem.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lpc1768_mem.cpp	Sat Nov 27 17:27:33 2010 +0000
@@ -0,0 +1,25 @@
+#include "mbed.h"
+#include "config.h"
+
+static char *free_ptr = (char *)AHBMEM;
+static int free_sz = AHBMEMSIZE;
+void reset_ahb_mem(void)
+ {
+   free_ptr = (char *)AHBMEM;
+   free_sz = AHBMEMSIZE;
+ }
+void *mad_malloc(unsigned int sz)
+{
+  unsigned int nsz = ((sz >> 3) + 1) << 3; // align to 8 byte
+  if(nsz < free_sz)
+  {
+    char *p = free_ptr;
+	free_ptr += nsz;
+	free_sz -=nsz;
+	return(p);
+  }
+  else
+  {
+    return(malloc(sz));
+  }
+}
diff -r 7c923cbe9f1d -r f28cf0afd021 main.cpp
--- a/main.cpp	Fri Nov 26 13:05:34 2010 +0000
+++ b/main.cpp	Sat Nov 27 17:27:33 2010 +0000
@@ -28,18 +28,33 @@
  * use "decoder.h" for now
  * Have fun, 
  *   Andreas Gruen 
+ * *** Version 3:  ***
+ * moved another memory block into AHB RAM, giving more room for
+ * stereo buffer.
+ * moved content of decode() to main()
+ * decoding	is now safe to be called multiple times (bug in older versions)
+ * Output routine now fills stereo buffer, DAC output sums channels,
+ * just for demonstration that stereo output could go here
  */
 
 #include "mbed.h"
 # include "decoder.h"
 
-static int decode(void);
 FILE *fp;
 #include "MSCFileSystem.h"
 MSCFileSystem fs("usb");
 
-volatile unsigned short dacbuf[1200];
-volatile unsigned short *dac_s, *dac_e;
+static enum mad_flow input(void *data,struct mad_stream *stream);
+static enum mad_flow output(void *data,struct mad_header const *header,struct mad_pcm *pcm);
+static enum mad_flow error_fn(void *data,struct mad_stream *stream,struct mad_frame *frame);
+
+struct dacout_s {
+  unsigned short l;
+  unsigned short r;
+ };
+
+volatile dacout_s dacbuf[1152];
+volatile dacout_s *dac_s, *dac_e;
 
 AnalogOut dac(p18);
 Ticker dacclk;
@@ -48,26 +63,33 @@
 {
   if(dac_s < dac_e)  
   {
-    dac.write_u16(*dac_s++);
+    dac.write_u16((dac_s->l/2)+(dac_s->r/2));
+	dac_s++;
   }
 }
 
 int main(int argc, char *argv[])
 {
-  int ret;
+  int result;
   Timer t;
+  struct mad_decoder decoder;
 
   dac_s = dac_e = dacbuf;
   dacclk.attach_us(dacout,23);
-
-  fp = fopen("/usb/test.mp3","rb");
-  if(!fp)  return(printf("no file\r\n"));
-  t.start();
-  ret = decode();
-  t.stop();
-  printf("decode ret=%d in %d ms\r\n",ret,t.read_ms());
-  fclose(fp);
-
+  while(1) {
+	  fp = fopen("/usb/test.mp3","rb");
+	
+	  if(!fp)  return(printf("file error\r\n"));
+	  fprintf(stderr,"decode start\r\n");
+	  mad_decoder_init(&decoder, NULL,input, 0, 0, output,error_fn, 0);
+	  t.reset();
+	  t.start();
+	  result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
+	  t.stop();
+	  fprintf(stderr,"decode ret=%d in %d ms\r\n",result,t.read_ms());
+	  mad_decoder_finish(&decoder);
+	  fclose(fp);
+	}
   return 0;
 }
 
@@ -149,33 +171,27 @@
   unsigned int nchannels, nsamples;
   mad_fixed_t const *left_ch, *right_ch;
 
+
   /* pcm->samplerate contains the sampling frequency */
   nchannels = pcm->channels;
   nsamples  = pcm->length;
   left_ch   = pcm->samples[0];
   right_ch  = pcm->samples[1];
-  
-  while(dac_s < dac_e) wait_us(10);
-  dac_e = dacbuf;  // potential thread problem ??
-  dac_s = dacbuf;  
+
+  while(dac_s < dac_e) wait_us(1);
+  dac_e = dacbuf;  // potential thread problem ??  no...
+  dac_s = dacbuf;
 
   while (nsamples--) {
-    signed int sample;
-
-    /* output sample(s) in 16-bit signed little-endian PCM */
-
-    sample = scale(*left_ch++);     
-    *dac_e++ = sample  +32700;
-    //putchar((sample >> 0) & 0xff);
-    //putchar((sample >> 8) & 0xff);
-	/* the second channel is not supported at the moment*/
-    if (nchannels == 2) {
-      sample = scale(*right_ch++);
-      //putchar((sample >> 0) & 0xff);
-      //putchar((sample >> 8) & 0xff);
-    }
+    signed int sample_l,sample_r;
+    sample_l = scale(*left_ch);
+    sample_r = scale(*right_ch);
+    dac_e->l = sample_l  +32768;
+    dac_e->r = sample_r  +32768;
+    dac_e++;
+    left_ch++;
+    right_ch++;
   }
-
   return MAD_FLOW_CONTINUE;
 }
 
@@ -202,36 +218,4 @@
   return MAD_FLOW_CONTINUE;
 }
 
-/*
- * This is the function called by main() above to perform all the decoding.
- * It instantiates a decoder object and configures it with the input,
- * output, and error callback functions above. A single call to
- * mad_decoder_run() continues until a callback function returns
- * MAD_FLOW_STOP (to stop decoding) or MAD_FLOW_BREAK (to stop decoding and
- * signal an error).
- */
 
-static
-int decode()
-{
-  struct mad_decoder decoder;
-  int result;
-
-  /* configure input, output, and error functions */
-
-  mad_decoder_init(&decoder, NULL,
-           input, 0 /* header */, 0 /* filter */, output,
-           error_fn, 0 /* message */);
-
-  /* start decoding */
-
-  result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
-
-  /* release the decoder */
-
-  mad_decoder_finish(&decoder);
-
-  return result;
-}
-
-
diff -r 7c923cbe9f1d -r f28cf0afd021 stream.cpp
--- a/stream.cpp	Fri Nov 26 13:05:34 2010 +0000
+++ b/stream.cpp	Sat Nov 27 17:27:33 2010 +0000
@@ -62,7 +62,9 @@
 void mad_stream_finish(struct mad_stream *stream)
 {
   if (stream->main_data) {
+#if !defined(TARGET_LPC1768)
     free(stream->main_data);
+#endif
     stream->main_data = 0;
   }
 
diff -r 7c923cbe9f1d -r f28cf0afd021 timer.cpp
--- a/timer.cpp	Fri Nov 26 13:05:34 2010 +0000
+++ b/timer.cpp	Sat Nov 27 17:27:33 2010 +0000
@@ -25,10 +25,6 @@
 
 # include <stdio.h>
 
-# ifdef HAVE_ASSERT_H
-#  include <assert.h>
-# endif
-
 # include "timer.h"
 
 mad_timer_t const mad_timer_zero = { 0, 0 };