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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 static int decode(unsigned char const *, unsigned long);
00039
00040 int main(int argc, char *argv[])
00041 {
00042 struct stat stat;
00043 void *fdm;
00044
00045 if (argc != 1)
00046 return 1;
00047
00048 if (fstat(STDIN_FILENO, &stat) == -1 ||
00049 stat.st_size == 0)
00050 return 2;
00051
00052 fdm = mmap(0, stat.st_size, PROT_READ, MAP_SHARED, STDIN_FILENO, 0);
00053 if (fdm == MAP_FAILED)
00054 return 3;
00055
00056 decode(fdm, stat.st_size);
00057
00058 if (munmap(fdm, stat.st_size) == -1)
00059 return 4;
00060
00061 return 0;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070 struct buffer {
00071 unsigned char const *start;
00072 unsigned long length;
00073 };
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 static
00084 enum mad_flow input(void *data,
00085 struct mad_stream *stream)
00086 {
00087 struct buffer *buffer = data;
00088
00089 if (!buffer->length)
00090 return MAD_FLOW_STOP;
00091
00092 mad_stream_buffer(stream, buffer->start, buffer->length);
00093
00094 buffer->length = 0;
00095
00096 return MAD_FLOW_CONTINUE;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 static inline
00108 signed int scale(mad_fixed_t sample)
00109 {
00110
00111 sample += (1L << (MAD_F_FRACBITS - 16));
00112
00113
00114 if (sample >= MAD_F_ONE)
00115 sample = MAD_F_ONE - 1;
00116 else if (sample < -MAD_F_ONE)
00117 sample = -MAD_F_ONE;
00118
00119
00120 return sample >> (MAD_F_FRACBITS + 1 - 16);
00121 }
00122
00123
00124
00125
00126
00127
00128
00129 static
00130 enum mad_flow output(void *data,
00131 struct mad_header const *header,
00132 struct mad_pcm *pcm)
00133 {
00134 unsigned int nchannels, nsamples;
00135 mad_fixed_t const *left_ch, *right_ch;
00136
00137
00138
00139 nchannels = pcm->channels;
00140 nsamples = pcm->length;
00141 left_ch = pcm->samples[0];
00142 right_ch = pcm->samples[1];
00143
00144 while (nsamples--) {
00145 signed int sample;
00146
00147
00148
00149 sample = scale(*left_ch++);
00150 putchar((sample >> 0) & 0xff);
00151 putchar((sample >> 8) & 0xff);
00152
00153 if (nchannels == 2) {
00154 sample = scale(*right_ch++);
00155 putchar((sample >> 0) & 0xff);
00156 putchar((sample >> 8) & 0xff);
00157 }
00158 }
00159
00160 return MAD_FLOW_CONTINUE;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170 static
00171 enum mad_flow error(void *data,
00172 struct mad_stream *stream,
00173 struct mad_frame *frame)
00174 {
00175 struct buffer *buffer = data;
00176
00177 fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n",
00178 stream->error, mad_stream_errorstr(stream),
00179 stream->this_frame - buffer->start);
00180
00181
00182
00183 return MAD_FLOW_CONTINUE;
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 static
00196 int decode(unsigned char const *start, unsigned long length)
00197 {
00198 struct buffer buffer;
00199 struct mad_decoder decoder;
00200 int result;
00201
00202
00203
00204 buffer.start = start;
00205 buffer.length = length;
00206
00207
00208
00209 mad_decoder_init(&decoder, &buffer,
00210 input, 0 , 0 , output,
00211 error, 0 );
00212
00213
00214
00215 result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
00216
00217
00218
00219 mad_decoder_finish(&decoder);
00220
00221 return result;
00222 }