00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 # include <stdio.h>
00023 # include <unistd.h>
00024 # include <sys/stat.h>
00025 # include <sys/mman.h>
00026
00027 # include "mad.h"
00028
00040 static int decode(unsigned char const *, unsigned long);
00041
00042 int main(int argc, char *argv[])
00043 {
00044 struct stat stat;
00045 void *fdm;
00046
00047 if (argc != 1)
00048 return 1;
00049
00050 if (fstat(STDIN_FILENO, &stat) == -1 ||
00051 stat.st_size == 0)
00052 return 2;
00053
00054 fdm = mmap(0, stat.st_size, PROT_READ, MAP_SHARED, STDIN_FILENO, 0);
00055 if (fdm == MAP_FAILED)
00056 return 3;
00057
00058 decode(fdm, stat.st_size);
00059
00060 if (munmap(fdm, stat.st_size) == -1)
00061 return 4;
00062
00063 return 0;
00064 }
00065
00072 struct buffer {
00073 unsigned char const *start;
00074 unsigned long length;
00075 };
00076
00085 static
00086 enum mad_flow input(void *data,
00087 struct mad_stream *stream)
00088 {
00089 struct buffer *buffer = data;
00090
00091 if (!buffer->length)
00092 return MAD_FLOW_STOP;
00093
00094 mad_stream_buffer(stream, buffer->start, buffer->length);
00095
00096 buffer->length = 0;
00097
00098 return MAD_FLOW_CONTINUE;
00099 }
00100
00109 static inline
00110 signed int scale(mad_fixed_t sample)
00111 {
00112
00113 sample += (1L << (MAD_F_FRACBITS - 16));
00114
00115
00116 if (sample >= MAD_F_ONE)
00117 sample = MAD_F_ONE - 1;
00118 else if (sample < -MAD_F_ONE)
00119 sample = -MAD_F_ONE;
00120
00121
00122 return sample >> (MAD_F_FRACBITS + 1 - 16);
00123 }
00124
00131 static
00132 enum mad_flow output(void *data,
00133 struct mad_header const *header,
00134 struct mad_pcm *pcm)
00135 {
00136 unsigned int nchannels, nsamples;
00137 mad_fixed_t const *left_ch, *right_ch;
00138
00139
00140
00141 nchannels = pcm->channels;
00142 nsamples = pcm->length;
00143 left_ch = pcm->samples[0];
00144 right_ch = pcm->samples[1];
00145
00146 while (nsamples--) {
00147 signed int sample;
00148
00149
00150
00151 sample = scale(*left_ch++);
00152 putchar((sample >> 0) & 0xff);
00153 putchar((sample >> 8) & 0xff);
00154
00155 if (nchannels == 2) {
00156 sample = scale(*right_ch++);
00157 putchar((sample >> 0) & 0xff);
00158 putchar((sample >> 8) & 0xff);
00159 }
00160 }
00161
00162 return MAD_FLOW_CONTINUE;
00163 }
00164
00172 static
00173 enum mad_flow error(void *data,
00174 struct mad_stream *stream,
00175 struct mad_frame *frame)
00176 {
00177 struct buffer *buffer = data;
00178
00179 fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n",
00180 stream->error, mad_stream_errorstr(stream),
00181 stream->this_frame - buffer->start);
00182
00183
00184
00185 return MAD_FLOW_CONTINUE;
00186 }
00187
00197 static
00198 int decode(unsigned char const *start, unsigned long length)
00199 {
00200 struct buffer buffer;
00201 struct mad_decoder decoder;
00202 int result;
00203
00204
00205
00206 buffer.start = start;
00207 buffer.length = length;
00208
00209
00210
00211 mad_decoder_init(&decoder, &buffer,
00212 input, 0 , 0 , output,
00213 error, 0 );
00214
00215
00216
00217 result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
00218
00219
00220
00221 mad_decoder_finish(&decoder);
00222
00223 return result;
00224 }