1 /*****************************************************************************
2 * wav.c : wav file input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2008 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_demux.h>
36 #include <vlc_codecs.h>
38 /*****************************************************************************
40 *****************************************************************************/
41 static int Open ( vlc_object_t
* );
42 static void Close( vlc_object_t
* );
45 set_description( N_("WAV demuxer") )
46 set_category( CAT_INPUT
)
47 set_subcategory( SUBCAT_INPUT_DEMUX
)
48 set_capability( "demux", 142 )
49 set_callbacks( Open
, Close
)
52 /*****************************************************************************
54 *****************************************************************************/
55 static int Demux ( demux_t
* );
56 static int Control( demux_t
*, int i_query
, va_list args
);
64 unsigned int i_data_size
;
66 unsigned int i_frame_size
;
71 uint32_t i_channel_mask
;
72 bool b_chan_reorder
; /* do we need channel reordering */
73 int pi_chan_table
[AOUT_CHAN_MAX
];
76 static int ChunkFind( demux_t
*, const char *, unsigned int * );
78 static int FrameInfo_IMA_ADPCM( unsigned int *, int *, const es_format_t
* );
79 static int FrameInfo_MS_ADPCM ( unsigned int *, int *, const es_format_t
* );
80 static int FrameInfo_PCM ( unsigned int *, int *, const es_format_t
* );
81 static int FrameInfo_MSGSM ( unsigned int *, int *, const es_format_t
* );
83 static const uint32_t pi_channels_src
[] =
84 { WAVE_SPEAKER_FRONT_LEFT
, WAVE_SPEAKER_FRONT_RIGHT
,
85 WAVE_SPEAKER_FRONT_CENTER
, WAVE_SPEAKER_LOW_FREQUENCY
,
86 WAVE_SPEAKER_BACK_LEFT
, WAVE_SPEAKER_BACK_RIGHT
, WAVE_SPEAKER_BACK_CENTER
,
87 WAVE_SPEAKER_SIDE_LEFT
, WAVE_SPEAKER_SIDE_RIGHT
, 0 };
88 static const uint32_t pi_channels_in
[] =
89 { AOUT_CHAN_LEFT
, AOUT_CHAN_RIGHT
,
90 AOUT_CHAN_CENTER
, AOUT_CHAN_LFE
,
91 AOUT_CHAN_REARLEFT
, AOUT_CHAN_REARRIGHT
, AOUT_CHAN_REARCENTER
,
92 AOUT_CHAN_MIDDLELEFT
, AOUT_CHAN_MIDDLERIGHT
, 0 };
94 /*****************************************************************************
95 * Open: check file and initializes structures
96 *****************************************************************************/
97 static int Open( vlc_object_t
* p_this
)
99 demux_t
*p_demux
= (demux_t
*)p_this
;
102 const uint8_t *p_peek
;
104 unsigned int i_extended
;
105 const char *psz_name
;
107 WAVEFORMATEXTENSIBLE
*p_wf_ext
= NULL
;
108 WAVEFORMATEX
*p_wf
= NULL
;
110 /* Is it a wav file ? */
111 if( stream_Peek( p_demux
->s
, &p_peek
, 12 ) < 12 )
114 if( memcmp( p_peek
, "RIFF", 4 ) || memcmp( &p_peek
[8], "WAVE", 4 ) )
119 p_demux
->pf_demux
= Demux
;
120 p_demux
->pf_control
= Control
;
121 p_demux
->p_sys
= p_sys
= malloc( sizeof( *p_sys
) );
126 p_sys
->b_chan_reorder
= false;
127 p_sys
->i_channel_mask
= 0;
129 /* skip riff header */
130 if( stream_Read( p_demux
->s
, NULL
, 12 ) != 12 )
133 /* search fmt chunk */
134 if( ChunkFind( p_demux
, "fmt ", &i_size
) )
136 msg_Err( p_demux
, "cannot find 'fmt ' chunk" );
140 if( i_size
< sizeof( WAVEFORMATEX
) )
142 msg_Err( p_demux
, "invalid 'fmt ' chunk" );
145 if( stream_Read( p_demux
->s
, NULL
, 8 ) != 8 )
149 /* load waveformatex */
150 p_wf_ext
= malloc( i_size
);
151 if( p_wf_ext
== NULL
)
154 p_wf
= &p_wf_ext
->Format
;
157 if( stream_Read( p_demux
->s
, p_wf
, i_size
) != (int)i_size
||
158 ( ( i_size
& 1 ) && stream_Read( p_demux
->s
, NULL
, 1 ) != 1 ) )
160 msg_Err( p_demux
, "cannot load 'fmt ' chunk" );
164 es_format_Init( &p_sys
->fmt
, AUDIO_ES
, 0 );
165 wf_tag_to_fourcc( GetWLE( &p_wf
->wFormatTag
), &p_sys
->fmt
.i_codec
,
167 p_sys
->fmt
.audio
.i_channels
= GetWLE ( &p_wf
->nChannels
);
168 p_sys
->fmt
.audio
.i_rate
= GetDWLE( &p_wf
->nSamplesPerSec
);
169 p_sys
->fmt
.audio
.i_blockalign
= GetWLE( &p_wf
->nBlockAlign
);
170 p_sys
->fmt
.i_bitrate
= GetDWLE( &p_wf
->nAvgBytesPerSec
) * 8;
171 p_sys
->fmt
.audio
.i_bitspersample
= GetWLE( &p_wf
->wBitsPerSample
);
172 if( i_size
>= sizeof(WAVEFORMATEX
) )
173 p_sys
->fmt
.i_extra
= __MIN( GetWLE( &p_wf
->cbSize
), i_size
- sizeof(WAVEFORMATEX
) );
176 /* Handle new WAVE_FORMAT_EXTENSIBLE wav files */
177 /* see the following link for more information:
178 * http://www.microsoft.com/whdc/device/audio/multichaud.mspx#EFAA */
179 if( GetWLE( &p_wf
->wFormatTag
) == WAVE_FORMAT_EXTENSIBLE
&&
180 i_size
>= sizeof( WAVEFORMATEXTENSIBLE
) &&
181 ( p_sys
->fmt
.i_extra
+ sizeof( WAVEFORMATEX
)
182 >= sizeof( WAVEFORMATEXTENSIBLE
) ) )
184 unsigned i
, i_channel_mask
;
187 guid_subformat
= p_wf_ext
->SubFormat
;
188 guid_subformat
.Data1
= GetDWLE( &p_wf_ext
->SubFormat
.Data1
);
189 guid_subformat
.Data2
= GetWLE( &p_wf_ext
->SubFormat
.Data2
);
190 guid_subformat
.Data3
= GetWLE( &p_wf_ext
->SubFormat
.Data3
);
192 sf_tag_to_fourcc( &guid_subformat
, &p_sys
->fmt
.i_codec
, &psz_name
);
194 i_extended
= sizeof( WAVEFORMATEXTENSIBLE
) - sizeof( WAVEFORMATEX
);
195 p_sys
->fmt
.i_extra
-= i_extended
;
197 i_channel_mask
= GetDWLE( &p_wf_ext
->dwChannelMask
);
201 for( i
= 0; i
< sizeof(pi_channels_src
)/sizeof(*pi_channels_src
); i
++ )
203 if( i_channel_mask
& pi_channels_src
[i
] )
205 if( !( p_sys
->i_channel_mask
& pi_channels_in
[i
] ) )
208 i_channel_mask
&= ~pi_channels_src
[i
];
209 p_sys
->i_channel_mask
|= pi_channels_in
[i
];
211 if( i_match
>= p_sys
->fmt
.audio
.i_channels
)
216 msg_Warn( p_demux
, "Some channels are unrecognized or uselessly specified (0x%x)", i_channel_mask
);
217 if( i_match
< p_sys
->fmt
.audio
.i_channels
)
219 int i_missing
= p_sys
->fmt
.audio
.i_channels
- i_match
;
220 msg_Warn( p_demux
, "Trying to fill up unspecified position for %d channels", p_sys
->fmt
.audio
.i_channels
- i_match
);
222 static const uint32_t pi_pair
[] = { AOUT_CHAN_REARLEFT
|AOUT_CHAN_REARRIGHT
,
223 AOUT_CHAN_MIDDLELEFT
|AOUT_CHAN_MIDDLERIGHT
,
224 AOUT_CHAN_LEFT
|AOUT_CHAN_RIGHT
};
226 static const uint32_t pi_center[] = { AOUT_CHAN_REARCENTER,
228 AOUT_CHAN_CENTER }; */
230 /* Try to complete with pair */
231 for( unsigned i
= 0; i
< sizeof(pi_pair
)/sizeof(*pi_pair
); i
++ )
233 if( i_missing
>= 2 && !(p_sys
->i_channel_mask
& pi_pair
[i
] ) )
236 p_sys
->i_channel_mask
|= pi_pair
[i
];
239 /* Well fill up with what we can */
240 for( unsigned i
= 0; i
< sizeof(pi_channels_in
)/sizeof(*pi_channels_in
) && i_missing
> 0; i
++ )
242 if( !( p_sys
->i_channel_mask
& pi_channels_in
[i
] ) )
244 p_sys
->i_channel_mask
|= pi_channels_in
[i
];
252 i_match
= p_sys
->fmt
.audio
.i_channels
- i_missing
;
254 if( i_match
< p_sys
->fmt
.audio
.i_channels
)
256 msg_Err( p_demux
, "Invalid/unsupported channel mask" );
257 p_sys
->i_channel_mask
= 0;
261 else if( GetWLE( &p_wf
->wFormatTag
) == WAVE_FORMAT_PCM
&&
262 p_sys
->fmt
.audio
.i_channels
> 2 && p_sys
->fmt
.audio
.i_channels
<= 9 )
264 for( int i
= 0; i
< p_sys
->fmt
.audio
.i_channels
; i
++ )
265 p_sys
->i_channel_mask
|= pi_channels_in
[i
];
268 if( p_sys
->i_channel_mask
)
270 if( p_sys
->fmt
.i_codec
== VLC_FOURCC('a','r','a','w') ||
271 p_sys
->fmt
.i_codec
== VLC_FOURCC('p','c','m',' ') ||
272 p_sys
->fmt
.i_codec
== VLC_FOURCC('a','f','l','t') )
273 p_sys
->b_chan_reorder
=
274 aout_CheckChannelReorder( pi_channels_in
, NULL
,
275 p_sys
->i_channel_mask
,
276 p_sys
->fmt
.audio
.i_channels
,
277 p_sys
->pi_chan_table
);
279 msg_Dbg( p_demux
, "channel mask: %x, reordering: %i",
280 p_sys
->i_channel_mask
, (int)p_sys
->b_chan_reorder
);
283 p_sys
->fmt
.audio
.i_physical_channels
=
284 p_sys
->fmt
.audio
.i_original_channels
= p_sys
->i_channel_mask
;
286 if( p_sys
->fmt
.i_extra
> 0 )
288 p_sys
->fmt
.p_extra
= malloc( p_sys
->fmt
.i_extra
);
289 if( !p_sys
->fmt
.p_extra
)
291 p_sys
->fmt
.i_extra
= 0;
294 memcpy( p_sys
->fmt
.p_extra
, (uint8_t *)p_wf
+ sizeof( WAVEFORMATEX
) + i_extended
,
295 p_sys
->fmt
.i_extra
);
298 msg_Dbg( p_demux
, "format: 0x%4.4x, fourcc: %4.4s, channels: %d, "
299 "freq: %u Hz, bitrate: %uKo/s, blockalign: %d, bits/samples: %d, "
301 GetWLE( &p_wf
->wFormatTag
), (char *)&p_sys
->fmt
.i_codec
,
302 p_sys
->fmt
.audio
.i_channels
, p_sys
->fmt
.audio
.i_rate
,
303 p_sys
->fmt
.i_bitrate
/ 8 / 1024, p_sys
->fmt
.audio
.i_blockalign
,
304 p_sys
->fmt
.audio
.i_bitspersample
, p_sys
->fmt
.i_extra
);
309 switch( p_sys
->fmt
.i_codec
)
311 case VLC_FOURCC( 'a', 'r', 'a', 'w' ):
312 case VLC_FOURCC( 'a', 'f', 'l', 't' ):
313 case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
315 case VLC_CODEC_MULAW
:
316 case VLC_FOURCC( 'p', 'c', 'm', ' ' ):
317 if( FrameInfo_PCM( &p_sys
->i_frame_size
, &p_sys
->i_frame_samples
,
321 case VLC_CODEC_ADPCM_MS
:
322 if( FrameInfo_MS_ADPCM( &p_sys
->i_frame_size
, &p_sys
->i_frame_samples
,
326 case VLC_CODEC_ADPCM_IMA_WAV
:
327 if( FrameInfo_IMA_ADPCM( &p_sys
->i_frame_size
, &p_sys
->i_frame_samples
,
331 case VLC_FOURCC( 'm', 's', 0x00, 0x61 ):
332 case VLC_FOURCC( 'm', 's', 0x00, 0x62 ):
333 /* FIXME not sure at all FIXME */
334 if( FrameInfo_MS_ADPCM( &p_sys
->i_frame_size
, &p_sys
->i_frame_samples
,
340 /* FIXME set end of area FIXME */
342 case VLC_CODEC_GSM_MS
:
343 case VLC_CODEC_ADPCM_G726
:
344 if( FrameInfo_MSGSM( &p_sys
->i_frame_size
, &p_sys
->i_frame_samples
,
349 msg_Err( p_demux
, "unsupported codec (%4.4s)",
350 (char*)&p_sys
->fmt
.i_codec
);
354 if( p_sys
->i_frame_size
<= 0 || p_sys
->i_frame_samples
<= 0 )
356 msg_Dbg( p_demux
, "invalid frame size: %i %i", p_sys
->i_frame_size
,
357 p_sys
->i_frame_samples
);
360 if( p_sys
->fmt
.audio
.i_rate
<= 0 )
362 msg_Dbg( p_demux
, "invalid sample rate: %i", p_sys
->fmt
.audio
.i_rate
);
366 msg_Dbg( p_demux
, "found %s audio format", psz_name
);
368 if( ChunkFind( p_demux
, "data", &p_sys
->i_data_size
) )
370 msg_Err( p_demux
, "cannot find 'data' chunk" );
373 if( stream_Read( p_demux
->s
, NULL
, 8 ) != 8 )
375 p_sys
->i_data_pos
= stream_Tell( p_demux
->s
);
377 if( p_sys
->fmt
.i_bitrate
<= 0 )
379 p_sys
->fmt
.i_bitrate
= (int64_t)p_sys
->i_frame_size
*
380 p_sys
->fmt
.audio
.i_rate
* 8 / p_sys
->i_frame_samples
;
383 p_sys
->p_es
= es_out_Add( p_demux
->out
, &p_sys
->fmt
);
385 date_Init( &p_sys
->pts
, p_sys
->fmt
.audio
.i_rate
, 1 );
386 date_Set( &p_sys
->pts
, 1 );
391 msg_Err( p_demux
, "An error occured during wav demuxing" );
397 /*****************************************************************************
398 * Demux: read packet and send them to decoders
399 *****************************************************************************
400 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
401 *****************************************************************************/
402 static int Demux( demux_t
*p_demux
)
404 demux_sys_t
*p_sys
= p_demux
->p_sys
;
406 const int64_t i_pos
= stream_Tell( p_demux
->s
);
408 if( p_sys
->i_data_size
> 0 &&
409 i_pos
>= p_sys
->i_data_pos
+ p_sys
->i_data_size
)
415 if( ( p_block
= stream_Block( p_demux
->s
, p_sys
->i_frame_size
) ) == NULL
)
417 msg_Warn( p_demux
, "cannot read data" );
422 p_block
->i_pts
= VLC_TS_0
+ date_Get( &p_sys
->pts
);
425 es_out_Control( p_demux
->out
, ES_OUT_SET_PCR
, p_block
->i_pts
);
427 /* Do the channel reordering */
428 if( p_sys
->b_chan_reorder
)
429 aout_ChannelReorder( p_block
->p_buffer
, p_block
->i_buffer
,
430 p_sys
->fmt
.audio
.i_channels
,
431 p_sys
->pi_chan_table
,
432 p_sys
->fmt
.audio
.i_bitspersample
);
434 es_out_Send( p_demux
->out
, p_sys
->p_es
, p_block
);
436 date_Increment( &p_sys
->pts
, p_sys
->i_frame_samples
);
441 /*****************************************************************************
442 * Close: frees unused data
443 *****************************************************************************/
444 static void Close ( vlc_object_t
* p_this
)
446 demux_t
*p_demux
= (demux_t
*)p_this
;
447 demux_sys_t
*p_sys
= p_demux
->p_sys
;
452 /*****************************************************************************
454 *****************************************************************************/
455 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
457 demux_sys_t
*p_sys
= p_demux
->p_sys
;
460 if( p_sys
->i_data_size
> 0 )
461 i_end
= p_sys
->i_data_pos
+ p_sys
->i_data_size
;
463 return demux_vaControlHelper( p_demux
->s
, p_sys
->i_data_pos
, i_end
,
464 p_sys
->fmt
.i_bitrate
,
465 p_sys
->fmt
.audio
.i_blockalign
,
469 /*****************************************************************************
471 *****************************************************************************/
472 static int ChunkFind( demux_t
*p_demux
, const char *fcc
, unsigned int *pi_size
)
474 const uint8_t *p_peek
;
480 if( stream_Peek( p_demux
->s
, &p_peek
, 8 ) < 8 )
482 msg_Err( p_demux
, "cannot peek" );
486 i_size
= GetDWLE( p_peek
+ 4 );
488 msg_Dbg( p_demux
, "chunk: fcc=`%4.4s` size=%"PRIu32
, p_peek
, i_size
);
490 if( !memcmp( p_peek
, fcc
, 4 ) )
500 if( stream_Read( p_demux
->s
, NULL
, 8 ) != 8 ||
501 stream_Read( p_demux
->s
, NULL
, i_size
) != (int)i_size
||
502 ( (i_size
& 1) && stream_Read( p_demux
->s
, NULL
, 1 ) != 1 ) )
507 static int FrameInfo_PCM( unsigned int *pi_size
, int *pi_samples
,
508 const es_format_t
*p_fmt
)
512 /* read samples for 50ms of */
513 *pi_samples
= __MAX( p_fmt
->audio
.i_rate
/ 20, 1 );
515 i_bytes
= *pi_samples
* p_fmt
->audio
.i_channels
*
516 ( (p_fmt
->audio
.i_bitspersample
+ 7) / 8 );
518 if( p_fmt
->audio
.i_blockalign
> 0 )
520 const int i_modulo
= i_bytes
% p_fmt
->audio
.i_blockalign
;
522 i_bytes
+= p_fmt
->audio
.i_blockalign
- i_modulo
;
529 static int FrameInfo_MS_ADPCM( unsigned int *pi_size
, int *pi_samples
,
530 const es_format_t
*p_fmt
)
532 if( p_fmt
->audio
.i_channels
<= 0 )
535 *pi_samples
= 2 + 2 * ( p_fmt
->audio
.i_blockalign
-
536 7 * p_fmt
->audio
.i_channels
) / p_fmt
->audio
.i_channels
;
537 *pi_size
= p_fmt
->audio
.i_blockalign
;
542 static int FrameInfo_IMA_ADPCM( unsigned int *pi_size
, int *pi_samples
,
543 const es_format_t
*p_fmt
)
545 if( p_fmt
->audio
.i_channels
<= 0 )
548 *pi_samples
= 2 * ( p_fmt
->audio
.i_blockalign
-
549 4 * p_fmt
->audio
.i_channels
) / p_fmt
->audio
.i_channels
;
550 *pi_size
= p_fmt
->audio
.i_blockalign
;
555 static int FrameInfo_MSGSM( unsigned int *pi_size
, int *pi_samples
,
556 const es_format_t
*p_fmt
)
558 if( p_fmt
->i_bitrate
<= 0 )
561 *pi_samples
= ( p_fmt
->audio
.i_blockalign
* p_fmt
->audio
.i_rate
* 8)
563 *pi_size
= p_fmt
->audio
.i_blockalign
;