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 */
56 static void end_tag_be(
AVIOContext *pb, int64_t start)
57 {
58 int64_t pos;
59
64 }
65
67 {
70 int64_t pos;
71 int rate;
73 "VN:Lavf," :
75
77 if(rate < 0) {
80 }
81
86 "add '-strict %d' if you want to use it.\n",
89 }
90
99 end_tag_be(pb, pos);
101 avio_write(pb, version, strlen(version));
/* metadata ("ST:songtitle,VN:version,...") */
102 end_tag_be(pb, pos);
103
107 avio_w8(pb, 0);
/* format type */
108 avio_w8(pb, 0);
/* sequence type */
109 avio_w8(pb, (mmf->
stereo << 7) | (1 << 4) | rate);
/* (channel << 7) | (format << 4) | rate */
110 avio_w8(pb, 0);
/* wave base bit */
111 avio_w8(pb, 2);
/* time base d */
112 avio_w8(pb, 2);
/* time base g */
113
117 /* Will be filled on close */
118 avio_write(pb,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16);
119
121
123
125
126 return 0;
127 }
128
129 /* Write a variable-length symbol */
130 static void put_varlength(
AVIOContext *pb,
int val)
131 {
132 if(val < 128)
134 else {
135 val -= 128;
138 }
139 }
140
142 {
146 int gatetime;
147
149 /* Fill in length fields */
150 end_tag_be(pb, mmf->
awapos);
151 end_tag_be(pb, mmf->
atrpos);
152 end_tag_be(pb, 8);
153
156
157 /* Fill Atsq chunk */
159
160 /* "play wav" */
161 avio_w8(pb, 0);
/* start time */
162 avio_w8(pb, (mmf->
stereo << 6) | 1);
/* (channel << 6) | wavenum */
164 put_varlength(pb, gatetime); /* duration */
165
166 /* "nop" */
167 put_varlength(pb, gatetime); /* start time */
169
170 /* "end of sequence" */
172
174
176 }
177 return 0;
178 }
179 #endif /* CONFIG_MMF_MUXER */
180
182 {
183 /* check file header */
184 if (p->
buf[0] ==
'M' && p->
buf[1] ==
'M' &&
185 p->
buf[2] ==
'M' && p->
buf[3] ==
'D' &&
186 p->
buf[8] ==
'C' && p->
buf[9] ==
'N' &&
187 p->
buf[10] ==
'T' && p->
buf[11] ==
'I')
189 else
190 return 0;
191 }
192
193 /* mmf input */
195 {
201 int rate, params;
202
204 if (tag !=
MKTAG(
'M',
'M',
'M',
'D'))
207
208 /* Skip some unused chunks that may or may not be present */
212 if(tag ==
MKTAG(
'C',
'N',
'T',
'I'))
continue;
213 if(tag ==
MKTAG(
'O',
'P',
'D',
'A'))
continue;
214 break;
215 }
216
217 /* Tag = "ATRx", where "x" = track number */
218 if ((tag & 0xffffff) ==
MKTAG(
'M',
'T',
'R', 0)) {
221 }
222 if ((tag & 0xffffff) !=
MKTAG(
'A',
'T',
'R', 0)) {
225 }
226
228 avio_r8(pb);
/* sequence type */
229 params =
avio_r8(pb);
/* (channel << 7) | (format << 4) | rate */
231 if(rate < 0) {
234 }
235 avio_r8(pb);
/* wave base bit */
238
239 /* Skip some unused chunks that may or may not be present */
243 if(tag ==
MKTAG(
'A',
't',
's',
'q'))
continue;
244 if(tag ==
MKTAG(
'A',
's',
'p',
'I'))
continue;
245 break;
246 }
247
248 /* Make sure it's followed by an Awa chunk, aka wave data */
249 if ((tag & 0xffffff) !=
MKTAG(
'A',
'w',
'a', 0)) {
252 }
254
256 if (!st)
258
266
268
269 return 0;
270 }
271
272 #define MAX_SIZE 4096
273
276 {
279 int ret;
280
285
287 if (ret < 0)
288 return ret;
289
291
292 return ret;
293 }
294
295 #if CONFIG_MMF_DEMUXER
304 };
305 #endif
306 #if CONFIG_MMF_MUXER
310 .mime_type = "application/vnd.smaf",
311 .extensions = "mmf",
318 };
319 #endif