Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 2:f28cf0afd021, committed 2010-11-27
- 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
--- 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
--- 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
}
--- 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;
--- 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;
}
}
}
--- 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)
--- 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
--- 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),
--- /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));
+ }
+}
--- 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;
-}
-
-
--- 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;
}
--- 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 };