1 /*
2 * Yamaha SMAF format
3 * Copyright (c) 2005 Vidar Madsen
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
29
35
36 static const int mmf_rates[] = { 4000, 8000, 11025, 22050, 44100 };
37
39 {
40 if ((code < 0) || (code > 4))
41 return -1;
43 }
44
45 #if CONFIG_MMF_MUXER
46 static int mmf_rate_code(int rate)
47 {
48 int i;
49 for (i = 0; i < 5; i++)
51 return i;
52 return -1;
53 }
54
55 /* Copy of end_tag() from avienc.c, but for big-endian chunk size */
57 {
58 int64_t pos;
59
64 }
65
67 {
70 int64_t pos;
71 int rate;
73 "VN:Lavf," :
75
77 if (rate < 0) {
78 av_log(s,
AV_LOG_ERROR,
"Unsupported sample rate %d, supported are 4000, 8000, 11025, 22050 and 44100\n",
81 }
82
87 "add '-strict %d' if you want to use it.\n",
90 }
91
100 end_tag_be(pb, pos);
101
103 avio_write(pb, version, strlen(version));
/* metadata ("ST:songtitle,VN:version,...") */
104 end_tag_be(pb, pos);
105
109 avio_w8(pb, 0);
/* format type */
110 avio_w8(pb, 0);
/* sequence type */
111 avio_w8(pb, (mmf->
stereo << 7) | (1 << 4) | rate);
/* (channel << 7) | (format << 4) | rate */
112 avio_w8(pb, 0);
/* wave base bit */
113 avio_w8(pb, 2);
/* time base d */
114 avio_w8(pb, 2);
/* time base g */
115
119 /* Will be filled on close */
120 avio_write(pb,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16);
121
123
125
127
128 return 0;
129 }
130
131 /* Write a variable-length symbol */
133 {
134 if (val < 128)
136 else {
137 val -= 128;
140 }
141 }
142
144 {
148 int gatetime;
149
151 /* Fill in length fields */
152 end_tag_be(pb, mmf->
awapos);
153 end_tag_be(pb, mmf->
atrpos);
154 end_tag_be(pb, 8);
155
158
159 /* Fill Atsq chunk */
161
162 /* "play wav" */
163 avio_w8(pb, 0);
/* start time */
164 avio_w8(pb, (mmf->
stereo << 6) | 1);
/* (channel << 6) | wavenum */
166 put_varlength(pb, gatetime); /* duration */
167
168 /* "nop" */
169 put_varlength(pb, gatetime); /* start time */
171
172 /* "end of sequence" */
174
176
178 }
179 return 0;
180 }
181 #endif /* CONFIG_MMF_MUXER */
182
184 {
185 /* check file header */
186 if (p->
buf[0] ==
'M' && p->
buf[1] ==
'M' &&
187 p->
buf[2] ==
'M' && p->
buf[3] ==
'D' &&
188 p->
buf[8] ==
'C' && p->
buf[9] ==
'N' &&
189 p->
buf[10] ==
'T' && p->
buf[11] ==
'I')
191 else
192 return 0;
193 }
194
195 /* mmf input */
197 {
204
206 if (tag !=
MKTAG(
'M',
'M',
'M',
'D'))
209
210 /* Skip some unused chunks that may or may not be present */
214 if (tag ==
MKTAG(
'C',
'N',
'T',
'I'))
215 continue;
216 if (tag ==
MKTAG(
'O',
'P',
'D',
'A'))
217 continue;
218 break;
219 }
220
221 /* Tag = "ATRx", where "x" = track number */
222 if ((tag & 0xffffff) ==
MKTAG(
'M',
'T',
'R', 0)) {
225 }
226 if ((tag & 0xffffff) !=
MKTAG(
'A',
'T',
'R', 0)) {
229 }
230
232 avio_r8(pb);
/* sequence type */
233 params =
avio_r8(pb);
/* (channel << 7) | (format << 4) | rate */
235 if (rate < 0) {
238 }
239 avio_r8(pb);
/* wave base bit */
242
243 /* Skip some unused chunks that may or may not be present */
247 if (tag ==
MKTAG(
'A',
't',
's',
'q'))
248 continue;
249 if (tag ==
MKTAG(
'A',
's',
'p',
'I'))
250 continue;
251 break;
252 }
253
254 /* Make sure it's followed by an Awa chunk, aka wave data */
255 if ((tag & 0xffffff) !=
MKTAG(
'A',
'w',
'a', 0)) {
258 }
260
262 if (!st)
264
273
275
276 return 0;
277 }
278
279 #define MAX_SIZE 4096
280
282 {
286
291
293 if (ret < 0)
295
297
299 }
300
301 #if CONFIG_MMF_DEMUXER
310 };
311 #endif
312
313 #if CONFIG_MMF_MUXER
317 .mime_type = "application/vnd.smaf",
318 .extensions = "mmf",
325 };
326 #endif