author | harlekin <harlekin> | 2002-04-19 16:08:55 (UTC) |
---|---|---|
committer | harlekin <harlekin> | 2002-04-19 16:08:55 (UTC) |
commit | 7ea4abeb652e6787e57a938e1ca028d25fd249ce (patch) (side-by-side diff) | |
tree | ee08f2d9d6aaa8adb1c5f07f4124da8a61eb8cd5 | |
parent | caa7ced77b9014526607f9f65c58aabe7e0ba631 (diff) | |
download | opie-7ea4abeb652e6787e57a938e1ca028d25fd249ce.zip opie-7ea4abeb652e6787e57a938e1ca028d25fd249ce.tar.gz opie-7ea4abeb652e6787e57a938e1ca028d25fd249ce.tar.bz2 |
new libmad version, less cpu usage
30 files changed, 625 insertions, 401 deletions
diff --git a/core/multimedia/opieplayer/libmad/COPYRIGHT b/core/multimedia/opieplayer/libmad/COPYRIGHT new file mode 100644 index 0000000..f30a707 --- a/dev/null +++ b/core/multimedia/opieplayer/libmad/COPYRIGHT @@ -0,0 +1,21 @@ + + libmad - MPEG audio decoder library + Copyright (C) 2000-2001 Robert Leslie + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + If you would like to negotiate alternate licensing terms, you may do + so by contacting the author: Robert Leslie <rob@mars.org> + diff --git a/core/multimedia/opieplayer/libmad/D.dat b/core/multimedia/opieplayer/libmad/D.dat index f33d30c..c3ee74c 100644 --- a/core/multimedia/opieplayer/libmad/D.dat +++ b/core/multimedia/opieplayer/libmad/D.dat @@ -1,50 +1,50 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ /* * These are the coefficients for the subband synthesis window. This is a * reordered version of Table B.3 from ISO/IEC 11172-3. * * Every value is parameterized so that shift optimizations can be made at * compile-time. For example, every value can be right-shifted 12 bits to * minimize multiply instruction times without any loss of accuracy. */ { PRESHIFT(0x00000000) /* 0.000000000 */, /* 0 */ -PRESHIFT(0x0001d000) /* -0.000442505 */, PRESHIFT(0x000d5000) /* 0.003250122 */, -PRESHIFT(0x001cb000) /* -0.007003784 */, PRESHIFT(0x007f5000) /* 0.031082153 */, -PRESHIFT(0x01421000) /* -0.078628540 */, PRESHIFT(0x019ae000) /* 0.100311279 */, -PRESHIFT(0x09271000) /* -0.572036743 */, PRESHIFT(0x1251e000) /* 1.144989014 */, PRESHIFT(0x09271000) /* 0.572036743 */, PRESHIFT(0x019ae000) /* 0.100311279 */, PRESHIFT(0x01421000) /* 0.078628540 */, PRESHIFT(0x007f5000) /* 0.031082153 */, PRESHIFT(0x001cb000) /* 0.007003784 */, PRESHIFT(0x000d5000) /* 0.003250122 */, PRESHIFT(0x0001d000) /* 0.000442505 */, PRESHIFT(0x00000000) /* 0.000000000 */, -PRESHIFT(0x0001d000) /* -0.000442505 */, PRESHIFT(0x000d5000) /* 0.003250122 */, diff --git a/core/multimedia/opieplayer/libmad/bit.c b/core/multimedia/opieplayer/libmad/bit.c index 2466c5f..4a4661b 100644 --- a/core/multimedia/opieplayer/libmad/bit.c +++ b/core/multimedia/opieplayer/libmad/bit.c @@ -1,50 +1,50 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # ifdef HAVE_LIMITS_H # include <limits.h> # else # define CHAR_BIT 8 # endif # include "bit.h" /* * This is the lookup table for computing the CRC-check word. * As described in section 2.4.3.1 and depicted in Figure A.9 * of ISO/IEC 11172-3, the generator polynomial is: * * G(X) = X^16 + X^15 + X^2 + 1 */ static unsigned short const crc_table[256] = { 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, @@ -152,69 +152,86 @@ unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len) /* remaining bits in current byte */ value = bitptr->cache & ((1 << bitptr->left) - 1); len -= bitptr->left; bitptr->byte++; bitptr->left = CHAR_BIT; /* more bytes */ while (len >= CHAR_BIT) { value = (value << CHAR_BIT) | *bitptr->byte++; len -= CHAR_BIT; } if (len > 0) { bitptr->cache = *bitptr->byte; value = (value << len) | (bitptr->cache >> (CHAR_BIT - len)); bitptr->left -= len; } return value; } # if 0 /* * NAME: bit->write() * DESCRIPTION: write an arbitrary number of bits */ void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len, unsigned long value) { unsigned char *ptr; ptr = (unsigned char *) bitptr->byte; /* ... */ } # endif /* * NAME: bit->crc() * DESCRIPTION: compute CRC-check word */ unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len, unsigned short init) { - register unsigned int crc, data; + register unsigned int crc; -# if CHAR_BIT == 8 - for (crc = init; len >= 8; len -= 8) { - crc = (crc << 8) ^ - crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + for (crc = init; len >= 32; len -= 32) { + register unsigned long data; + + data = mad_bit_read(&bitptr, 32); + + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 24)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 16)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 8)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 0)) & 0xff]; + } + + switch (len / 8) { + case 3: crc = (crc << 8) ^ + crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + case 2: crc = (crc << 8) ^ + crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + case 1: crc = (crc << 8) ^ + crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; + + len %= 8; + + case 0: break; } -# else - crc = init; -# endif while (len--) { - data = mad_bit_read(&bitptr, 1) ^ (crc >> 15); + register unsigned int msb; + + msb = mad_bit_read(&bitptr, 1) ^ (crc >> 15); crc <<= 1; - if (data & 1) + if (msb & 1) crc ^= CRC_POLY; } return crc & 0xffff; } diff --git a/core/multimedia/opieplayer/libmad/bit.h b/core/multimedia/opieplayer/libmad/bit.h index f315bc9..3448d40 100644 --- a/core/multimedia/opieplayer/libmad/bit.h +++ b/core/multimedia/opieplayer/libmad/bit.h @@ -1,47 +1,47 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_BIT_H # define LIBMAD_BIT_H struct mad_bitptr { unsigned char const *byte; unsigned short cache; unsigned short left; }; void mad_bit_init(struct mad_bitptr *, unsigned char const *); # define mad_bit_finish(bitptr) /* nothing */ unsigned int mad_bit_length(struct mad_bitptr const *, struct mad_bitptr const *); # define mad_bit_bitsleft(bitptr) ((bitptr)->left) unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); void mad_bit_skip(struct mad_bitptr *, unsigned int); unsigned long mad_bit_read(struct mad_bitptr *, unsigned int); void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long); unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short); # endif diff --git a/core/multimedia/opieplayer/libmad/decoder.c b/core/multimedia/opieplayer/libmad/decoder.c index dcf7cf3..b2b6cbb 100644 --- a/core/multimedia/opieplayer/libmad/decoder.c +++ b/core/multimedia/opieplayer/libmad/decoder.c @@ -1,196 +1,201 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H -# include "libmad_config.h" -# else -# ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -# endif -# ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -# endif +# include "libmad_config.h" # endif # include "libmad_global.h" -# include <sys/types.h> +# ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +# endif # ifdef HAVE_SYS_WAIT_H # include <sys/wait.h> # endif # ifdef HAVE_UNISTD_H # include <unistd.h> # endif -# include <fcntl.h> +# ifdef HAVE_FCNTL_H +# include <fcntl.h> +# endif + # include <stdlib.h> -# include <errno.h> + +# ifdef HAVE_ERRNO_H +# include <errno.h> +# endif # include "stream.h" # include "frame.h" # include "synth.h" # include "decoder.h" void mad_decoder_init(struct mad_decoder *decoder, void *data, - enum mad_flow (*input_func)(void *, struct mad_stream *), + enum mad_flow (*input_func)(void *, + struct mad_stream *), enum mad_flow (*header_func)(void *, struct mad_header const *), - enum mad_flow (*filter_func)(void *, struct mad_frame *), + enum mad_flow (*filter_func)(void *, + struct mad_stream const *, + struct mad_frame *), enum mad_flow (*output_func)(void *, struct mad_header const *, struct mad_pcm *), - enum mad_flow (*error_func)(void *, struct mad_stream *, + enum mad_flow (*error_func)(void *, + struct mad_stream *, struct mad_frame *), enum mad_flow (*message_func)(void *, void *, unsigned int *)) { decoder->mode = -1; decoder->options = 0; decoder->async.pid = 0; decoder->async.in = -1; decoder->async.out = -1; decoder->sync = 0; decoder->cb_data = data; decoder->input_func = input_func; decoder->header_func = header_func; decoder->filter_func = filter_func; decoder->output_func = output_func; decoder->error_func = error_func; decoder->message_func = message_func; } 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 { + 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 { + 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 { + 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)); @@ -236,319 +241,330 @@ enum mad_flow receive(int fd, void **message, unsigned int *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, struct mad_frame *frame) { int *bad_last_frame = data; switch (stream->error) { case MAD_ERROR_BADCRC: if (*bad_last_frame) mad_frame_mute(frame); else *bad_last_frame = 1; return MAD_FLOW_IGNORE; default: return MAD_FLOW_CONTINUE; } } static int run_sync(struct mad_decoder *decoder) { enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); void *error_data; int bad_last_frame = 0; struct mad_stream *stream; struct mad_frame *frame; struct mad_synth *synth; int result = 0; if (decoder->input_func == 0) return 0; if (decoder->error_func) { error_func = decoder->error_func; error_data = decoder->cb_data; } else { error_func = error_default; error_data = &bad_last_frame; } stream = &decoder->sync->stream; frame = &decoder->sync->frame; synth = &decoder->sync->synth; mad_stream_init(stream); mad_frame_init(frame); mad_synth_init(synth); mad_stream_options(stream, decoder->options); do { switch (decoder->input_func(decoder->cb_data, stream)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: continue; case MAD_FLOW_CONTINUE: break; } 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)) break; switch (error_func(error_data, stream, frame)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: case MAD_FLOW_CONTINUE: default: continue; } } switch (decoder->header_func(decoder->cb_data, &frame->header)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: continue; case MAD_FLOW_CONTINUE: break; } } if (mad_frame_decode(frame, stream) == -1) { if (!MAD_RECOVERABLE(stream->error)) break; switch (error_func(error_data, stream, frame)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: break; case MAD_FLOW_CONTINUE: default: continue; } } else bad_last_frame = 0; if (decoder->filter_func) { - switch (decoder->filter_func(decoder->cb_data, frame)) { + switch (decoder->filter_func(decoder->cb_data, stream, frame)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: continue; case MAD_FLOW_CONTINUE: break; } } mad_synth_frame(synth, frame); if (decoder->output_func) { switch (decoder->output_func(decoder->cb_data, &frame->header, &synth->pcm)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: case MAD_FLOW_CONTINUE: break; } } } } while (stream->error == MAD_ERROR_BUFLEN); fail: result = -1; done: mad_synth_finish(synth); mad_frame_finish(frame); mad_stream_finish(stream); 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 int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode) { int result; int (*run)(struct mad_decoder *) = 0; switch (decoder->mode = mode) { case MAD_DECODER_MODE_SYNC: run = run_sync; break; case MAD_DECODER_MODE_ASYNC: +# if defined(USE_ASYNC) run = run_async; +# endif break; } if (run == 0) return -1; decoder->sync = malloc(sizeof(*decoder->sync)); if (decoder->sync == 0) return -1; result = run(decoder); free(decoder->sync); decoder->sync = 0; return result; } 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 --git a/core/multimedia/opieplayer/libmad/decoder.h b/core/multimedia/opieplayer/libmad/decoder.h index dbacc1a..f34150d 100644 --- a/core/multimedia/opieplayer/libmad/decoder.h +++ b/core/multimedia/opieplayer/libmad/decoder.h @@ -1,87 +1,91 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_DECODER_H # define LIBMAD_DECODER_H # include "stream.h" # include "frame.h" # include "synth.h" enum mad_decoder_mode { MAD_DECODER_MODE_SYNC = 0, MAD_DECODER_MODE_ASYNC }; enum mad_flow { - MAD_FLOW_CONTINUE = 0x0000, - MAD_FLOW_STOP = 0x0010, - MAD_FLOW_BREAK = 0x0011, - MAD_FLOW_IGNORE = 0x0020 + MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ + MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ + MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ + MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ }; struct mad_decoder { enum mad_decoder_mode mode; int options; struct { long pid; int in; int out; } async; struct { struct mad_stream stream; struct mad_frame frame; struct mad_synth synth; } *sync; void *cb_data; enum mad_flow (*input_func)(void *, struct mad_stream *); enum mad_flow (*header_func)(void *, struct mad_header const *); - enum mad_flow (*filter_func)(void *, struct mad_frame *); + enum mad_flow (*filter_func)(void *, + struct mad_stream const *, struct mad_frame *); enum mad_flow (*output_func)(void *, struct mad_header const *, struct mad_pcm *); enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); enum mad_flow (*message_func)(void *, void *, unsigned int *); }; void mad_decoder_init(struct mad_decoder *, void *, enum mad_flow (*)(void *, struct mad_stream *), enum mad_flow (*)(void *, struct mad_header const *), - enum mad_flow (*)(void *, struct mad_frame *), + enum mad_flow (*)(void *, + struct mad_stream const *, + struct mad_frame *), enum mad_flow (*)(void *, struct mad_header const *, struct mad_pcm *), enum mad_flow (*)(void *, struct mad_stream *, struct mad_frame *), enum mad_flow (*)(void *, void *, unsigned int *)); int mad_decoder_finish(struct mad_decoder *); -# define mad_decoder_options(decoder, opts) ((decoder)->options = (opts)) +# define mad_decoder_options(decoder, opts) \ + ((void) ((decoder)->options = (opts))) int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode); int mad_decoder_message(struct mad_decoder *, void *, unsigned int *); # endif diff --git a/core/multimedia/opieplayer/libmad/fixed.c b/core/multimedia/opieplayer/libmad/fixed.c index be5c94e..af1e87e 100644 --- a/core/multimedia/opieplayer/libmad/fixed.c +++ b/core/multimedia/opieplayer/libmad/fixed.c @@ -1,37 +1,37 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # include "fixed.h" /* * NAME: fixed->abs() * DESCRIPTION: return absolute value of a fixed-point number */ mad_fixed_t mad_f_abs(mad_fixed_t x) { return x < 0 ? -x : x; } diff --git a/core/multimedia/opieplayer/libmad/fixed.h b/core/multimedia/opieplayer/libmad/fixed.h index 00ade62..c9b98ca 100644 --- a/core/multimedia/opieplayer/libmad/fixed.h +++ b/core/multimedia/opieplayer/libmad/fixed.h @@ -1,267 +1,321 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_FIXED_H # define LIBMAD_FIXED_H # if SIZEOF_INT >= 4 typedef signed int mad_fixed_t; typedef signed int mad_fixed64hi_t; typedef unsigned int mad_fixed64lo_t; # else typedef signed long mad_fixed_t; typedef signed long mad_fixed64hi_t; typedef unsigned long mad_fixed64lo_t; # endif +# if defined(_MSC_VER) +# define mad_fixed64_t signed __int64 +# elif 1 || defined(__GNUC__) +# define mad_fixed64_t signed long long +# endif + +# if defined(FPM_FLOAT) +typedef double mad_sample_t; +# else +typedef mad_fixed_t mad_sample_t; +# endif + /* * Fixed-point format: 0xABBBBBBB * A == whole part (sign + 3 bits) * B == fractional part (28 bits) * * Values are signed two's complement, so the effective range is: * 0x80000000 to 0x7fffffff * -8.0 to +7.9999999962747097015380859375 * * The smallest representable value is: * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) * * 28 bits of fractional accuracy represent about * 8.6 digits of decimal accuracy. * * Fixed-point numbers can be added or subtracted as normal * integers, but multiplication requires shifting the 64-bit result * from 56 fractional bits back to 28 (and rounding.) * * Changing the definition of MAD_F_FRACBITS is only partially * supported, and must be done with care. */ # define MAD_F_FRACBITS 28 # if MAD_F_FRACBITS == 28 # define MAD_F(x) ((mad_fixed_t) (x##L)) # else # if MAD_F_FRACBITS < 28 # warning "MAD_F_FRACBITS < 28" # define MAD_F(x) ((mad_fixed_t) \ (((x##L) + \ (1L << (28 - MAD_F_FRACBITS - 1))) >> \ (28 - MAD_F_FRACBITS))) # elif MAD_F_FRACBITS > 28 # error "MAD_F_FRACBITS > 28 not currently supported" # define MAD_F(x) ((mad_fixed_t) \ ((x##L) << (MAD_F_FRACBITS - 28))) # endif # endif # define MAD_F_MIN ((mad_fixed_t) -0x80000000L) # define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL) # define MAD_F_ONE MAD_F(0x10000000) # define mad_f_tofixed(x) ((mad_fixed_t) \ ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5)) # define mad_f_todouble(x) ((double) \ ((x) / (double) (1L << MAD_F_FRACBITS))) # define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS) # define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1)) /* (x should be positive) */ # define mad_f_fromint(x) ((x) << MAD_F_FRACBITS) # define mad_f_add(x, y) ((x) + (y)) # define mad_f_sub(x, y) ((x) - (y)) -# if defined(FPM_64BIT) +# if defined(FPM_FLOAT) +# error "FPM_FLOAT not yet supported" + +# undef MAD_F +# define MAD_F(x) mad_f_todouble(x) + +# define mad_f_mul(x, y) ((x) * (y)) +# define mad_f_scale64 + +# undef ASO_ZEROCHECK + +# elif defined(FPM_64BIT) /* - * This version should be the most accurate if 64-bit (long long) types are - * supported by the compiler, although it may not be the most efficient. + * This version should be the most accurate if 64-bit types are supported by + * the compiler, although it may not be the most efficient. */ # if defined(OPT_ACCURACY) # define mad_f_mul(x, y) \ ((mad_fixed_t) \ - ((((signed long long) (x) * (y)) + \ + ((((mad_fixed64_t) (x) * (y)) + \ (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS)) # else # define mad_f_mul(x, y) \ - ((mad_fixed_t) (((signed long long) (x) * (y)) >> MAD_F_SCALEBITS)) + ((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS)) # endif # define MAD_F_SCALEBITS MAD_F_FRACBITS /* --- Intel --------------------------------------------------------------- */ # elif defined(FPM_INTEL) +# if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4035) /* no return value */ +static __forceinline +mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) +{ + enum { + fracbits = MAD_F_FRACBITS + }; + + __asm { + mov eax, x + imul y + shrd eax, edx, fracbits + } + + /* implicit return of eax */ +} +# pragma warning(pop) + +# define mad_f_mul mad_f_mul_inline +# define mad_f_scale64 +# else /* * This Intel version is fast and accurate; the disposition of the least * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ -# define MAD_F_MLX(hi, lo, x, y) \ +# define MAD_F_MLX(hi, lo, x, y) \ asm ("imull %3" \ : "=a" (lo), "=d" (hi) \ : "%a" (x), "rm" (y) \ : "cc") -# if defined(OPT_ACCURACY) +# if defined(OPT_ACCURACY) /* * This gives best accuracy but is not very fast. */ -# define MAD_F_MLA(hi, lo, x, y) \ +# define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ MAD_F_MLX(__hi, __lo, (x), (y)); \ asm ("addl %2,%0\n\t" \ "adcl %3,%1" \ : "=rm" (lo), "=rm" (hi) \ : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \ : "cc"); \ }) -# endif /* OPT_ACCURACY */ +# endif /* OPT_ACCURACY */ -# if defined(OPT_ACCURACY) +# if defined(OPT_ACCURACY) /* * Surprisingly, this is faster than SHRD followed by ADC. */ -# define mad_f_scale64(hi, lo) \ +# define mad_f_scale64(hi, lo) \ ({ mad_fixed64hi_t __hi_; \ mad_fixed64lo_t __lo_; \ mad_fixed_t __result; \ asm ("addl %4,%2\n\t" \ "adcl %5,%3" \ : "=rm" (__lo_), "=rm" (__hi_) \ : "0" (lo), "1" (hi), \ "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \ : "cc"); \ asm ("shrdl %3,%2,%1" \ : "=rm" (__result) \ : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) -# else -# define mad_f_scale64(hi, lo) \ +# else +# define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("shrdl %3,%2,%1" \ : "=rm" (__result) \ : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) -# endif /* OPT_ACCURACY */ +# endif /* OPT_ACCURACY */ -# define MAD_F_SCALEBITS MAD_F_FRACBITS +# define MAD_F_SCALEBITS MAD_F_FRACBITS +# endif /* --- ARM ----------------------------------------------------------------- */ # elif defined(FPM_ARM) /* * This ARM V4 version is as accurate as FPM_64BIT but much faster. The * least significant bit is properly rounded at no CPU cycle cost! */ # if 1 /* * There's a bug somewhere, possibly in the compiler, that sometimes makes * this necessary instead of the default implementation via MAD_F_MLX and * mad_f_scale64. It may be related to the use (or lack) of * -finline-functions and/or -fstrength-reduce. * * This is also apparently faster than MAD_F_MLX/mad_f_scale64. */ # define mad_f_mul(x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ mad_fixed_t __result; \ asm ("smull %0, %1, %3, %4\n\t" \ "movs %0, %0, lsr %5\n\t" \ "adc %2, %0, %1, lsl %6" \ : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ : "%r" (x), "r" (y), \ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # endif # define MAD_F_MLX(hi, lo, x, y) \ asm ("smull %0, %1, %2, %3" \ : "=&r" (lo), "=&r" (hi) \ : "%r" (x), "r" (y)) # define MAD_F_MLA(hi, lo, x, y) \ asm ("smlal %0, %1, %2, %3" \ : "+r" (lo), "+r" (hi) \ : "%r" (x), "r" (y)) +# define MAD_F_MLN(hi, lo) \ + asm ("rsbs %0, %2, #0\n\t" \ + "rsc %1, %3, #0" \ + : "=r" (lo), "=r" (hi) \ + : "0" (lo), "1" (hi) \ + : "cc") + # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("movs %0, %1, lsr %3\n\t" \ "adc %0, %0, %2, lsl %4" \ : "=r" (__result) \ : "r" (lo), "r" (hi), \ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # define MAD_F_SCALEBITS MAD_F_FRACBITS /* --- MIPS ---------------------------------------------------------------- */ # elif defined(FPM_MIPS) /* * This MIPS version is fast and accurate; the disposition of the least * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ # define MAD_F_MLX(hi, lo, x, y) \ asm ("mult %2,%3" \ : "=l" (lo), "=h" (hi) \ : "%r" (x), "r" (y)) # if defined(HAVE_MADD_ASM) # define MAD_F_MLA(hi, lo, x, y) \ asm ("madd %2,%3" \ : "+l" (lo), "+h" (hi) \ : "%r" (x), "r" (y)) # elif defined(HAVE_MADD16_ASM) /* * This loses significant accuracy due to the 16-bit integer limit in the * multiply/accumulate instruction. */ # define MAD_F_ML0(hi, lo, x, y) \ asm ("mult %2,%3" \ : "=l" (lo), "=h" (hi) \ : "%r" ((x) >> 12), "r" ((y) >> 16)) # define MAD_F_MLA(hi, lo, x, y) \ asm ("madd16 %2,%3" \ : "+l" (lo), "+h" (hi) \ : "%r" ((x) >> 12), "r" ((y) >> 16)) # define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo)) # endif # if defined(OPT_SPEED) @@ -312,102 +366,111 @@ typedef unsigned long mad_fixed64lo_t; # if defined(OPT_ACCURACY) /* * This is accurate and ~2 - 2.5 times slower than the unrounded version. * * The __volatile__ improves the generated code by another 5% (fewer spills * to memory); eventually they should be removed. */ # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ mad_fixed64hi_t __hi_; \ mad_fixed64lo_t __lo_; \ asm __volatile__ ("addc %0, %2, %4\n\t" \ "addze %1, %3" \ : "=r" (__lo_), "=r" (__hi_) \ : "r" (lo), "r" (hi), "r" (1 << (MAD_F_SCALEBITS - 1))); \ asm __volatile__ ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \ "rlwimi %0, %1,32-%3,%3,31" \ : "=&r" (__result) \ : "r" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)); \ __result; \ }) # else # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \ "rlwimi %0, %1,32-%3,%3,31" \ : "=r" (__result) \ : "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \ __result; \ }) # endif /* OPT_ACCURACY */ # define MAD_F_SCALEBITS MAD_F_FRACBITS /* --- Default ------------------------------------------------------------- */ # elif defined(FPM_DEFAULT) /* * This version is the most portable but it loses significant accuracy. * Furthermore, accuracy is biased against the second argument, so care * should be taken when ordering operands. * * The scale factors are constant as this is not used with SSO. * * Pre-rounding is required to stay within the limits of compliance. */ -# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ +# if defined(OPT_SPEED) +# define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16)) +# else +# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ (((y) + (1L << 15)) >> 16)) +# endif /* ------------------------------------------------------------------------- */ # else # error "no FPM selected" # endif /* default implementations */ # if !defined(mad_f_mul) # define mad_f_mul(x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ MAD_F_MLX(__hi, __lo, (x), (y)); \ mad_f_scale64(__hi, __lo); \ }) # endif # if !defined(MAD_F_MLA) # define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y))) # define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y))) +# define MAD_F_MLN(hi, lo) ((lo) = -(lo)) # define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) # endif # if !defined(MAD_F_ML0) # define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y)) # endif +# if !defined(MAD_F_MLN) +# define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi)) +# endif + # if !defined(MAD_F_MLZ) # define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo)) # endif # if !defined(mad_f_scale64) # if defined(OPT_ACCURACY) # define mad_f_scale64(hi, lo) \ ((((mad_fixed_t) \ (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \ ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1) # else # define mad_f_scale64(hi, lo) \ ((mad_fixed_t) \ (((hi) << (32 - MAD_F_SCALEBITS)) | \ ((lo) >> MAD_F_SCALEBITS))) # endif # define MAD_F_SCALEBITS MAD_F_FRACBITS # endif /* miscellaneous C routines */ mad_fixed_t mad_f_abs(mad_fixed_t); # endif diff --git a/core/multimedia/opieplayer/libmad/frame.c b/core/multimedia/opieplayer/libmad/frame.c index 4ebb80c..bf15e7f 100644 --- a/core/multimedia/opieplayer/libmad/frame.c +++ b/core/multimedia/opieplayer/libmad/frame.c @@ -1,50 +1,50 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # include <stdlib.h> # include "bit.h" # include "stream.h" # include "frame.h" # include "timer.h" # include "layer12.h" # include "layer3.h" static unsigned long const bitrate_table[5][15] = { /* MPEG-1 */ { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */ 256000, 288000, 320000, 352000, 384000, 416000, 448000 }, { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */ 128000, 160000, 192000, 224000, 256000, 320000, 384000 }, { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */ 112000, 128000, 160000, 192000, 224000, 256000, 320000 }, /* MPEG-2 LSF */ { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */ 128000, 144000, 160000, 176000, 192000, 224000, 256000 }, { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */ @@ -328,97 +328,97 @@ int mad_header_decode(struct mad_header *header, struct mad_stream *stream) sync: /* synchronize */ if (stream->sync) { if (end - ptr < MAD_BUFFER_GUARD) { stream->next_frame = ptr; stream->error = MAD_ERROR_BUFLEN; goto fail; } else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { /* mark point where frame sync word was expected */ stream->this_frame = ptr; stream->next_frame = ptr + 1; stream->error = MAD_ERROR_LOSTSYNC; goto fail; } } else { mad_bit_init(&stream->ptr, ptr); if (mad_stream_sync(stream) == -1) { if (end - stream->next_frame >= MAD_BUFFER_GUARD) stream->next_frame = end - MAD_BUFFER_GUARD; stream->error = MAD_ERROR_BUFLEN; goto fail; } ptr = mad_bit_nextbyte(&stream->ptr); } /* begin processing */ stream->this_frame = ptr; stream->next_frame = ptr + 1; /* possibly bogus sync word */ mad_bit_init(&stream->ptr, stream->this_frame); if (decode_header(header, stream) == -1) goto fail; /* calculate frame duration */ mad_timer_set(&header->duration, 0, 32 * MAD_NSBSAMPLES(header), header->samplerate); /* calculate free bit rate */ if (header->bitrate == 0) { - if ((!stream->sync || !stream->freerate) && + if ((stream->freerate == 0 || !stream->sync) && free_bitrate(stream, header) == -1) goto fail; header->bitrate = stream->freerate; header->flags |= MAD_FLAG_FREEFORMAT; } /* calculate beginning of next frame */ pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; if (header->layer == MAD_LAYER_I) N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4; else { unsigned int slots_per_frame; slots_per_frame = (header->layer == MAD_LAYER_III && (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot; } /* verify there is enough data left in buffer to decode this frame */ if (N + MAD_BUFFER_GUARD > end - stream->this_frame) { stream->next_frame = stream->this_frame; stream->error = MAD_ERROR_BUFLEN; goto fail; } stream->next_frame = stream->this_frame + N; if (!stream->sync) { /* check that a valid frame header follows this frame */ ptr = stream->next_frame; if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { ptr = stream->next_frame = stream->this_frame + 1; goto sync; } stream->sync = 1; } header->flags |= MAD_FLAG_INCOMPLETE; return 0; fail: diff --git a/core/multimedia/opieplayer/libmad/frame.h b/core/multimedia/opieplayer/libmad/frame.h index e88d0c8..3b8e454 100644 --- a/core/multimedia/opieplayer/libmad/frame.h +++ b/core/multimedia/opieplayer/libmad/frame.h @@ -1,115 +1,117 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_FRAME_H # define LIBMAD_FRAME_H # include "fixed.h" # include "timer.h" # include "stream.h" enum mad_layer { MAD_LAYER_I = 1, /* Layer I */ MAD_LAYER_II = 2, /* Layer II */ MAD_LAYER_III = 3 /* Layer III */ }; enum mad_mode { MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ MAD_MODE_STEREO = 3 /* normal LR stereo */ }; enum mad_emphasis { MAD_EMPHASIS_NONE = 0, /* no emphasis */ MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */ }; -struct mad_frame { - struct mad_header { - enum mad_layer layer; /* audio layer (1, 2, or 3) */ - enum mad_mode mode; /* channel mode (see above) */ - int mode_extension; /* additional mode info */ - enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ +struct mad_header { + enum mad_layer layer; /* audio layer (1, 2, or 3) */ + enum mad_mode mode; /* channel mode (see above) */ + int mode_extension; /* additional mode info */ + enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ + + unsigned long bitrate; /* stream bitrate (bps) */ + unsigned int samplerate; /* sampling frequency (Hz) */ - unsigned long bitrate; /* stream bitrate (bps) */ - unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned short crc_check; /* frame CRC accumulator */ + unsigned short crc_target; /* final target CRC checksum */ - unsigned short crc_check; /* frame CRC accumulator */ - unsigned short crc_target; /* final target CRC checksum */ + int flags; /* flags (see below) */ + int private_bits; /* private bits (see below) */ - int flags; /* flags (see below) */ - int private_bits; /* private bits (see below) */ + mad_timer_t duration; /* audio playing time of frame */ +}; - mad_timer_t duration; /* audio playing time of frame */ - } header; +struct mad_frame { + struct mad_header header; /* MPEG audio header */ 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 */ }; # define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) # define MAD_NSBSAMPLES(header) \ ((header)->layer == MAD_LAYER_I ? 12 : \ (((header)->layer == MAD_LAYER_III && \ ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) enum { - MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ - MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ + MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ + MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ - MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ - MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ - MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ - MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ + MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ + MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ + MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ + MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ - MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ - MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ - MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ + MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ + MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ + MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ - MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ - MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ - MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ + MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ + MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ + MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ }; enum { - MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ - MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ + MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ + MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ }; void mad_header_init(struct mad_header *); # define mad_header_finish(header) /* nothing */ int mad_header_decode(struct mad_header *, struct mad_stream *); void mad_frame_init(struct mad_frame *); void mad_frame_finish(struct mad_frame *); int mad_frame_decode(struct mad_frame *, struct mad_stream *); void mad_frame_mute(struct mad_frame *); # endif diff --git a/core/multimedia/opieplayer/libmad/huffman.c b/core/multimedia/opieplayer/libmad/huffman.c index 8ec9499..5ea6547 100644 --- a/core/multimedia/opieplayer/libmad/huffman.c +++ b/core/multimedia/opieplayer/libmad/huffman.c @@ -1,152 +1,163 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # include "huffman.h" /* * These are the Huffman code words for Layer III. * The data for these tables are derived from Table B.7 of ISO/IEC 11172-3. * * These tables support decoding up to 4 Huffman code bits at a time. */ -# define V(v, w, x, y, hlen) { { 1, hlen, v, w, x, y } } -# define PTR(offs, bits) { ptr: { 0, bits, offs } } +# if defined(__GNUC__) +# define PTR(offs, bits) { ptr: { 0, bits, offs } } +# define V(v, w, x, y, hlen) { value: { 1, hlen, v, w, x, y } } +# else +# define PTR(offs, bits) { { 0, bits, offs } } +# define V(v, w, x, y, hlen) { { 1, hlen, (v << 0) | (w << 1) | \ + (x << 2) | (y << 3) } } +# endif static union huffquad const hufftabA[] = { /* 0000 */ PTR(16, 2), /* 0001 */ PTR(20, 2), /* 0010 */ PTR(24, 1), /* 0011 */ PTR(26, 1), /* 0100 */ V(0, 0, 1, 0, 4), /* 0101 */ V(0, 0, 0, 1, 4), /* 0110 */ V(0, 1, 0, 0, 4), /* 0111 */ V(1, 0, 0, 0, 4), /* 1000 */ V(0, 0, 0, 0, 1), /* 1001 */ V(0, 0, 0, 0, 1), /* 1010 */ V(0, 0, 0, 0, 1), /* 1011 */ V(0, 0, 0, 0, 1), /* 1100 */ V(0, 0, 0, 0, 1), /* 1101 */ V(0, 0, 0, 0, 1), /* 1110 */ V(0, 0, 0, 0, 1), /* 1111 */ V(0, 0, 0, 0, 1), /* 0000 ... */ /* 00 */ V(1, 0, 1, 1, 2), /* 16 */ /* 01 */ V(1, 1, 1, 1, 2), /* 10 */ V(1, 1, 0, 1, 2), /* 11 */ V(1, 1, 1, 0, 2), /* 0001 ... */ /* 00 */ V(0, 1, 1, 1, 2), /* 20 */ /* 01 */ V(0, 1, 0, 1, 2), /* 10 */ V(1, 0, 0, 1, 1), /* 11 */ V(1, 0, 0, 1, 1), /* 0010 ... */ /* 0 */ V(0, 1, 1, 0, 1), /* 24 */ /* 1 */ V(0, 0, 1, 1, 1), /* 0011 ... */ /* 0 */ V(1, 0, 1, 0, 1), /* 26 */ /* 1 */ V(1, 1, 0, 0, 1) }; static union huffquad const hufftabB[] = { /* 0000 */ V(1, 1, 1, 1, 4), /* 0001 */ V(1, 1, 1, 0, 4), /* 0010 */ V(1, 1, 0, 1, 4), /* 0011 */ V(1, 1, 0, 0, 4), /* 0100 */ V(1, 0, 1, 1, 4), /* 0101 */ V(1, 0, 1, 0, 4), /* 0110 */ V(1, 0, 0, 1, 4), /* 0111 */ V(1, 0, 0, 0, 4), /* 1000 */ V(0, 1, 1, 1, 4), /* 1001 */ V(0, 1, 1, 0, 4), /* 1010 */ V(0, 1, 0, 1, 4), /* 1011 */ V(0, 1, 0, 0, 4), /* 1100 */ V(0, 0, 1, 1, 4), /* 1101 */ V(0, 0, 1, 0, 4), /* 1110 */ V(0, 0, 0, 1, 4), /* 1111 */ V(0, 0, 0, 0, 4) }; # undef V # undef PTR -# define V(x, y, hlen) { { 1, hlen, x, y } } -# define PTR(offs, bits) { ptr: { 0, bits, offs } } +# if defined(__GNUC__) +# define PTR(offs, bits) { ptr: { 0, bits, offs } } +# define V(x, y, hlen) { value: { 1, hlen, x, y } } +# else +# define PTR(offs, bits) { { 0, bits, offs } } +# define V(x, y, hlen) { { 1, hlen, (x << 0) | (y << 4) } } +# endif static union huffpair const hufftab0[] = { /* */ V(0, 0, 0) }; static union huffpair const hufftab1[] = { /* 000 */ V(1, 1, 3), /* 001 */ V(0, 1, 3), /* 010 */ V(1, 0, 2), /* 011 */ V(1, 0, 2), /* 100 */ V(0, 0, 1), /* 101 */ V(0, 0, 1), /* 110 */ V(0, 0, 1), /* 111 */ V(0, 0, 1) }; static union huffpair const hufftab2[] = { /* 000 */ PTR(8, 3), /* 001 */ V(1, 1, 3), /* 010 */ V(0, 1, 3), /* 011 */ V(1, 0, 3), /* 100 */ V(0, 0, 1), /* 101 */ V(0, 0, 1), /* 110 */ V(0, 0, 1), /* 111 */ V(0, 0, 1), /* 000 ... */ /* 000 */ V(2, 2, 3), /* 8 */ /* 001 */ V(0, 2, 3), /* 010 */ V(1, 2, 2), /* 011 */ V(1, 2, 2), /* 100 */ V(2, 1, 2), /* 101 */ V(2, 1, 2), /* 110 */ V(2, 0, 2), /* 111 */ V(2, 0, 2) }; static union huffpair const hufftab3[] = { /* 000 */ PTR(8, 3), /* 001 */ V(1, 0, 3), /* 010 */ V(1, 1, 2), /* 011 */ V(1, 1, 2), /* 100 */ V(0, 1, 2), /* 101 */ V(0, 1, 2), diff --git a/core/multimedia/opieplayer/libmad/huffman.h b/core/multimedia/opieplayer/libmad/huffman.h index 1801210..d051949 100644 --- a/core/multimedia/opieplayer/libmad/huffman.h +++ b/core/multimedia/opieplayer/libmad/huffman.h @@ -1,66 +1,66 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_HUFFMAN_H # define LIBMAD_HUFFMAN_H union huffquad { struct { unsigned short final : 1; + unsigned short bits : 3; + unsigned short offset : 12; + } ptr; + struct { + unsigned short final : 1; unsigned short hlen : 3; unsigned short v : 1; unsigned short w : 1; unsigned short x : 1; unsigned short y : 1; } value; + unsigned short final : 1; +}; + +union huffpair { struct { unsigned short final : 1; unsigned short bits : 3; unsigned short offset : 12; } ptr; - unsigned short final : 1; -}; - -union huffpair { struct { unsigned short final : 1; unsigned short hlen : 3; unsigned short x : 4; unsigned short y : 4; } value; - struct { - unsigned short final : 1; - unsigned short bits : 3; - unsigned short offset : 12; - } ptr; unsigned short final : 1; }; struct hufftable { union huffpair const *table; unsigned short linbits; unsigned short startbits; }; extern union huffquad const *const mad_huff_quad_table[2]; extern struct hufftable const mad_huff_pair_table[32]; # endif diff --git a/core/multimedia/opieplayer/libmad/imdct_s.dat b/core/multimedia/opieplayer/libmad/imdct_s.dat index 00d62eb..ed70446 100644 --- a/core/multimedia/opieplayer/libmad/imdct_s.dat +++ b/core/multimedia/opieplayer/libmad/imdct_s.dat @@ -1,50 +1,50 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ /* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x0216a2a2) /* -0.130526192 */, MAD_F(0x0fdcf549) /* 0.991444861 */, -MAD_F(0x061f78aa) /* -0.382683432 */, -MAD_F(0x0cb19346) /* -0.793353340 */ }, /* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0216a2a2) /* 0.130526192 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x09bd7ca0) /* -0.608761429 */ }, /* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, MAD_F(0x0ec835e8) /* 0.923879533 */, -MAD_F(0x061f78aa) /* -0.382683432 */, -MAD_F(0x061f78aa) /* -0.382683432 */, MAD_F(0x0ec835e8) /* 0.923879533 */ }, /* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x061f78aa) /* -0.382683432 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x061f78aa) /* 0.382683432 */ }, /* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */, diff --git a/core/multimedia/opieplayer/libmad/layer12.c b/core/multimedia/opieplayer/libmad/layer12.c index 41b17ca..d291174 100644 --- a/core/multimedia/opieplayer/libmad/layer12.c +++ b/core/multimedia/opieplayer/libmad/layer12.c @@ -1,50 +1,50 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # ifdef HAVE_LIMITS_H # include <limits.h> # else # define CHAR_BIT 8 # endif # include "fixed.h" # include "bit.h" # include "stream.h" # include "frame.h" # include "layer12.h" /* * scalefactor table * used in both Layer I and Layer II decoding */ static mad_fixed_t const sf_table[63] = { # include "sf_table.dat" }; /* --- Layer I ------------------------------------------------------------- */ diff --git a/core/multimedia/opieplayer/libmad/layer12.h b/core/multimedia/opieplayer/libmad/layer12.h index d2c81ac..c673726 100644 --- a/core/multimedia/opieplayer/libmad/layer12.h +++ b/core/multimedia/opieplayer/libmad/layer12.h @@ -1,31 +1,31 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_LAYER12_H # define LIBMAD_LAYER12_H # include "stream.h" # include "frame.h" int mad_layer_I(struct mad_stream *, struct mad_frame *); int mad_layer_II(struct mad_stream *, struct mad_frame *); # endif diff --git a/core/multimedia/opieplayer/libmad/layer3.c b/core/multimedia/opieplayer/libmad/layer3.c index 194fc7e..03f13fe 100644 --- a/core/multimedia/opieplayer/libmad/layer3.c +++ b/core/multimedia/opieplayer/libmad/layer3.c @@ -1,101 +1,109 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # include <stdlib.h> # include <string.h> -# include <assert.h> + +# ifdef HAVE_ASSERT_H +# include <assert.h> +# endif # ifdef HAVE_LIMITS_H # include <limits.h> # else # define CHAR_BIT 8 # endif # include "fixed.h" # include "bit.h" # include "stream.h" # include "frame.h" # include "huffman.h" # include "layer3.h" /* --- Layer III ----------------------------------------------------------- */ enum { count1table_select = 0x01, scalefac_scale = 0x02, preflag = 0x04, mixed_block_flag = 0x08 }; +enum { + I_STEREO = 0x1, + MS_STEREO = 0x2 +}; + struct sideinfo { unsigned int main_data_begin; unsigned int private_bits; unsigned char scfsi[2]; struct granule { struct channel { /* from side info */ unsigned short part2_3_length; unsigned short big_values; unsigned short global_gain; unsigned short scalefac_compress; unsigned char flags; unsigned char block_type; unsigned char table_select[3]; unsigned char subblock_gain[3]; unsigned char region0_count; unsigned char region1_count; /* from main_data */ unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */ } ch[2]; } gr[2]; }; /* * scalefactor bit lengths * derived from section 2.4.2.7 of ISO/IEC 11172-3 */ static struct { unsigned char slen1; unsigned char slen2; } const sflen_table[16] = { { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 } }; /* * number of LSF scalefactor band values * derived from section 2.4.3.2 of ISO/IEC 13818-3 */ static unsigned char const nsfb_table[6][3][4] = { @@ -458,97 +466,97 @@ mad_fixed_t const is_table[7] = { static mad_fixed_t const is_lsf_table[2][15] = { { MAD_F(0x0d744fcd) /* 0.840896415 */, MAD_F(0x0b504f33) /* 0.707106781 */, MAD_F(0x09837f05) /* 0.594603558 */, MAD_F(0x08000000) /* 0.500000000 */, MAD_F(0x06ba27e6) /* 0.420448208 */, MAD_F(0x05a8279a) /* 0.353553391 */, MAD_F(0x04c1bf83) /* 0.297301779 */, MAD_F(0x04000000) /* 0.250000000 */, MAD_F(0x035d13f3) /* 0.210224104 */, MAD_F(0x02d413cd) /* 0.176776695 */, MAD_F(0x0260dfc1) /* 0.148650889 */, MAD_F(0x02000000) /* 0.125000000 */, MAD_F(0x01ae89fa) /* 0.105112052 */, MAD_F(0x016a09e6) /* 0.088388348 */, MAD_F(0x01306fe1) /* 0.074325445 */ }, { MAD_F(0x0b504f33) /* 0.707106781 */, MAD_F(0x08000000) /* 0.500000000 */, MAD_F(0x05a8279a) /* 0.353553391 */, MAD_F(0x04000000) /* 0.250000000 */, MAD_F(0x02d413cd) /* 0.176776695 */, MAD_F(0x02000000) /* 0.125000000 */, MAD_F(0x016a09e6) /* 0.088388348 */, MAD_F(0x01000000) /* 0.062500000 */, MAD_F(0x00b504f3) /* 0.044194174 */, MAD_F(0x00800000) /* 0.031250000 */, MAD_F(0x005a827a) /* 0.022097087 */, MAD_F(0x00400000) /* 0.015625000 */, MAD_F(0x002d413d) /* 0.011048543 */, MAD_F(0x00200000) /* 0.007812500 */, MAD_F(0x0016a09e) /* 0.005524272 */ } }; /* * NAME: III_sideinfo() * DESCRIPTION: decode frame side information from a bitstream */ static enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch, int lsf, struct sideinfo *si, unsigned int *data_bitlen, unsigned int *priv_bitlen) { unsigned int ngr, gr, ch, i; - enum mad_error result = 0; + enum mad_error result = MAD_ERROR_NONE; *data_bitlen = 0; *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3); si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9); si->private_bits = mad_bit_read(ptr, *priv_bitlen); ngr = 1; if (!lsf) { ngr = 2; for (ch = 0; ch < nch; ++ch) si->scfsi[ch] = mad_bit_read(ptr, 4); } for (gr = 0; gr < ngr; ++gr) { struct granule *granule = &si->gr[gr]; for (ch = 0; ch < nch; ++ch) { struct channel *channel = &granule->ch[ch]; channel->part2_3_length = mad_bit_read(ptr, 12); channel->big_values = mad_bit_read(ptr, 9); channel->global_gain = mad_bit_read(ptr, 8); channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4); *data_bitlen += channel->part2_3_length; if (channel->big_values > 288 && result == 0) result = MAD_ERROR_BADBIGVALUES; channel->flags = 0; /* window_switching_flag */ if (mad_bit_read(ptr, 1)) { channel->block_type = mad_bit_read(ptr, 2); if (channel->block_type == 0 && result == 0) result = MAD_ERROR_BADBLOCKTYPE; if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0) result = MAD_ERROR_BADSCFSI; channel->region0_count = 7; channel->region1_count = 36; if (mad_bit_read(ptr, 1)) channel->flags |= mixed_block_flag; @@ -557,138 +565,138 @@ enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch, for (i = 0; i < 2; ++i) channel->table_select[i] = mad_bit_read(ptr, 5); # if defined(DEBUG) channel->table_select[2] = 4; /* not used */ # endif for (i = 0; i < 3; ++i) channel->subblock_gain[i] = mad_bit_read(ptr, 3); } else { channel->block_type = 0; for (i = 0; i < 3; ++i) channel->table_select[i] = mad_bit_read(ptr, 5); channel->region0_count = mad_bit_read(ptr, 4); channel->region1_count = mad_bit_read(ptr, 3); } /* [preflag,] scalefac_scale, count1table_select */ channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3); } } return result; } /* * NAME: III_scalefactors_lsf() * DESCRIPTION: decode channel scalefactors for LSF from a bitstream */ static unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr, struct channel *channel, struct channel *gr1ch, int mode_extension) { struct mad_bitptr start; unsigned int scalefac_compress, index, slen[4], part, n, i; unsigned char const *nsfb; start = *ptr; scalefac_compress = channel->scalefac_compress; index = (channel->block_type == 2) ? ((channel->flags & mixed_block_flag) ? 2 : 1) : 0; - if (!((mode_extension & 0x1) && gr1ch)) { + if (!((mode_extension & I_STEREO) && gr1ch)) { if (scalefac_compress < 400) { slen[0] = (scalefac_compress >> 4) / 5; slen[1] = (scalefac_compress >> 4) % 5; slen[2] = (scalefac_compress % 16) >> 2; slen[3] = scalefac_compress % 4; nsfb = nsfb_table[0][index]; } else if (scalefac_compress < 500) { scalefac_compress -= 400; slen[0] = (scalefac_compress >> 2) / 5; slen[1] = (scalefac_compress >> 2) % 5; slen[2] = scalefac_compress % 4; slen[3] = 0; nsfb = nsfb_table[1][index]; } else { scalefac_compress -= 500; slen[0] = scalefac_compress / 3; slen[1] = scalefac_compress % 3; slen[2] = 0; slen[3] = 0; channel->flags |= preflag; nsfb = nsfb_table[2][index]; } n = 0; for (part = 0; part < 4; ++part) { for (i = 0; i < nsfb[part]; ++i) channel->scalefac[n++] = mad_bit_read(ptr, slen[part]); } while (n < 39) channel->scalefac[n++] = 0; } - else { /* (mode_extension & 0x1) && gr1ch (i.e. ch == 1) */ + else { /* (mode_extension & I_STEREO) && gr1ch (i.e. ch == 1) */ scalefac_compress >>= 1; if (scalefac_compress < 180) { slen[0] = scalefac_compress / 36; slen[1] = (scalefac_compress % 36) / 6; slen[2] = (scalefac_compress % 36) % 6; slen[3] = 0; nsfb = nsfb_table[3][index]; } else if (scalefac_compress < 244) { scalefac_compress -= 180; slen[0] = (scalefac_compress % 64) >> 4; slen[1] = (scalefac_compress % 16) >> 2; slen[2] = scalefac_compress % 4; slen[3] = 0; nsfb = nsfb_table[4][index]; } else { scalefac_compress -= 244; slen[0] = scalefac_compress / 3; slen[1] = scalefac_compress % 3; slen[2] = 0; slen[3] = 0; nsfb = nsfb_table[5][index]; } n = 0; for (part = 0; part < 4; ++part) { unsigned int max, is_pos; max = (1 << slen[part]) - 1; for (i = 0; i < nsfb[part]; ++i) { is_pos = mad_bit_read(ptr, slen[part]); channel->scalefac[n] = is_pos; gr1ch->scalefac[n++] = (is_pos == max); } } while (n < 39) { channel->scalefac[n] = 0; gr1ch->scalefac[n++] = 0; /* apparently not illegal */ @@ -730,207 +738,215 @@ unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel, nsfb = 1 * 3; while (nsfb--) channel->scalefac[sfbi++] = 0; } else { /* channel->block_type != 2 */ if (scfsi & 0x8) { for (sfbi = 0; sfbi < 6; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 0; sfbi < 6; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); } if (scfsi & 0x4) { for (sfbi = 6; sfbi < 11; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 6; sfbi < 11; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); } if (scfsi & 0x2) { for (sfbi = 11; sfbi < 16; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 11; sfbi < 16; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); } if (scfsi & 0x1) { for (sfbi = 16; sfbi < 21; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 16; sfbi < 21; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); } channel->scalefac[21] = 0; } return mad_bit_length(&start, ptr); } /* + * The Layer III formula for requantization and scaling is defined by + * section 2.4.3.4.7.1 of ISO/IEC 11172-3, as follows: + * + * long blocks: + * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * + * 2^((1/4) * (global_gain - 210)) * + * 2^-(scalefac_multiplier * + * (scalefac_l[sfb] + preflag * pretab[sfb])) + * + * short blocks: + * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * + * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) * + * 2^-(scalefac_multiplier * scalefac_s[sfb][w]) + * + * where: + * scalefac_multiplier = (scalefac_scale + 1) / 2 + * + * The routines III_exponents() and III_requantize() facilitate this + * calculation. + */ + +/* * NAME: III_exponents() * DESCRIPTION: calculate scalefactor exponents */ static void III_exponents(struct channel const *channel, unsigned char const *sfbwidth, signed int exponents[39]) { signed int gain; unsigned int scalefac_multiplier, sfbi; gain = (signed int) channel->global_gain - 210; scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1; if (channel->block_type == 2) { unsigned int l; signed int gain0, gain1, gain2; sfbi = l = 0; if (channel->flags & mixed_block_flag) { unsigned int premask; premask = (channel->flags & preflag) ? ~0 : 0; /* long block subbands 0-1 */ while (l < 36) { exponents[sfbi] = gain - (signed int) ((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) << scalefac_multiplier); l += sfbwidth[sfbi++]; } } /* this is probably wrong for 8000 Hz short/mixed blocks */ gain0 = gain - 8 * (signed int) channel->subblock_gain[0]; gain1 = gain - 8 * (signed int) channel->subblock_gain[1]; gain2 = gain - 8 * (signed int) channel->subblock_gain[2]; while (l < 576) { exponents[sfbi + 0] = gain0 - (signed int) (channel->scalefac[sfbi + 0] << scalefac_multiplier); exponents[sfbi + 1] = gain1 - (signed int) (channel->scalefac[sfbi + 1] << scalefac_multiplier); exponents[sfbi + 2] = gain2 - (signed int) (channel->scalefac[sfbi + 2] << scalefac_multiplier); l += 3 * sfbwidth[sfbi]; sfbi += 3; } } else { /* channel->block_type != 2 */ if (channel->flags & preflag) { for (sfbi = 0; sfbi < 22; ++sfbi) { exponents[sfbi] = gain - (signed int) ((channel->scalefac[sfbi] + pretab[sfbi]) << scalefac_multiplier); } } else { for (sfbi = 0; sfbi < 22; ++sfbi) { exponents[sfbi] = gain - (signed int) (channel->scalefac[sfbi] << scalefac_multiplier); } } } } /* * NAME: III_requantize() * DESCRIPTION: requantize one (positive) value */ static mad_fixed_t III_requantize(unsigned int value, signed int exp) { mad_fixed_t requantized; signed int frac; struct fixedfloat const *power; - /* - * long blocks: - * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * - * 2^((1/4) * (global_gain - 210)) * - * 2^-(scalefac_multiplier * - * (scalefac_l[sfb] + preflag * pretab[sfb])) - * - * short blocks: - * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * - * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) * - * 2^-(scalefac_multiplier * scalefac_s[sfb][w]) - * - * where: - * scalefac_multiplier = (scalefac_scale + 1) / 2 - */ - - frac = exp % 4; + frac = exp % 4; /* assumes sign(frac) == sign(exp) */ exp /= 4; power = &rq_table[value]; requantized = power->mantissa; exp += power->exponent; if (exp < 0) { if (-exp >= sizeof(mad_fixed_t) * CHAR_BIT) { /* underflow */ requantized = 0; } - else + else { + requantized += 1L << (-exp - 1); requantized >>= -exp; + } } else { if (exp >= 5) { /* overflow */ # if defined(DEBUG) fprintf(stderr, "requantize overflow (%f * 2^%d)\n", mad_f_todouble(requantized), exp); # endif requantized = MAD_F_MAX; } else requantized <<= exp; } return frac ? mad_f_mul(requantized, root_table[3 + frac]) : requantized; } /* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */ # define MASK(cache, sz, bits) \ (((cache) >> ((sz) - (bits))) & ((1 << (bits)) - 1)) # define MASK1BIT(cache, sz) \ ((cache) & (1 << ((sz) - 1))) /* * NAME: III_huffdecode() * DESCRIPTION: decode Huffman code words of one channel of one granule */ static enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576], struct channel *channel, unsigned char const *sfbwidth, unsigned int part2_length) { signed int exponents[39], exp; signed int const *expptr; struct mad_bitptr peek; signed int bits_left, cachesz; register mad_fixed_t *xrptr; mad_fixed_t const *sfbound; register unsigned long bitcache; bits_left = (signed) channel->part2_3_length - (signed) part2_length; if (bits_left < 0) return MAD_ERROR_BADPART3LEN; III_exponents(channel, sfbwidth, exponents); peek = *ptr; @@ -1206,400 +1222,394 @@ enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576], } ++expptr; } /* x (0..1) */ xrptr[0] = quad->value.x ? (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; /* y (0..1) */ xrptr[1] = quad->value.y ? (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; xrptr += 2; } if (cachesz + bits_left < 0) { # if 0 && defined(DEBUG) fprintf(stderr, "huffman count1 overrun (%d bits)\n", -(cachesz + bits_left)); # endif /* technically the bitstream is misformatted, but apparently some encoders are just a bit sloppy with stuffing bits */ xrptr -= 4; } } assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT); # if 0 && defined(DEBUG) if (bits_left < 0) fprintf(stderr, "read %d bits too many\n", -bits_left); else if (cachesz + bits_left > 0) fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left); # endif /* rzero */ while (xrptr < &xr[576]) { xrptr[0] = 0; xrptr[1] = 0; xrptr += 2; } - return 0; + return MAD_ERROR_NONE; } # undef MASK # undef MASK1BIT /* * NAME: III_reorder() * DESCRIPTION: reorder frequency lines of a short block into subband order */ static void III_reorder(mad_fixed_t xr[576], struct channel const *channel, unsigned char const sfbwidth[39]) { mad_fixed_t tmp[32][3][6]; - unsigned int sb, l, sfbi, f, w, sbw[3], sw[3]; + unsigned int sb, l, f, w, sbw[3], sw[3]; /* this is probably wrong for 8000 Hz mixed blocks */ - if (channel->flags & mixed_block_flag) - sb = 2, sfbi = 3 * 3; - else - sb = 0, sfbi = 0; + sb = 0; + if (channel->flags & mixed_block_flag) { + sb = 2; + + l = 0; + while (l < 36) + l += *sfbwidth++; + } for (w = 0; w < 3; ++w) { sbw[w] = sb; sw[w] = 0; } - f = sfbwidth[sfbi]; + f = *sfbwidth++; w = 0; for (l = 18 * sb; l < 576; ++l) { + if (f-- == 0) { + f = *sfbwidth++ - 1; + w = (w + 1) % 3; + } + tmp[sbw[w]][w][sw[w]++] = xr[l]; if (sw[w] == 6) { sw[w] = 0; ++sbw[w]; } - - if (--f == 0) { - if (++w == 3) - w = 0; - - f = sfbwidth[++sfbi]; - } } memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t)); } /* * NAME: III_stereo() * DESCRIPTION: perform joint stereo processing on a granule */ static enum mad_error III_stereo(mad_fixed_t xr[2][576], struct granule const *granule, struct mad_header *header, unsigned char const *sfbwidth) { short modes[39]; unsigned int sfbi, l, n, i; - enum { - i_stereo = 0x1, - ms_stereo = 0x2 - }; - if (granule->ch[0].block_type != granule->ch[1].block_type || (granule->ch[0].flags & mixed_block_flag) != (granule->ch[1].flags & mixed_block_flag)) return MAD_ERROR_BADSTEREO; for (i = 0; i < 39; ++i) modes[i] = header->mode_extension; /* intensity stereo */ - if (header->mode_extension & i_stereo) { + if (header->mode_extension & I_STEREO) { struct channel const *right_ch = &granule->ch[1]; mad_fixed_t const *right_xr = xr[1]; unsigned int is_pos; header->flags |= MAD_FLAG_I_STEREO; /* first determine which scalefactor bands are to be processed */ if (right_ch->block_type == 2) { unsigned int lower, start, max, bound[3], w; lower = start = max = bound[0] = bound[1] = bound[2] = 0; sfbi = l = 0; if (right_ch->flags & mixed_block_flag) { while (l < 36) { n = sfbwidth[sfbi++]; for (i = 0; i < n; ++i) { if (right_xr[i]) { lower = sfbi; break; } } right_xr += n; l += n; } start = sfbi; } w = 0; while (l < 576) { n = sfbwidth[sfbi++]; for (i = 0; i < n; ++i) { if (right_xr[i]) { max = bound[w] = sfbi; break; } } right_xr += n; l += n; w = (w + 1) % 3; } if (max) lower = start; /* long blocks */ for (i = 0; i < lower; ++i) - modes[i] = header->mode_extension & ~i_stereo; + modes[i] = header->mode_extension & ~I_STEREO; /* short blocks */ w = 0; for (i = start; i < max; ++i) { if (i < bound[w]) - modes[i] = header->mode_extension & ~i_stereo; + modes[i] = header->mode_extension & ~I_STEREO; w = (w + 1) % 3; } } else { /* right_ch->block_type != 2 */ unsigned int bound; bound = 0; for (sfbi = l = 0; l < 576; l += n) { n = sfbwidth[sfbi++]; for (i = 0; i < n; ++i) { if (right_xr[i]) { bound = sfbi; break; } } right_xr += n; } for (i = 0; i < bound; ++i) - modes[i] = header->mode_extension & ~i_stereo; + modes[i] = header->mode_extension & ~I_STEREO; } /* now do the actual processing */ if (header->flags & MAD_FLAG_LSF_EXT) { unsigned char const *illegal_pos = granule[1].ch[1].scalefac; mad_fixed_t const *lsf_scale; /* intensity_scale */ lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1]; for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; - if (!(modes[sfbi] & i_stereo)) + if (!(modes[sfbi] & I_STEREO)) continue; if (illegal_pos[sfbi]) { - modes[sfbi] &= ~i_stereo; + modes[sfbi] &= ~I_STEREO; continue; } is_pos = right_ch->scalefac[sfbi]; for (i = 0; i < n; ++i) { register mad_fixed_t left; left = xr[0][l + i]; if (is_pos == 0) xr[1][l + i] = left; else { register mad_fixed_t opposite; opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]); if (is_pos & 1) { xr[0][l + i] = opposite; xr[1][l + i] = left; } else xr[1][l + i] = opposite; } } } } else { /* !(header->flags & MAD_FLAG_LSF_EXT) */ for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; - if (!(modes[sfbi] & i_stereo)) + if (!(modes[sfbi] & I_STEREO)) continue; is_pos = right_ch->scalefac[sfbi]; if (is_pos >= 7) { /* illegal intensity position */ - modes[sfbi] &= ~i_stereo; + modes[sfbi] &= ~I_STEREO; continue; } for (i = 0; i < n; ++i) { register mad_fixed_t left; left = xr[0][l + i]; xr[0][l + i] = mad_f_mul(left, is_table[ is_pos]); xr[1][l + i] = mad_f_mul(left, is_table[6 - is_pos]); } } } } /* middle/side stereo */ - if (header->mode_extension & ms_stereo) { + if (header->mode_extension & MS_STEREO) { register mad_fixed_t invsqrt2; header->flags |= MAD_FLAG_MS_STEREO; invsqrt2 = root_table[3 + -2]; for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; - if (modes[sfbi] != ms_stereo) + if (modes[sfbi] != MS_STEREO) continue; for (i = 0; i < n; ++i) { register mad_fixed_t m, s; m = xr[0][l + i]; s = xr[1][l + i]; xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */ xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */ } } } - return 0; + return MAD_ERROR_NONE; } /* * NAME: III_aliasreduce() * DESCRIPTION: perform frequency line alias reduction */ static void III_aliasreduce(mad_fixed_t xr[576], int lines) { mad_fixed_t const *bound; int i; bound = &xr[lines]; for (xr += 18; xr < bound; xr += 18) { for (i = 0; i < 8; ++i) { - register mad_fixed_t *aptr, *bptr, a, b; + register mad_fixed_t a, b; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; - aptr = &xr[-1 - i]; - bptr = &xr[ i]; - - a = *aptr; - b = *bptr; + a = xr[-1 - i]; + b = xr[ i]; # if defined(ASO_ZEROCHECK) if (a | b) { # endif MAD_F_ML0(hi, lo, a, cs[i]); MAD_F_MLA(hi, lo, -b, ca[i]); - *aptr = MAD_F_MLZ(hi, lo); + xr[-1 - i] = MAD_F_MLZ(hi, lo); MAD_F_ML0(hi, lo, b, cs[i]); MAD_F_MLA(hi, lo, a, ca[i]); - *bptr = MAD_F_MLZ(hi, lo); + xr[ i] = MAD_F_MLZ(hi, lo); # if defined(ASO_ZEROCHECK) } # endif } } } # if defined(ASO_IMDCT) void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int); # else /* * NAME: imdct36 * DESCRIPTION: perform X[18]->x[36] IMDCT */ static inline void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36]) { mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8)); MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa)); t6 = MAD_F_MLZ(hi, lo); MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa)); MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8)); t0 = MAD_F_MLZ(hi, lo); MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549)); x[7] = MAD_F_MLZ(hi, lo); x[10] = -x[7]; MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0)); x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0; t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15]; @@ -2096,256 +2106,256 @@ void III_overlap_z(mad_fixed_t overlap[18], } # else for (i = 0; i < 18; ++i) { sample[i][sb] = overlap[i]; overlap[i] = 0; } # endif } /* * NAME: III_freqinver() * DESCRIPTION: perform subband frequency inversion for odd sample lines */ static void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb) { unsigned int i; # if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = sample[1][sb]; tmp2 = sample[3][sb]; for (i = 1; i < 13; i += 4) { sample[i + 0][sb] = -tmp1; tmp1 = sample[i + 4][sb]; sample[i + 2][sb] = -tmp2; tmp2 = sample[i + 6][sb]; } sample[13][sb] = -tmp1; tmp1 = sample[17][sb]; sample[15][sb] = -tmp2; sample[17][sb] = -tmp1; } # else for (i = 1; i < 18; i += 2) sample[i][sb] = -sample[i][sb]; # endif } /* * NAME: III_decode() * DESCRIPTION: decode frame main_data */ static -int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, - struct sideinfo *si, unsigned int nch) +enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, + struct sideinfo *si, unsigned int nch) { struct mad_header *header = &frame->header; unsigned int sfreqi, ngr, gr; { unsigned int sfreq; sfreq = header->samplerate; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) sfreq *= 2; /* 48000 => 0, 44100 => 1, 32000 => 2, 24000 => 3, 22050 => 4, 16000 => 5 */ sfreqi = ((sfreq >> 7) & 0x000f) + ((sfreq >> 15) & 0x0001) - 8; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) sfreqi += 3; } /* scalefactors, Huffman decoding, requantization */ ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2; for (gr = 0; gr < ngr; ++gr) { struct granule *granule = &si->gr[gr]; - unsigned char const *sfbwidth = 0; + unsigned char const *sfbwidth[2]; mad_fixed_t xr[2][576]; unsigned int ch; enum mad_error error; for (ch = 0; ch < nch; ++ch) { struct channel *channel = &granule->ch[ch]; unsigned int part2_length; - sfbwidth = sfbwidth_table[sfreqi].l; + sfbwidth[ch] = sfbwidth_table[sfreqi].l; if (channel->block_type == 2) { - sfbwidth = (channel->flags & mixed_block_flag) ? + sfbwidth[ch] = (channel->flags & mixed_block_flag) ? sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s; } if (header->flags & MAD_FLAG_LSF_EXT) { part2_length = III_scalefactors_lsf(ptr, channel, ch == 0 ? 0 : &si->gr[1].ch[1], header->mode_extension); } else { part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch], gr == 0 ? 0 : si->scfsi[ch]); } - error = III_huffdecode(ptr, xr[ch], channel, sfbwidth, part2_length); + error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length); if (error) return error; } /* joint stereo processing */ if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) { - error = III_stereo(xr, granule, header, sfbwidth); + error = III_stereo(xr, granule, header, sfbwidth[0]); if (error) return error; } /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */ for (ch = 0; ch < nch; ++ch) { struct channel const *channel = &granule->ch[ch]; mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr]; unsigned int sb, l, i, sblimit; mad_fixed_t output[36]; if (channel->block_type == 2) { - III_reorder(xr[ch], channel, sfbwidth_table[sfreqi].s); + III_reorder(xr[ch], channel, sfbwidth[ch]); # if !defined(OPT_STRICT) /* * According to ISO/IEC 11172-3, "Alias reduction is not applied for * granules with block_type == 2 (short block)." However, other * sources suggest alias reduction should indeed be performed on the * lower two subbands of mixed blocks. Most other implementations do * this, so by default we will too. */ if (channel->flags & mixed_block_flag) III_aliasreduce(xr[ch], 36); # endif } else III_aliasreduce(xr[ch], 576); l = 0; /* subbands 0-1 */ if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) { unsigned int block_type; block_type = channel->block_type; if (channel->flags & mixed_block_flag) block_type = 0; /* 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); } } 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_freqinver(sample, 1); /* (nonzero) subbands 2-31 */ i = 576; while (i > 36 && xr[ch][i - 1] == 0) --i; sblimit = 32 - (576 - i) / 18; if (channel->block_type != 2) { /* 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); if (sb & 1) III_freqinver(sample, sb); } } else { /* 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); if (sb & 1) III_freqinver(sample, sb); } } /* remaining (zero) subbands */ for (sb = sblimit; sb < 32; ++sb) { III_overlap_z((*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } } - return 0; + return MAD_ERROR_NONE; } /* * NAME: layer->III() * DESCRIPTION: decode a single Layer III frame */ int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame) { struct mad_header *header = &frame->header; unsigned int nch, priv_bitlen, next_md_begin = 0; unsigned int si_len, data_bitlen, md_len; unsigned int frame_space, frame_used, frame_free; struct mad_bitptr ptr; struct sideinfo si; enum mad_error error; int result = 0; /* allocate Layer III dynamic structures */ if (stream->main_data == 0) { stream->main_data = malloc(MAD_BUFFER_MDLEN); if (stream->main_data == 0) { stream->error = MAD_ERROR_NOMEM; return -1; } } if (frame->overlap == 0) { frame->overlap = 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); /* check frame sanity */ if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) < (signed int) si_len) { stream->error = MAD_ERROR_BADFRAMELEN; stream->md_len = 0; return -1; } diff --git a/core/multimedia/opieplayer/libmad/layer3.h b/core/multimedia/opieplayer/libmad/layer3.h index 1fd83e2..c1a5c69 100644 --- a/core/multimedia/opieplayer/libmad/layer3.h +++ b/core/multimedia/opieplayer/libmad/layer3.h @@ -1,30 +1,30 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_LAYER3_H # define LIBMAD_LAYER3_H # include "stream.h" # include "frame.h" int mad_layer_III(struct mad_stream *, struct mad_frame *); # endif diff --git a/core/multimedia/opieplayer/libmad/libmad_global.h b/core/multimedia/opieplayer/libmad/libmad_global.h index f2a2a71..2c9c713 100644 --- a/core/multimedia/opieplayer/libmad/libmad_global.h +++ b/core/multimedia/opieplayer/libmad/libmad_global.h @@ -1,45 +1,58 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_GLOBAL_H # define LIBMAD_GLOBAL_H /* conditional debugging */ # if defined(DEBUG) && defined(NDEBUG) # error "cannot define both DEBUG and NDEBUG" # endif # if defined(DEBUG) # include <stdio.h> # endif /* conditional features */ # if defined(OPT_SPEED) && defined(OPT_ACCURACY) # error "cannot optimize for both speed and accuracy" # endif # if defined(OPT_SPEED) && !defined(OPT_SSO) # define OPT_SSO 1 # 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 --git a/core/multimedia/opieplayer/libmad/libmad_version.h b/core/multimedia/opieplayer/libmad/libmad_version.h index f8ee1fa..9e684a7 100644 --- a/core/multimedia/opieplayer/libmad/libmad_version.h +++ b/core/multimedia/opieplayer/libmad/libmad_version.h @@ -1,47 +1,47 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_VERSION_H # define LIBMAD_VERSION_H # define MAD_VERSION_MAJOR 0 -# define MAD_VERSION_MINOR 13 -# define MAD_VERSION_PATCH 0 +# define MAD_VERSION_MINOR 14 +# define MAD_VERSION_PATCH 2 # define MAD_VERSION_EXTRA " (beta)" # define MAD_VERSION_STRINGIZE(str) #str # define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num) # define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \ MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \ MAD_VERSION_STRING(MAD_VERSION_PATCH) \ MAD_VERSION_EXTRA # define MAD_PUBLISHYEAR "2000-2001" # define MAD_AUTHOR "Robert Leslie" # define MAD_EMAIL "rob@mars.org" extern char const mad_version[]; extern char const mad_copyright[]; extern char const mad_author[]; extern char const mad_build[]; # endif diff --git a/core/multimedia/opieplayer/libmad/opie-libmadplugin.control b/core/multimedia/opieplayer/libmad/opie-libmadplugin.control index 941047f..42ea6c7 100644 --- a/core/multimedia/opieplayer/libmad/opie-libmadplugin.control +++ b/core/multimedia/opieplayer/libmad/opie-libmadplugin.control @@ -1,9 +1,9 @@ Files: plugins/codecs/libmadplugin.so.1.0.0 plugins/codecs/libmadplugin.so.1.0 plugins/codecs/libmadplugin.so.1 plugins/codecs/libmadplugin.so Priority: optional Section: opie/plugins -Maintainer: John Ryland <jryland@trolltech.com> +Maintainer: Maximilian Reiss <max.reiss@gmx.de> Architecture: arm Version: $QPE_VERSION-$SUB_VERSION Depends: opie-base ($QPE_VERSION) Description: MP3 file plugin using libmad Plugin to play MP3 files with the mediaplayer in the Opie environment. diff --git a/core/multimedia/opieplayer/libmad/qc_table.dat b/core/multimedia/opieplayer/libmad/qc_table.dat index 92b7f38..5d9ca96 100644 --- a/core/multimedia/opieplayer/libmad/qc_table.dat +++ b/core/multimedia/opieplayer/libmad/qc_table.dat @@ -1,50 +1,50 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ /* * These are the Layer II classes of quantization. * The table is derived from Table B.4 of ISO/IEC 11172-3. */ { 3, 2, 5, MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e 0.00000000124 */, MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, { 5, 3, 7, MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */, MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, { 7, 0, 3, MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e 0.00000000107 */, MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ }, { 9, 4, 10, MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e 0.00000000165 */, MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, { 15, 0, 4, MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e 0.00000000024 */, MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ }, { 31, 0, 5, MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e 0.00000000097 */, MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ }, { 63, 0, 6, MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e 0.00000000094 */, MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ }, { 127, 0, 7, MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e 0.00000000003 */, MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ }, diff --git a/core/multimedia/opieplayer/libmad/rq_table.dat b/core/multimedia/opieplayer/libmad/rq_table.dat index b6d1634..803cf04 100644 --- a/core/multimedia/opieplayer/libmad/rq_table.dat +++ b/core/multimedia/opieplayer/libmad/rq_table.dat @@ -1,50 +1,50 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ /* * This is the lookup table used to compute x^(4/3) for Layer III * requantization. To maintain the best possible accuracy, the value is * stored as a normalized mantissa with exponent. The requantization * algorithm recombines these parts with appropriate scaling. */ /* 0 */ { MAD_F(0x00000000) /* 0.000000000 */, 0 }, /* 1 */ { MAD_F(0x04000000) /* 0.250000000 */, 2 }, /* 2 */ { MAD_F(0x050a28be) /* 0.314980262 */, 3 }, /* 3 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 4 }, /* 4 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 4 }, /* 5 */ { MAD_F(0x04466275) /* 0.267183742 */, 5 }, /* 6 */ { MAD_F(0x05738c72) /* 0.340710111 */, 5 }, /* 7 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 5 }, /* 8 */ { MAD_F(0x04000000) /* 0.250000000 */, 6 }, /* 9 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 6 }, /* 10 */ { MAD_F(0x0562d694) /* 0.336630420 */, 6 }, /* 11 */ { MAD_F(0x061dae96) /* 0.382246578 */, 6 }, /* 12 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 6 }, /* 13 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 6 }, /* 14 */ { MAD_F(0x0437be65) /* 0.263609310 */, 7 }, /* 15 */ { MAD_F(0x049fc824) /* 0.289009227 */, 7 }, /* 16 */ { MAD_F(0x050a28be) /* 0.314980262 */, 7 }, /* 17 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 7 }, /* 18 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 7 }, /* 19 */ { MAD_F(0x06566361) /* 0.396090870 */, 7 }, /* 20 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 7 }, diff --git a/core/multimedia/opieplayer/libmad/sf_table.dat b/core/multimedia/opieplayer/libmad/sf_table.dat index 18e6202..bc368af 100644 --- a/core/multimedia/opieplayer/libmad/sf_table.dat +++ b/core/multimedia/opieplayer/libmad/sf_table.dat @@ -1,50 +1,50 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ /* * These are the scalefactor values for Layer I and Layer II. * The values are from Table B.1 of ISO/IEC 11172-3. * * There is some error introduced by the 32-bit fixed-point representation; * the amount of error is shown. For 16-bit PCM output, this shouldn't be * too much of a problem. */ MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */ MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */ MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */ MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */ MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */ MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */ MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */ MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */ MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */ MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */ MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */ MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */ MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */ MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */ MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */ MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */ MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */ MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */ diff --git a/core/multimedia/opieplayer/libmad/stream.c b/core/multimedia/opieplayer/libmad/stream.c index dea7b8e..4374de7 100644 --- a/core/multimedia/opieplayer/libmad/stream.c +++ b/core/multimedia/opieplayer/libmad/stream.c @@ -1,123 +1,160 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # include <stdlib.h> # include "bit.h" # include "stream.h" /* * NAME: stream->init() * DESCRIPTION: initialize stream struct */ void mad_stream_init(struct mad_stream *stream) { stream->buffer = 0; stream->bufend = 0; stream->skiplen = 0; stream->sync = 0; stream->freerate = 0; stream->this_frame = 0; stream->next_frame = 0; mad_bit_init(&stream->ptr, 0); mad_bit_init(&stream->anc_ptr, 0); stream->anc_bitlen = 0; stream->main_data = 0; stream->md_len = 0; stream->options = 0; - stream->error = 0; + stream->error = MAD_ERROR_NONE; } /* * NAME: stream->finish() * DESCRIPTION: deallocate any dynamic memory associated with stream */ void mad_stream_finish(struct mad_stream *stream) { if (stream->main_data) { free(stream->main_data); stream->main_data = 0; } mad_bit_finish(&stream->anc_ptr); mad_bit_finish(&stream->ptr); } /* * NAME: stream->buffer() * DESCRIPTION: set stream buffer pointers */ void mad_stream_buffer(struct mad_stream *stream, unsigned char const *buffer, unsigned long length) { stream->buffer = buffer; stream->bufend = buffer + length; stream->this_frame = buffer; stream->next_frame = buffer; stream->sync = 1; mad_bit_init(&stream->ptr, buffer); } /* * NAME: stream->skip() * DESCRIPTION: arrange to skip bytes before the next frame */ void mad_stream_skip(struct mad_stream *stream, unsigned long length) { stream->skiplen += length; } /* * NAME: stream->sync() * DESCRIPTION: locate the next stream sync word */ int mad_stream_sync(struct mad_stream *stream) { register unsigned char const *ptr, *end; ptr = mad_bit_nextbyte(&stream->ptr); end = stream->bufend; while (ptr < end - 1 && !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) ++ptr; if (end - ptr < MAD_BUFFER_GUARD) return -1; mad_bit_init(&stream->ptr, ptr); return 0; } + +/* + * NAME: stream->errorstr() + * DESCRIPTION: return a string description of the current error condition + */ +char const *mad_stream_errorstr(struct mad_stream const *stream) +{ + switch (stream->error) { + case MAD_ERROR_NONE: return "no error"; + + case MAD_ERROR_BUFLEN: return "input buffer too small (or EOF)"; + case MAD_ERROR_BUFPTR: return "invalid (null) buffer pointer"; + + case MAD_ERROR_NOMEM: return "not enough memory"; + + case MAD_ERROR_LOSTSYNC: return "lost synchronization"; + case MAD_ERROR_BADLAYER: return "reserved header layer value"; + case MAD_ERROR_BADBITRATE: return "forbidden bitrate value"; + case MAD_ERROR_BADSAMPLERATE: return "reserved sample frequency value"; + case MAD_ERROR_BADEMPHASIS: return "reserved emphasis value"; + + case MAD_ERROR_BADCRC: return "CRC check failed"; + case MAD_ERROR_BADBITALLOC: return "forbidden bit allocation value"; + case MAD_ERROR_BADSCALEFACTOR: return "bad scalefactor index"; + case MAD_ERROR_BADFRAMELEN: return "bad frame length"; + case MAD_ERROR_BADBIGVALUES: return "bad big_values count"; + case MAD_ERROR_BADBLOCKTYPE: return "reserved block_type"; + case MAD_ERROR_BADSCFSI: return "bad scalefactor selection info"; + case MAD_ERROR_BADDATAPTR: return "bad main_data_begin pointer"; + case MAD_ERROR_BADPART3LEN: return "bad audio data length"; + case MAD_ERROR_BADHUFFTABLE: return "bad Huffman table select"; + case MAD_ERROR_BADHUFFDATA: return "Huffman data overrun"; + case MAD_ERROR_BADSTEREO: return "incompatible block_type for JS"; + } + + return 0; +} diff --git a/core/multimedia/opieplayer/libmad/stream.h b/core/multimedia/opieplayer/libmad/stream.h index cf3280e..08e6dc5 100644 --- a/core/multimedia/opieplayer/libmad/stream.h +++ b/core/multimedia/opieplayer/libmad/stream.h @@ -1,102 +1,107 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_STREAM_H # define LIBMAD_STREAM_H # include "bit.h" # define MAD_BUFFER_GUARD 8 # define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) enum mad_error { + MAD_ERROR_NONE = 0x0000, /* no error */ + MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ }; # define MAD_RECOVERABLE(error) ((error) & 0xff00) struct mad_stream { unsigned char const *buffer; /* input bitstream buffer */ unsigned char const *bufend; /* end of buffer */ unsigned long skiplen; /* bytes to skip before next frame */ int sync; /* stream sync found */ unsigned long freerate; /* free bitrate (fixed) */ unsigned char const *this_frame; /* start of current frame */ unsigned char const *next_frame; /* start of next frame */ struct mad_bitptr ptr; /* current processing bit pointer */ struct mad_bitptr anc_ptr; /* ancillary bits pointer */ unsigned int anc_bitlen; /* number of ancillary bits */ unsigned char (*main_data)[MAD_BUFFER_MDLEN]; /* Layer III main_data() */ unsigned int md_len; /* bytes in main_data */ int options; /* decoding options (see below) */ enum mad_error error; /* error code (see above) */ }; enum { MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ - MAD_OPTION_HALFSAMPLERATE = 0x0002, /* generate PCM at 1/2 sample rate */ + MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ # if 0 /* not yet implemented */ MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ - MAD_OPTION_SINGLECHANNEL = 0x0030, /* combine channels */ + MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ # endif }; void mad_stream_init(struct mad_stream *); void mad_stream_finish(struct mad_stream *); -# define mad_stream_options(stream, opts) ((stream)->options = (opts)) +# define mad_stream_options(stream, opts) \ + ((void) ((stream)->options = (opts))) void mad_stream_buffer(struct mad_stream *, unsigned char const *, unsigned long); void mad_stream_skip(struct mad_stream *, unsigned long); int mad_stream_sync(struct mad_stream *); +char const *mad_stream_errorstr(struct mad_stream const *); + # endif diff --git a/core/multimedia/opieplayer/libmad/synth.c b/core/multimedia/opieplayer/libmad/synth.c index e1914c9..cf3c1d5 100644 --- a/core/multimedia/opieplayer/libmad/synth.c +++ b/core/multimedia/opieplayer/libmad/synth.c @@ -1,50 +1,50 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # include "fixed.h" # include "frame.h" # include "synth.h" /* * NAME: synth->init() * DESCRIPTION: initialize synth struct */ void mad_synth_init(struct mad_synth *synth) { mad_synth_mute(synth); synth->phase = 0; synth->pcm.samplerate = 0; synth->pcm.channels = 0; synth->pcm.length = 0; } /* * NAME: synth->mute() * DESCRIPTION: zero all polyphase filterbank values, resetting synthesis */ @@ -105,163 +105,159 @@ void mad_synth_mute(struct mad_synth *synth) # if defined(OPT_SPEED) && defined(MAD_F_MLX) # define OPT_DCTO # define MUL(x, y) \ ({ mad_fixed64hi_t hi; \ mad_fixed64lo_t lo; \ MAD_F_MLX(hi, lo, (x), (y)); \ hi << (32 - MAD_F_SCALEBITS - 3); \ }) # else # undef OPT_DCTO # define MUL(x, y) mad_f_mul((x), (y)) # endif /* * NAME: dct32() * DESCRIPTION: perform fast in[32]->out[32] DCT */ static void dct32(mad_fixed_t const in[32], unsigned int slot, mad_fixed_t lo[16][8], mad_fixed_t hi[16][8]) { mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23; mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31; mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39; mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47; mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55; mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63; mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71; mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79; mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87; mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95; mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103; mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111; mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119; mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127; mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135; mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143; mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151; mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159; mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167; mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175; mad_fixed_t t176; /* costab[i] = cos(PI / (2 * 32) * i) */ # if defined(OPT_DCTO) - enum { - costab1 = MAD_F(0x7fd8878e), - costab2 = MAD_F(0x7f62368f), - costab3 = MAD_F(0x7e9d55fc), - costab4 = MAD_F(0x7d8a5f40), - costab5 = MAD_F(0x7c29fbee), - costab6 = MAD_F(0x7a7d055b), - costab7 = MAD_F(0x78848414), - costab8 = MAD_F(0x7641af3d), - costab9 = MAD_F(0x73b5ebd1), - costab10 = MAD_F(0x70e2cbc6), - costab11 = MAD_F(0x6dca0d14), - costab12 = MAD_F(0x6a6d98a4), - costab13 = MAD_F(0x66cf8120), - costab14 = MAD_F(0x62f201ac), - costab15 = MAD_F(0x5ed77c8a), - costab16 = MAD_F(0x5a82799a), - costab17 = MAD_F(0x55f5a4d2), - costab18 = MAD_F(0x5133cc94), - costab19 = MAD_F(0x4c3fdff4), - costab20 = MAD_F(0x471cece7), - costab21 = MAD_F(0x41ce1e65), - costab22 = MAD_F(0x3c56ba70), - costab23 = MAD_F(0x36ba2014), - costab24 = MAD_F(0x30fbc54d), - costab25 = MAD_F(0x2b1f34eb), - costab26 = MAD_F(0x25280c5e), - costab27 = MAD_F(0x1f19f97b), - costab28 = MAD_F(0x18f8b83c), - costab29 = MAD_F(0x12c8106f), - costab30 = MAD_F(0x0c8bd35e), - costab31 = MAD_F(0x0647d97c) - }; +# define costab1 MAD_F(0x7fd8878e) +# define costab2 MAD_F(0x7f62368f) +# define costab3 MAD_F(0x7e9d55fc) +# define costab4 MAD_F(0x7d8a5f40) +# define costab5 MAD_F(0x7c29fbee) +# define costab6 MAD_F(0x7a7d055b) +# define costab7 MAD_F(0x78848414) +# define costab8 MAD_F(0x7641af3d) +# define costab9 MAD_F(0x73b5ebd1) +# define costab10 MAD_F(0x70e2cbc6) +# define costab11 MAD_F(0x6dca0d14) +# define costab12 MAD_F(0x6a6d98a4) +# define costab13 MAD_F(0x66cf8120) +# define costab14 MAD_F(0x62f201ac) +# define costab15 MAD_F(0x5ed77c8a) +# define costab16 MAD_F(0x5a82799a) +# define costab17 MAD_F(0x55f5a4d2) +# define costab18 MAD_F(0x5133cc94) +# define costab19 MAD_F(0x4c3fdff4) +# define costab20 MAD_F(0x471cece7) +# define costab21 MAD_F(0x41ce1e65) +# define costab22 MAD_F(0x3c56ba70) +# define costab23 MAD_F(0x36ba2014) +# define costab24 MAD_F(0x30fbc54d) +# define costab25 MAD_F(0x2b1f34eb) +# define costab26 MAD_F(0x25280c5e) +# define costab27 MAD_F(0x1f19f97b) +# define costab28 MAD_F(0x18f8b83c) +# define costab29 MAD_F(0x12c8106f) +# define costab30 MAD_F(0x0c8bd35e) +# define costab31 MAD_F(0x0647d97c) # else - enum { - costab1 = MAD_F(0x0ffb10f2), /* 0.998795456 */ - costab2 = MAD_F(0x0fec46d2), /* 0.995184727 */ - costab3 = MAD_F(0x0fd3aac0), /* 0.989176510 */ - costab4 = MAD_F(0x0fb14be8), /* 0.980785280 */ - costab5 = MAD_F(0x0f853f7e), /* 0.970031253 */ - costab6 = MAD_F(0x0f4fa0ab), /* 0.956940336 */ - costab7 = MAD_F(0x0f109082), /* 0.941544065 */ - costab8 = MAD_F(0x0ec835e8), /* 0.923879533 */ - costab9 = MAD_F(0x0e76bd7a), /* 0.903989293 */ - costab10 = MAD_F(0x0e1c5979), /* 0.881921264 */ - costab11 = MAD_F(0x0db941a3), /* 0.857728610 */ - costab12 = MAD_F(0x0d4db315), /* 0.831469612 */ - costab13 = MAD_F(0x0cd9f024), /* 0.803207531 */ - costab14 = MAD_F(0x0c5e4036), /* 0.773010453 */ - costab15 = MAD_F(0x0bdaef91), /* 0.740951125 */ - costab16 = MAD_F(0x0b504f33), /* 0.707106781 */ - costab17 = MAD_F(0x0abeb49a), /* 0.671558955 */ - costab18 = MAD_F(0x0a267993), /* 0.634393284 */ - costab19 = MAD_F(0x0987fbfe), /* 0.595699304 */ - costab20 = MAD_F(0x08e39d9d), /* 0.555570233 */ - costab21 = MAD_F(0x0839c3cd), /* 0.514102744 */ - costab22 = MAD_F(0x078ad74e), /* 0.471396737 */ - costab23 = MAD_F(0x06d74402), /* 0.427555093 */ - costab24 = MAD_F(0x061f78aa), /* 0.382683432 */ - costab25 = MAD_F(0x0563e69d), /* 0.336889853 */ - costab26 = MAD_F(0x04a5018c), /* 0.290284677 */ - costab27 = MAD_F(0x03e33f2f), /* 0.242980180 */ - costab28 = MAD_F(0x031f1708), /* 0.195090322 */ - costab29 = MAD_F(0x0259020e), /* 0.146730474 */ - costab30 = MAD_F(0x01917a6c), /* 0.098017140 */ - costab31 = MAD_F(0x00c8fb30) /* 0.049067674 */ - }; +# define costab1 MAD_F(0x0ffb10f2) /* 0.998795456 */ +# define costab2 MAD_F(0x0fec46d2) /* 0.995184727 */ +# define costab3 MAD_F(0x0fd3aac0) /* 0.989176510 */ +# define costab4 MAD_F(0x0fb14be8) /* 0.980785280 */ +# define costab5 MAD_F(0x0f853f7e) /* 0.970031253 */ +# define costab6 MAD_F(0x0f4fa0ab) /* 0.956940336 */ +# define costab7 MAD_F(0x0f109082) /* 0.941544065 */ +# define costab8 MAD_F(0x0ec835e8) /* 0.923879533 */ +# define costab9 MAD_F(0x0e76bd7a) /* 0.903989293 */ +# define costab10 MAD_F(0x0e1c5979) /* 0.881921264 */ +# define costab11 MAD_F(0x0db941a3) /* 0.857728610 */ +# define costab12 MAD_F(0x0d4db315) /* 0.831469612 */ +# define costab13 MAD_F(0x0cd9f024) /* 0.803207531 */ +# define costab14 MAD_F(0x0c5e4036) /* 0.773010453 */ +# define costab15 MAD_F(0x0bdaef91) /* 0.740951125 */ +# define costab16 MAD_F(0x0b504f33) /* 0.707106781 */ +# define costab17 MAD_F(0x0abeb49a) /* 0.671558955 */ +# define costab18 MAD_F(0x0a267993) /* 0.634393284 */ +# define costab19 MAD_F(0x0987fbfe) /* 0.595699304 */ +# define costab20 MAD_F(0x08e39d9d) /* 0.555570233 */ +# define costab21 MAD_F(0x0839c3cd) /* 0.514102744 */ +# define costab22 MAD_F(0x078ad74e) /* 0.471396737 */ +# define costab23 MAD_F(0x06d74402) /* 0.427555093 */ +# define costab24 MAD_F(0x061f78aa) /* 0.382683432 */ +# define costab25 MAD_F(0x0563e69d) /* 0.336889853 */ +# define costab26 MAD_F(0x04a5018c) /* 0.290284677 */ +# define costab27 MAD_F(0x03e33f2f) /* 0.242980180 */ +# define costab28 MAD_F(0x031f1708) /* 0.195090322 */ +# define costab29 MAD_F(0x0259020e) /* 0.146730474 */ +# define costab30 MAD_F(0x01917a6c) /* 0.098017140 */ +# define costab31 MAD_F(0x00c8fb30) /* 0.049067674 */ # endif t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1); t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31); t41 = t16 + t17; t59 = MUL(t16 - t17, costab2); t33 = t0 + t1; t50 = MUL(t0 - t1, costab2); t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15); t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17); t42 = t18 + t19; t60 = MUL(t18 - t19, costab30); t34 = t2 + t3; t51 = MUL(t2 - t3, costab30); t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7); t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25); t43 = t20 + t21; t61 = MUL(t20 - t21, costab14); t35 = t4 + t5; t52 = MUL(t4 - t5, costab14); t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9); t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23); t44 = t22 + t23; t62 = MUL(t22 - t23, costab18); t36 = t6 + t7; t53 = MUL(t6 - t7, costab18); t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3); t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29); t45 = t24 + t25; t63 = MUL(t24 - t25, costab6); t37 = t8 + t9; t54 = MUL(t8 - t9, costab6); t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13); t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19); t46 = t26 + t27; t64 = MUL(t26 - t27, costab26); t38 = t10 + t11; @@ -282,544 +278,550 @@ void dct32(mad_fixed_t const in[32], unsigned int slot, t66 = MUL(t30 - t31, costab22); t40 = t14 + t15; t57 = MUL(t14 - t15, costab22); t69 = t33 + t34; t89 = MUL(t33 - t34, costab4); t70 = t35 + t36; t90 = MUL(t35 - t36, costab28); t71 = t37 + t38; t91 = MUL(t37 - t38, costab12); t72 = t39 + t40; t92 = MUL(t39 - t40, costab20); t73 = t41 + t42; t94 = MUL(t41 - t42, costab4); t74 = t43 + t44; t95 = MUL(t43 - t44, costab28); t75 = t45 + t46; t96 = MUL(t45 - t46, costab12); t76 = t47 + t48; t97 = MUL(t47 - t48, costab20); t78 = t50 + t51; t100 = MUL(t50 - t51, costab4); t79 = t52 + t53; t101 = MUL(t52 - t53, costab28); t80 = t54 + t55; t102 = MUL(t54 - t55, costab12); t81 = t56 + t57; t103 = MUL(t56 - t57, costab20); t83 = t59 + t60; t106 = MUL(t59 - t60, costab4); t84 = t61 + t62; t107 = MUL(t61 - t62, costab28); t85 = t63 + t64; t108 = MUL(t63 - t64, costab12); t86 = t65 + t66; t109 = MUL(t65 - t66, costab20); t113 = t69 + t70; t114 = t71 + t72; /* 0 */ hi[15][slot] = SHIFT(t113 + t114); /* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16)); t115 = t73 + t74; t116 = t75 + t76; t32 = t115 + t116; /* 1 */ hi[14][slot] = SHIFT(t32); t118 = t78 + t79; t119 = t80 + t81; t58 = t118 + t119; /* 2 */ hi[13][slot] = SHIFT(t58); t121 = t83 + t84; t122 = t85 + t86; t67 = t121 + t122; - t49 = (t67 << 1) - t32; + t49 = (t67 * 2) - t32; /* 3 */ hi[12][slot] = SHIFT(t49); t125 = t89 + t90; t126 = t91 + t92; t93 = t125 + t126; /* 4 */ hi[11][slot] = SHIFT(t93); t128 = t94 + t95; t129 = t96 + t97; t98 = t128 + t129; - t68 = (t98 << 1) - t49; + t68 = (t98 * 2) - t49; /* 5 */ hi[10][slot] = SHIFT(t68); t132 = t100 + t101; t133 = t102 + t103; t104 = t132 + t133; - t82 = (t104 << 1) - t58; + t82 = (t104 * 2) - t58; /* 6 */ hi[ 9][slot] = SHIFT(t82); t136 = t106 + t107; t137 = t108 + t109; t110 = t136 + t137; - t87 = (t110 << 1) - t67; + t87 = (t110 * 2) - t67; - t77 = (t87 << 1) - t68; + t77 = (t87 * 2) - t68; /* 7 */ hi[ 8][slot] = SHIFT(t77); t141 = MUL(t69 - t70, costab8); t142 = MUL(t71 - t72, costab24); t143 = t141 + t142; /* 8 */ hi[ 7][slot] = SHIFT(t143); /* 24 */ lo[ 8][slot] = - SHIFT((MUL(t141 - t142, costab16) << 1) - t143); + SHIFT((MUL(t141 - t142, costab16) * 2) - t143); t144 = MUL(t73 - t74, costab8); t145 = MUL(t75 - t76, costab24); t146 = t144 + t145; - t88 = (t146 << 1) - t77; + t88 = (t146 * 2) - t77; /* 9 */ hi[ 6][slot] = SHIFT(t88); t148 = MUL(t78 - t79, costab8); t149 = MUL(t80 - t81, costab24); t150 = t148 + t149; - t105 = (t150 << 1) - t82; + t105 = (t150 * 2) - t82; /* 10 */ hi[ 5][slot] = SHIFT(t105); t152 = MUL(t83 - t84, costab8); t153 = MUL(t85 - t86, costab24); t154 = t152 + t153; - t111 = (t154 << 1) - t87; + t111 = (t154 * 2) - t87; - t99 = (t111 << 1) - t88; + t99 = (t111 * 2) - t88; /* 11 */ hi[ 4][slot] = SHIFT(t99); t157 = MUL(t89 - t90, costab8); t158 = MUL(t91 - t92, costab24); t159 = t157 + t158; - t127 = (t159 << 1) - t93; + t127 = (t159 * 2) - t93; /* 12 */ hi[ 3][slot] = SHIFT(t127); - t160 = (MUL(t125 - t126, costab16) << 1) - t127; + t160 = (MUL(t125 - t126, costab16) * 2) - t127; /* 20 */ lo[ 4][slot] = SHIFT(t160); /* 28 */ lo[12][slot] = - SHIFT((((MUL(t157 - t158, costab16) << 1) - t159) << 1) - t160); + SHIFT((((MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160); t161 = MUL(t94 - t95, costab8); t162 = MUL(t96 - t97, costab24); t163 = t161 + t162; - t130 = (t163 << 1) - t98; + t130 = (t163 * 2) - t98; - t112 = (t130 << 1) - t99; + t112 = (t130 * 2) - t99; /* 13 */ hi[ 2][slot] = SHIFT(t112); - t164 = (MUL(t128 - t129, costab16) << 1) - t130; + t164 = (MUL(t128 - t129, costab16) * 2) - t130; t166 = MUL(t100 - t101, costab8); t167 = MUL(t102 - t103, costab24); t168 = t166 + t167; - t134 = (t168 << 1) - t104; + t134 = (t168 * 2) - t104; - t120 = (t134 << 1) - t105; + t120 = (t134 * 2) - t105; /* 14 */ hi[ 1][slot] = SHIFT(t120); - t135 = (MUL(t118 - t119, costab16) << 1) - t120; + t135 = (MUL(t118 - t119, costab16) * 2) - t120; /* 18 */ lo[ 2][slot] = SHIFT(t135); - t169 = (MUL(t132 - t133, costab16) << 1) - t134; + t169 = (MUL(t132 - t133, costab16) * 2) - t134; - t151 = (t169 << 1) - t135; + t151 = (t169 * 2) - t135; /* 22 */ lo[ 6][slot] = SHIFT(t151); - t170 = (((MUL(t148 - t149, costab16) << 1) - t150) << 1) - t151; + t170 = (((MUL(t148 - t149, costab16) * 2) - t150) * 2) - t151; /* 26 */ lo[10][slot] = SHIFT(t170); /* 30 */ lo[14][slot] = - SHIFT((((((MUL(t166 - t167, costab16) << 1) - - t168) << 1) - t169) << 1) - t170); + SHIFT((((((MUL(t166 - t167, costab16) * 2) - + t168) * 2) - t169) * 2) - t170); t171 = MUL(t106 - t107, costab8); t172 = MUL(t108 - t109, costab24); t173 = t171 + t172; - t138 = (t173 << 1) - t110; + t138 = (t173 * 2) - t110; - t123 = (t138 << 1) - t111; + t123 = (t138 * 2) - t111; - t139 = (MUL(t121 - t122, costab16) << 1) - t123; + t139 = (MUL(t121 - t122, costab16) * 2) - t123; - t117 = (t123 << 1) - t112; + t117 = (t123 * 2) - t112; /* 15 */ hi[ 0][slot] = SHIFT(t117); - t124 = (MUL(t115 - t116, costab16) << 1) - t117; + t124 = (MUL(t115 - t116, costab16) * 2) - t117; /* 17 */ lo[ 1][slot] = SHIFT(t124); - t131 = (t139 << 1) - t124; + t131 = (t139 * 2) - t124; /* 19 */ lo[ 3][slot] = SHIFT(t131); - t140 = (t164 << 1) - t131; + t140 = (t164 * 2) - t131; /* 21 */ lo[ 5][slot] = SHIFT(t140); - t174 = (MUL(t136 - t137, costab16) << 1) - t138; + t174 = (MUL(t136 - t137, costab16) * 2) - t138; - t155 = (t174 << 1) - t139; + t155 = (t174 * 2) - t139; - t147 = (t155 << 1) - t140; + t147 = (t155 * 2) - t140; /* 23 */ lo[ 7][slot] = SHIFT(t147); - t156 = (((MUL(t144 - t145, costab16) << 1) - t146) << 1) - t147; + t156 = (((MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147; /* 25 */ lo[ 9][slot] = SHIFT(t156); - t175 = (((MUL(t152 - t153, costab16) << 1) - t154) << 1) - t155; + t175 = (((MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155; - t165 = (t175 << 1) - t156; + t165 = (t175 * 2) - t156; /* 27 */ lo[11][slot] = SHIFT(t165); - t176 = (((((MUL(t161 - t162, costab16) << 1) - - t163) << 1) - t164) << 1) - t165; + t176 = (((((MUL(t161 - t162, costab16) * 2) - + t163) * 2) - t164) * 2) - t165; /* 29 */ lo[13][slot] = SHIFT(t176); /* 31 */ lo[15][slot] = - SHIFT((((((((MUL(t171 - t172, costab16) << 1) - - t173) << 1) - t174) << 1) - t175) << 1) - t176); + SHIFT((((((((MUL(t171 - t172, costab16) * 2) - + t173) * 2) - t174) * 2) - t175) * 2) - t176); /* * Totals: * 80 multiplies * 80 additions * 119 subtractions * 49 shifts (not counting SSO) */ } # undef MUL # undef SHIFT /* third SSO shift and/or D[] optimization preshift */ # if defined(OPT_SSO) # if MAD_F_FRACBITS != 28 # error "MAD_F_FRACBITS must be 28 to use OPT_SSO" # endif # define ML0(hi, lo, x, y) ((lo) = (x) * (y)) # define MLA(hi, lo, x, y) ((lo) += (x) * (y)) +# define MLN(hi, lo) ((lo) = -(lo)) # define MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) # define SHIFT(x) ((x) >> 2) # define PRESHIFT(x) ((MAD_F(x) + (1L << 13)) >> 14) # else # define ML0(hi, lo, x, y) MAD_F_ML0((hi), (lo), (x), (y)) # define MLA(hi, lo, x, y) MAD_F_MLA((hi), (lo), (x), (y)) +# define MLN(hi, lo) MAD_F_MLN((hi), (lo)) # define MLZ(hi, lo) MAD_F_MLZ((hi), (lo)) # define SHIFT(x) (x) # if defined(MAD_F_SCALEBITS) # undef MAD_F_SCALEBITS # define MAD_F_SCALEBITS (MAD_F_FRACBITS - 12) # define PRESHIFT(x) (MAD_F(x) >> 12) # else # define PRESHIFT(x) MAD_F(x) # endif # endif static mad_fixed_t const D[17][32] = { # include "D.dat" }; # if defined(ASO_SYNTH) void synth_full(struct mad_synth *, struct mad_frame const *, unsigned int, unsigned int); # else /* * NAME: synth->full() * DESCRIPTION: perform full frequency PCM synthesis */ static void synth_full(struct mad_synth *synth, struct mad_frame const *frame, unsigned int nch, unsigned int ns) { unsigned int phase, ch, s, sb, pe, po; mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8]; mad_fixed_t const (*sbsample)[36][32]; register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; register mad_fixed_t const (*Dptr)[32], *ptr; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; for (ch = 0; ch < nch; ++ch) { sbsample = &frame->sbsample[ch]; filter = &synth->filter[ch]; phase = synth->phase; pcm1 = synth->pcm.samples[ch]; for (s = 0; s < ns; ++s) { dct32((*sbsample)[s], phase >> 1, (*filter)[0][phase & 1], (*filter)[1][phase & 1]); pe = phase & ~1; po = ((phase - 1) & 0xf) | 1; /* calculate 32 samples */ fe = &(*filter)[0][ phase & 1][0]; fx = &(*filter)[0][~phase & 1][0]; fo = &(*filter)[1][~phase & 1][0]; Dptr = &D[0]; + ptr = *Dptr + po; + ML0(hi, lo, (*fx)[0], ptr[ 0]); + MLA(hi, lo, (*fx)[1], ptr[14]); + MLA(hi, lo, (*fx)[2], ptr[12]); + MLA(hi, lo, (*fx)[3], ptr[10]); + MLA(hi, lo, (*fx)[4], ptr[ 8]); + MLA(hi, lo, (*fx)[5], ptr[ 6]); + MLA(hi, lo, (*fx)[6], ptr[ 4]); + MLA(hi, lo, (*fx)[7], ptr[ 2]); + MLN(hi, lo); + ptr = *Dptr + pe; - ML0(hi, lo, (*fe)[0], ptr[ 0]); + MLA(hi, lo, (*fe)[0], ptr[ 0]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[7], ptr[ 2]); - ptr = *Dptr + po; - MLA(hi, lo, (*fx)[0], -ptr[ 0]); - MLA(hi, lo, (*fx)[1], -ptr[14]); - MLA(hi, lo, (*fx)[2], -ptr[12]); - MLA(hi, lo, (*fx)[3], -ptr[10]); - MLA(hi, lo, (*fx)[4], -ptr[ 8]); - MLA(hi, lo, (*fx)[5], -ptr[ 6]); - MLA(hi, lo, (*fx)[6], -ptr[ 4]); - MLA(hi, lo, (*fx)[7], -ptr[ 2]); - *pcm1++ = SHIFT(MLZ(hi, lo)); pcm2 = pcm1 + 30; for (sb = 1; sb < 16; ++sb) { ++fe; ++Dptr; /* D[32 - sb][i] == -D[sb][31 - i] */ + ptr = *Dptr + po; + ML0(hi, lo, (*fo)[0], ptr[ 0]); + MLA(hi, lo, (*fo)[1], ptr[14]); + MLA(hi, lo, (*fo)[2], ptr[12]); + MLA(hi, lo, (*fo)[3], ptr[10]); + MLA(hi, lo, (*fo)[4], ptr[ 8]); + MLA(hi, lo, (*fo)[5], ptr[ 6]); + MLA(hi, lo, (*fo)[6], ptr[ 4]); + MLA(hi, lo, (*fo)[7], ptr[ 2]); + MLN(hi, lo); + ptr = *Dptr + pe; - ML0(hi, lo, (*fe)[7], ptr[ 2]); + MLA(hi, lo, (*fe)[7], ptr[ 2]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[0], ptr[ 0]); - ptr = *Dptr + po; - MLA(hi, lo, (*fo)[0], -ptr[ 0]); - MLA(hi, lo, (*fo)[1], -ptr[14]); - MLA(hi, lo, (*fo)[2], -ptr[12]); - MLA(hi, lo, (*fo)[3], -ptr[10]); - MLA(hi, lo, (*fo)[4], -ptr[ 8]); - MLA(hi, lo, (*fo)[5], -ptr[ 6]); - MLA(hi, lo, (*fo)[6], -ptr[ 4]); - MLA(hi, lo, (*fo)[7], -ptr[ 2]); - *pcm1++ = SHIFT(MLZ(hi, lo)); - ptr = *Dptr - po; - ML0(hi, lo, (*fo)[7], ptr[31 - 2]); - MLA(hi, lo, (*fo)[6], ptr[31 - 4]); - MLA(hi, lo, (*fo)[5], ptr[31 - 6]); - MLA(hi, lo, (*fo)[4], ptr[31 - 8]); - MLA(hi, lo, (*fo)[3], ptr[31 - 10]); - MLA(hi, lo, (*fo)[2], ptr[31 - 12]); - MLA(hi, lo, (*fo)[1], ptr[31 - 14]); - MLA(hi, lo, (*fo)[0], ptr[31 - 16]); - ptr = *Dptr - pe; - MLA(hi, lo, (*fe)[0], ptr[31 - 16]); + ML0(hi, lo, (*fe)[0], ptr[31 - 16]); MLA(hi, lo, (*fe)[1], ptr[31 - 14]); MLA(hi, lo, (*fe)[2], ptr[31 - 12]); MLA(hi, lo, (*fe)[3], ptr[31 - 10]); MLA(hi, lo, (*fe)[4], ptr[31 - 8]); MLA(hi, lo, (*fe)[5], ptr[31 - 6]); MLA(hi, lo, (*fe)[6], ptr[31 - 4]); MLA(hi, lo, (*fe)[7], ptr[31 - 2]); + ptr = *Dptr - po; + MLA(hi, lo, (*fo)[7], ptr[31 - 2]); + MLA(hi, lo, (*fo)[6], ptr[31 - 4]); + MLA(hi, lo, (*fo)[5], ptr[31 - 6]); + MLA(hi, lo, (*fo)[4], ptr[31 - 8]); + MLA(hi, lo, (*fo)[3], ptr[31 - 10]); + MLA(hi, lo, (*fo)[2], ptr[31 - 12]); + MLA(hi, lo, (*fo)[1], ptr[31 - 14]); + MLA(hi, lo, (*fo)[0], ptr[31 - 16]); + *pcm2-- = SHIFT(MLZ(hi, lo)); ++fo; } ++Dptr; ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); *pcm1 = SHIFT(-MLZ(hi, lo)); pcm1 += 16; phase = (phase + 1) % 16; } } } # endif /* * NAME: synth->half() * DESCRIPTION: perform half frequency PCM synthesis */ static void synth_half(struct mad_synth *synth, struct mad_frame const *frame, unsigned int nch, unsigned int ns) { unsigned int phase, ch, s, sb, pe, po; mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8]; mad_fixed_t const (*sbsample)[36][32]; register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; register mad_fixed_t const (*Dptr)[32], *ptr; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; for (ch = 0; ch < nch; ++ch) { sbsample = &frame->sbsample[ch]; filter = &synth->filter[ch]; phase = synth->phase; pcm1 = synth->pcm.samples[ch]; for (s = 0; s < ns; ++s) { dct32((*sbsample)[s], phase >> 1, (*filter)[0][phase & 1], (*filter)[1][phase & 1]); pe = phase & ~1; po = ((phase - 1) & 0xf) | 1; /* calculate 16 samples */ fe = &(*filter)[0][ phase & 1][0]; fx = &(*filter)[0][~phase & 1][0]; fo = &(*filter)[1][~phase & 1][0]; Dptr = &D[0]; + ptr = *Dptr + po; + ML0(hi, lo, (*fx)[0], ptr[ 0]); + MLA(hi, lo, (*fx)[1], ptr[14]); + MLA(hi, lo, (*fx)[2], ptr[12]); + MLA(hi, lo, (*fx)[3], ptr[10]); + MLA(hi, lo, (*fx)[4], ptr[ 8]); + MLA(hi, lo, (*fx)[5], ptr[ 6]); + MLA(hi, lo, (*fx)[6], ptr[ 4]); + MLA(hi, lo, (*fx)[7], ptr[ 2]); + MLN(hi, lo); + ptr = *Dptr + pe; - ML0(hi, lo, (*fe)[0], ptr[ 0]); + MLA(hi, lo, (*fe)[0], ptr[ 0]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[7], ptr[ 2]); - ptr = *Dptr + po; - MLA(hi, lo, (*fx)[0], -ptr[ 0]); - MLA(hi, lo, (*fx)[1], -ptr[14]); - MLA(hi, lo, (*fx)[2], -ptr[12]); - MLA(hi, lo, (*fx)[3], -ptr[10]); - MLA(hi, lo, (*fx)[4], -ptr[ 8]); - MLA(hi, lo, (*fx)[5], -ptr[ 6]); - MLA(hi, lo, (*fx)[6], -ptr[ 4]); - MLA(hi, lo, (*fx)[7], -ptr[ 2]); - *pcm1++ = SHIFT(MLZ(hi, lo)); pcm2 = pcm1 + 14; for (sb = 1; sb < 16; ++sb) { ++fe; ++Dptr; /* D[32 - sb][i] == -D[sb][31 - i] */ if (!(sb & 1)) { + ptr = *Dptr + po; + ML0(hi, lo, (*fo)[0], ptr[ 0]); + MLA(hi, lo, (*fo)[1], ptr[14]); + MLA(hi, lo, (*fo)[2], ptr[12]); + MLA(hi, lo, (*fo)[3], ptr[10]); + MLA(hi, lo, (*fo)[4], ptr[ 8]); + MLA(hi, lo, (*fo)[5], ptr[ 6]); + MLA(hi, lo, (*fo)[6], ptr[ 4]); + MLA(hi, lo, (*fo)[7], ptr[ 2]); + MLN(hi, lo); + ptr = *Dptr + pe; - ML0(hi, lo, (*fe)[7], ptr[ 2]); + MLA(hi, lo, (*fe)[7], ptr[ 2]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[0], ptr[ 0]); - ptr = *Dptr + po; - MLA(hi, lo, (*fo)[0], -ptr[ 0]); - MLA(hi, lo, (*fo)[1], -ptr[14]); - MLA(hi, lo, (*fo)[2], -ptr[12]); - MLA(hi, lo, (*fo)[3], -ptr[10]); - MLA(hi, lo, (*fo)[4], -ptr[ 8]); - MLA(hi, lo, (*fo)[5], -ptr[ 6]); - MLA(hi, lo, (*fo)[6], -ptr[ 4]); - MLA(hi, lo, (*fo)[7], -ptr[ 2]); - *pcm1++ = SHIFT(MLZ(hi, lo)); ptr = *Dptr - po; ML0(hi, lo, (*fo)[7], ptr[31 - 2]); MLA(hi, lo, (*fo)[6], ptr[31 - 4]); MLA(hi, lo, (*fo)[5], ptr[31 - 6]); MLA(hi, lo, (*fo)[4], ptr[31 - 8]); MLA(hi, lo, (*fo)[3], ptr[31 - 10]); MLA(hi, lo, (*fo)[2], ptr[31 - 12]); MLA(hi, lo, (*fo)[1], ptr[31 - 14]); MLA(hi, lo, (*fo)[0], ptr[31 - 16]); ptr = *Dptr - pe; MLA(hi, lo, (*fe)[0], ptr[31 - 16]); MLA(hi, lo, (*fe)[1], ptr[31 - 14]); MLA(hi, lo, (*fe)[2], ptr[31 - 12]); MLA(hi, lo, (*fe)[3], ptr[31 - 10]); MLA(hi, lo, (*fe)[4], ptr[31 - 8]); MLA(hi, lo, (*fe)[5], ptr[31 - 6]); MLA(hi, lo, (*fe)[6], ptr[31 - 4]); MLA(hi, lo, (*fe)[7], ptr[31 - 2]); *pcm2-- = SHIFT(MLZ(hi, lo)); } ++fo; } ++Dptr; ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); *pcm1 = SHIFT(-MLZ(hi, lo)); pcm1 += 8; phase = (phase + 1) % 16; } } } diff --git a/core/multimedia/opieplayer/libmad/synth.h b/core/multimedia/opieplayer/libmad/synth.h index 64f6a86..2c9d5c8 100644 --- a/core/multimedia/opieplayer/libmad/synth.h +++ b/core/multimedia/opieplayer/libmad/synth.h @@ -1,50 +1,69 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_SYNTH_H # define LIBMAD_SYNTH_H # include "fixed.h" # include "frame.h" +struct mad_pcm { + unsigned int samplerate; /* sampling frequency (Hz) */ + unsigned short channels; /* number of channels */ + unsigned short length; /* number of samples per channel */ + mad_fixed_t samples[2][1152]; /* PCM output samples [ch][sample] */ +}; + struct mad_synth { mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ /* [ch][eo][peo][s][v] */ unsigned int phase; /* current processing phase */ - struct mad_pcm { - unsigned int samplerate; /* sampling frequency (Hz) */ - unsigned short channels; /* number of channels */ - unsigned short length; /* number of samples per channel */ - mad_fixed_t samples[2][1152]; /* PCM output samples */ - } pcm; + struct mad_pcm pcm; /* PCM output */ +}; + +/* single channel PCM selector */ +enum { + MAD_PCM_CHANNEL_SINGLE = 0 +}; + +/* dual channel PCM selector */ +enum { + MAD_PCM_CHANNEL_DUAL_1 = 0, + MAD_PCM_CHANNEL_DUAL_2 = 1 +}; + +/* stereo PCM selector */ +enum { + MAD_PCM_CHANNEL_STEREO_LEFT = 0, + MAD_PCM_CHANNEL_STEREO_RIGHT = 1 }; void mad_synth_init(struct mad_synth *); # define mad_synth_finish(synth) /* nothing */ void mad_synth_mute(struct mad_synth *); void mad_synth_frame(struct mad_synth *, struct mad_frame const *); # endif diff --git a/core/multimedia/opieplayer/libmad/timer.c b/core/multimedia/opieplayer/libmad/timer.c index b30680c..299fe0b 100644 --- a/core/multimedia/opieplayer/libmad/timer.c +++ b/core/multimedia/opieplayer/libmad/timer.c @@ -1,77 +1,80 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # include <stdio.h> -# include <assert.h> + +# ifdef HAVE_ASSERT_H +# include <assert.h> +# endif # include "timer.h" mad_timer_t const mad_timer_zero = { 0, 0 }; /* * NAME: timer->compare() * DESCRIPTION: indicate relative order of two timers */ int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2) { signed long diff; diff = timer1.seconds - timer2.seconds; if (diff < 0) return -1; else if (diff > 0) return +1; diff = timer1.fraction - timer2.fraction; if (diff < 0) return -1; else if (diff > 0) return +1; return 0; } /* * NAME: timer->negate() * DESCRIPTION: invert the sign of a timer */ void mad_timer_negate(mad_timer_t *timer) { timer->seconds = -timer->seconds; if (timer->fraction) { timer->seconds -= 1; timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction; } } /* * NAME: timer->abs() * DESCRIPTION: return the absolute value of a timer */ mad_timer_t mad_timer_abs(mad_timer_t timer) { @@ -105,329 +108,330 @@ unsigned long gcd(unsigned long num1, unsigned long num2) tmp = num2; num2 = num1 % num2; num1 = tmp; } return num1; } /* * NAME: reduce_rational() * DESCRIPTION: convert rational expression to lowest terms */ static void reduce_rational(unsigned long *numer, unsigned long *denom) { unsigned long factor; factor = gcd(*numer, *denom); assert(factor != 0); *numer /= factor; *denom /= factor; } /* * NAME: scale_rational() * DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing */ static unsigned long scale_rational(unsigned long numer, unsigned long denom, unsigned long scale) { reduce_rational(&numer, &denom); reduce_rational(&scale, &denom); assert(denom != 0); if (denom < scale) return numer * (scale / denom) + numer * (scale % denom) / denom; if (denom < numer) return scale * (numer / denom) + scale * (numer % denom) / denom; return numer * scale / denom; } /* * NAME: timer->set() - * DESCRIPTION: set timer to specific value + * DESCRIPTION: set timer to specific (positive) value */ void mad_timer_set(mad_timer_t *timer, unsigned long seconds, - unsigned long fraction, unsigned long fracparts) + unsigned long numer, unsigned long denom) { timer->seconds = seconds; - - if (fraction == 0) - fracparts = 0; - else if (fracparts == 0) { - fracparts = fraction; - fraction = 1; + if (numer >= denom && denom > 0) { + timer->seconds += numer / denom; + numer %= denom; } - switch (fracparts) { + switch (denom) { case 0: + case 1: timer->fraction = 0; break; case MAD_TIMER_RESOLUTION: - timer->fraction = fraction; + timer->fraction = numer; + break; + + case 1000: + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000); break; case 8000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 8000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000); break; case 11025: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 11025); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025); break; case 12000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 12000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000); break; case 16000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 16000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000); break; case 22050: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 22050); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050); break; case 24000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 24000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000); break; case 32000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 32000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000); break; case 44100: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 44100); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100); break; case 48000: - timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 48000); + timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000); break; default: - timer->fraction = - scale_rational(fraction, fracparts, MAD_TIMER_RESOLUTION); + timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION); break; } if (timer->fraction >= MAD_TIMER_RESOLUTION) reduce_timer(timer); } /* * NAME: timer->add() * DESCRIPTION: add one timer to another */ void mad_timer_add(mad_timer_t *timer, mad_timer_t incr) { timer->seconds += incr.seconds; timer->fraction += incr.fraction; if (timer->fraction >= MAD_TIMER_RESOLUTION) reduce_timer(timer); } /* * NAME: timer->multiply() * DESCRIPTION: multiply a timer by a scalar value */ void mad_timer_multiply(mad_timer_t *timer, signed long scalar) { mad_timer_t addend; unsigned long factor; factor = scalar; if (scalar < 0) { - mad_timer_negate(timer); factor = -scalar; + mad_timer_negate(timer); } addend = *timer; *timer = mad_timer_zero; while (factor) { if (factor & 1) mad_timer_add(timer, addend); mad_timer_add(&addend, addend); factor >>= 1; } } /* * NAME: timer->count() * DESCRIPTION: return timer value in selected units */ signed long mad_timer_count(mad_timer_t timer, enum mad_units units) { switch (units) { case MAD_UNITS_HOURS: return timer.seconds / 60 / 60; case MAD_UNITS_MINUTES: return timer.seconds / 60; case MAD_UNITS_SECONDS: return timer.seconds; case MAD_UNITS_DECISECONDS: case MAD_UNITS_CENTISECONDS: case MAD_UNITS_MILLISECONDS: case MAD_UNITS_8000_HZ: case MAD_UNITS_11025_HZ: case MAD_UNITS_12000_HZ: case MAD_UNITS_16000_HZ: case MAD_UNITS_22050_HZ: case MAD_UNITS_24000_HZ: case MAD_UNITS_32000_HZ: case MAD_UNITS_44100_HZ: case MAD_UNITS_48000_HZ: case MAD_UNITS_24_FPS: case MAD_UNITS_25_FPS: case MAD_UNITS_30_FPS: case MAD_UNITS_48_FPS: case MAD_UNITS_50_FPS: case MAD_UNITS_60_FPS: case MAD_UNITS_75_FPS: return timer.seconds * (signed long) units + (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, units); case MAD_UNITS_23_976_FPS: case MAD_UNITS_24_975_FPS: case MAD_UNITS_29_97_FPS: case MAD_UNITS_47_952_FPS: case MAD_UNITS_49_95_FPS: case MAD_UNITS_59_94_FPS: return (mad_timer_count(timer, -units) + 1) * 1000 / 1001; } /* unsupported units */ return 0; } /* * NAME: timer->fraction() * DESCRIPTION: return fractional part of timer in arbitrary terms */ -unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long fracparts) +unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom) { timer = mad_timer_abs(timer); - switch (fracparts) { + switch (denom) { case 0: return MAD_TIMER_RESOLUTION / timer.fraction; case MAD_TIMER_RESOLUTION: return timer.fraction; default: - return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, fracparts); + return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom); } } /* * NAME: timer->string() * DESCRIPTION: write a string representation of a timer using a template */ void mad_timer_string(mad_timer_t timer, char *dest, char const *format, enum mad_units units, enum mad_units fracunits, unsigned long subparts) { unsigned long hours, minutes, seconds, sub; unsigned int frac; timer = mad_timer_abs(timer); seconds = timer.seconds; frac = sub = 0; switch (fracunits) { case MAD_UNITS_HOURS: case MAD_UNITS_MINUTES: case MAD_UNITS_SECONDS: break; case MAD_UNITS_DECISECONDS: case MAD_UNITS_CENTISECONDS: case MAD_UNITS_MILLISECONDS: case MAD_UNITS_8000_HZ: case MAD_UNITS_11025_HZ: case MAD_UNITS_12000_HZ: case MAD_UNITS_16000_HZ: case MAD_UNITS_22050_HZ: case MAD_UNITS_24000_HZ: case MAD_UNITS_32000_HZ: case MAD_UNITS_44100_HZ: case MAD_UNITS_48000_HZ: case MAD_UNITS_24_FPS: case MAD_UNITS_25_FPS: case MAD_UNITS_30_FPS: case MAD_UNITS_48_FPS: case MAD_UNITS_50_FPS: case MAD_UNITS_60_FPS: case MAD_UNITS_75_FPS: { - unsigned long fracparts; + unsigned long denom; - fracparts = MAD_TIMER_RESOLUTION / fracunits; + denom = MAD_TIMER_RESOLUTION / fracunits; - frac = timer.fraction / fracparts; - sub = scale_rational(timer.fraction % fracparts, fracparts, subparts); + frac = timer.fraction / denom; + sub = scale_rational(timer.fraction % denom, denom, subparts); } break; case MAD_UNITS_23_976_FPS: case MAD_UNITS_24_975_FPS: case MAD_UNITS_29_97_FPS: case MAD_UNITS_47_952_FPS: case MAD_UNITS_49_95_FPS: case MAD_UNITS_59_94_FPS: /* drop-frame encoding */ /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */ { unsigned long frame, cycle, d, m; frame = mad_timer_count(timer, fracunits); cycle = -fracunits * 60 * 10 - (10 - 1) * 2; d = frame / cycle; m = frame % cycle; frame += (10 - 1) * 2 * d; if (m > 2) frame += 2 * ((m - 2) / (cycle / 10)); frac = frame % -fracunits; seconds = frame / -fracunits; } break; } switch (units) { case MAD_UNITS_HOURS: minutes = seconds / 60; hours = minutes / 60; sprintf(dest, format, hours, (unsigned int) (minutes % 60), (unsigned int) (seconds % 60), frac, sub); break; case MAD_UNITS_MINUTES: minutes = seconds / 60; sprintf(dest, format, minutes, (unsigned int) (seconds % 60), diff --git a/core/multimedia/opieplayer/libmad/timer.h b/core/multimedia/opieplayer/libmad/timer.h index 67fe16a..f8afb8e 100644 --- a/core/multimedia/opieplayer/libmad/timer.h +++ b/core/multimedia/opieplayer/libmad/timer.h @@ -1,100 +1,100 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifndef LIBMAD_TIMER_H # define LIBMAD_TIMER_H typedef struct { signed long seconds; /* whole seconds */ unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ } mad_timer_t; extern mad_timer_t const mad_timer_zero; # define MAD_TIMER_RESOLUTION 352800000UL enum mad_units { MAD_UNITS_HOURS = -2, MAD_UNITS_MINUTES = -1, MAD_UNITS_SECONDS = 0, /* metric units */ MAD_UNITS_DECISECONDS = 10, MAD_UNITS_CENTISECONDS = 100, MAD_UNITS_MILLISECONDS = 1000, /* audio sample units */ MAD_UNITS_8000_HZ = 8000, MAD_UNITS_11025_HZ = 11025, MAD_UNITS_12000_HZ = 12000, MAD_UNITS_16000_HZ = 16000, MAD_UNITS_22050_HZ = 22050, MAD_UNITS_24000_HZ = 24000, MAD_UNITS_32000_HZ = 32000, MAD_UNITS_44100_HZ = 44100, MAD_UNITS_48000_HZ = 48000, /* video frame/field units */ MAD_UNITS_24_FPS = 24, MAD_UNITS_25_FPS = 25, MAD_UNITS_30_FPS = 30, MAD_UNITS_48_FPS = 48, MAD_UNITS_50_FPS = 50, MAD_UNITS_60_FPS = 60, /* CD audio frames */ MAD_UNITS_75_FPS = 75, /* video drop-frame units */ MAD_UNITS_23_976_FPS = -24, MAD_UNITS_24_975_FPS = -25, MAD_UNITS_29_97_FPS = -30, MAD_UNITS_47_952_FPS = -48, MAD_UNITS_49_95_FPS = -50, MAD_UNITS_59_94_FPS = -60 }; -# define mad_timer_reset(timer) (*(timer) = mad_timer_zero) +# define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero)) int mad_timer_compare(mad_timer_t, mad_timer_t); # define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero) void mad_timer_negate(mad_timer_t *); mad_timer_t mad_timer_abs(mad_timer_t); void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long); void mad_timer_add(mad_timer_t *, mad_timer_t); void mad_timer_multiply(mad_timer_t *, signed long); signed long mad_timer_count(mad_timer_t, enum mad_units); unsigned long mad_timer_fraction(mad_timer_t, unsigned long); void mad_timer_string(mad_timer_t, char *, char const *, enum mad_units, enum mad_units, unsigned long); # endif diff --git a/core/multimedia/opieplayer/libmad/version.c b/core/multimedia/opieplayer/libmad/version.c index 413d54b..fb126f4 100644 --- a/core/multimedia/opieplayer/libmad/version.c +++ b/core/multimedia/opieplayer/libmad/version.c @@ -1,82 +1,82 @@ /* - * mad - MPEG audio decoder + * libmad - MPEG audio decoder library * Copyright (C) 2000-2001 Robert Leslie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ # ifdef HAVE_CONFIG_H # include "libmad_config.h" # endif # include "libmad_global.h" # include "libmad_version.h" -char const mad_version[] = "MPEG Audio Decoder version " MAD_VERSION; +char const mad_version[] = "MPEG Audio Decoder " MAD_VERSION; char const mad_copyright[] = "Copyright (C) " MAD_PUBLISHYEAR " " MAD_AUTHOR; char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">"; -char const mad_build[] = +char const mad_build[] = "" # if defined(FPM_64BIT) "FPM_64BIT " # elif defined(FPM_INTEL) "FPM_INTEL " # elif defined(FPM_ARM) "FPM_ARM " # elif defined(FPM_MIPS) "FPM_MIPS " # elif defined(FPM_SPARC) "FPM_SPARC " # elif defined(FPM_PPC) "FPM_PPC " # elif defined(FPM_DEFAULT) "FPM_DEFAULT " # endif # if defined(ASO_IMDCT) "ASO_IMDCT " # endif # if defined(ASO_INTERLEAVE1) "ASO_INTERLEAVE1 " # endif # if defined(ASO_INTERLEAVE2) "ASO_INTERLEAVE2 " # endif # if defined(ASO_ZEROCHECK) "ASO_ZEROCHECK " # endif # if defined(OPT_SPEED) "OPT_SPEED " # elif defined(OPT_ACCURACY) "OPT_ACCURACY " # endif # if defined(OPT_SSO) "OPT_SSO " # endif # if defined(OPT_DCTO) /* never defined here */ "OPT_DCTO " # endif # if defined(OPT_STRICT) "OPT_STRICT " # endif # if defined(EXPERIMENTAL) |