1 /*
2 * decode_mp3.c
3 *
4 * Copyright (C) Thomas Oestreich - June 2001
5 *
6 * This file is part of transcode, a video stream processing tool
7 *
8 * transcode is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * transcode is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Make; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24 #include <stdint.h>
25
26 #include "transcode.h"
27 #include "libtc/libtc.h"
28 #include "tcinfo.h"
29
30 #include "ioaux.h"
31 #include "tc.h"
32
33 #ifdef HAVE_LAME
34
35 #include "mpg123.h"
36
37 #define MP3_PCM_SIZE 1152
38 static uint16_t buffer[MP3_PCM_SIZE<<2];
39 static uint16_t ch1[MP3_PCM_SIZE], ch2[MP3_PCM_SIZE];
40
41 #endif // HAVE_LAME
42
43 #define MP3_AUDIO_ID 0x55
44 #define MP2_AUDIO_ID 0x50
45
46 /*
47 * About MP2/3 handling differences:
48 * It is possible that lame_decode_initfile() when looking for an MP3 syncbyte
49 * finds an invalid one (esp. in broken mp3 streams). Thats why we use the
50 * format argument to decide which syncword detection is to be done. The
51 * syncword detection for mp2 also finds mp3 sync bytes but NOT the other way round.
52 */
53
54 /* ------------------------------------------------------------
55 *
56 * decoder thread
57 *
58 * ------------------------------------------------------------*/
59
60
decode_mpaudio(decode_t * decode,int format)61 static void decode_mpaudio(decode_t *decode, int format)
62 {
63 #ifdef HAVE_LAME
64 int samples = 0, j, bytes, channels = 0, i, padding = 0;
65 int verbose;
66
67 mp3data_struct *mp3data = NULL;
68 FILE *in_file = NULL;
69
70 if (format != MP2_AUDIO_ID && format != MP3_AUDIO_ID) {
71 tc_log_error(__FILE__, "wrong mpeg audio format: 0x%x", format);
72 exit(1);
73 }
74
75 verbose = decode->verbose;
76
77 // init decoder
78
79 mp3data = tc_zalloc(sizeof(mp3data_struct));
80 if (mp3data == NULL) {
81 tc_log_error(__FILE__, "out of memory");
82 exit(1);
83 }
84
85 if (lame_decode_init() < 0) {
86 tc_log_error(__FILE__, "failed to init decoder");
87 exit(1);
88 }
89
90 in_file = fdopen(decode->fd_in, "r");
91
92 if (format == MP3_AUDIO_ID) {
93 int c = 0;
94 /* padding detection */
95 while (!(c = fgetc(in_file)))
96 padding++;
97 if (c != EOF)
98 ungetc(c, in_file);
99 }
100
101 samples = lame_decode_initfile(in_file, mp3data, format);
102
103 if (verbose) {
104 tc_log_info(__FILE__, "channels=%d, samplerate=%d Hz, bitrate=%d kbps, (%d)",
105 mp3data->stereo, mp3data->samplerate, mp3data->bitrate,
106 mp3data->framesize);
107 }
108
109 if (format == MP3_AUDIO_ID) {
110 if (decode->padrate > 0) {
111 padding = (int)((double)padding / (double)decode->padrate * mp3data->samplerate)
112 * mp3data->stereo * 2;
113 memset(buffer, 0, sizeof(buffer));
114 while (padding >= sizeof(buffer)) {
115 if (tc_pwrite(decode->fd_out, (uint8_t *)buffer, sizeof(buffer)) != sizeof(buffer)) {
116 tc_log_error(__FILE__, "error while writing padding output data");
117 import_exit(1);
118 }
119 padding -= sizeof(buffer);
120 }
121 if (padding && tc_pwrite(decode->fd_out, (uint8_t *)buffer, padding) != padding) {
122 tc_log_error(__FILE__, "error while writing final padding output data");
123 import_exit(1);
124 }
125 }
126 }
127
128 // decoder loop
129 channels = mp3data->stereo;
130
131 while ((samples=lame_decode_fromfile(in_file, ch1, ch2, mp3data)) > 0) {
132 // interleave data
133 j = 0;
134 switch (channels) {
135 case 1: // mono
136 ac_memcpy (buffer, ch1, samples * sizeof(uint16_t));
137 break;
138 case 2: // stereo
139 for (i=0; i < samples; i++) {
140 *(buffer+j+0) = ch1[i];
141 *(buffer+j+1) = ch2[i];
142 j+=2;
143 }
144 break;
145 }
146
147 bytes = samples * channels * sizeof(uint16_t);
148
149 if (tc_pwrite(decode->fd_out, (uint8_t *) buffer, bytes) != bytes) {
150 tc_log_error(__FILE__, "error while writing output data");
151 import_exit(1);
152 break; /* broken pipe */
153 }
154 }
155
156 import_exit(0);
157
158 #else // HAVE_LAME
159 tc_log_error(__FILE__, "no lame support available");
160 import_exit(1);
161 #endif
162 }
163
decode_mp3(decode_t * decode)164 void decode_mp3(decode_t *decode)
165 {
166 decode_mpaudio(decode, MP3_AUDIO_ID);
167 }
168
169
decode_mp2(decode_t * decode)170 void decode_mp2(decode_t *decode)
171 {
172 decode_mpaudio(decode, MP2_AUDIO_ID);
173 }
174
175 /*************************************************************************/
176
177 /*
178 * Local variables:
179 * c-file-style: "stroustrup"
180 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
181 * indent-tabs-mode: nil
182 * End:
183 *
184 * vim: expandtab shiftwidth=4:
185 */
186