1 /*****************************************************************************
2 * wav.c : wav file input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001-2008 VLC authors and VideoLAN
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_demux.h>
38 #include <vlc_codecs.h>
40 #include "windows_audio_commons.h"
42 #define WAV_CHAN_MAX 32
43 static_assert( INPUT_CHAN_MAX
>= WAV_CHAN_MAX
, "channel count mismatch" );
45 /*****************************************************************************
47 *****************************************************************************/
48 static int Open ( vlc_object_t
* );
49 static void Close( vlc_object_t
* );
52 set_description( N_("WAV demuxer") )
53 set_category( CAT_INPUT
)
54 set_subcategory( SUBCAT_INPUT_DEMUX
)
55 set_capability( "demux", 142 )
56 set_callbacks( Open
, Close
)
59 /*****************************************************************************
61 *****************************************************************************/
62 static int Demux ( demux_t
* );
63 static int Control( demux_t
*, int i_query
, va_list args
);
73 unsigned int i_frame_size
;
78 uint32_t i_channel_mask
;
79 uint8_t i_chans_to_reorder
; /* do we need channel reordering */
80 uint8_t pi_chan_table
[AOUT_CHAN_MAX
];
83 static int ChunkFind( demux_t
*, const char *, unsigned int * );
85 static int FrameInfo_IMA_ADPCM( unsigned int *, int *, const es_format_t
* );
86 static int FrameInfo_MS_ADPCM ( unsigned int *, int *, const es_format_t
* );
87 static int FrameInfo_Creative_ADPCM( unsigned int *, int *, const es_format_t
* );
88 static int FrameInfo_PCM ( unsigned int *, int *, const es_format_t
* );
89 static int FrameInfo_MSGSM ( unsigned int *, int *, const es_format_t
* );
91 /*****************************************************************************
92 * Open: check file and initializes structures
93 *****************************************************************************/
94 static int Open( vlc_object_t
* p_this
)
96 demux_t
*p_demux
= (demux_t
*)p_this
;
99 const uint8_t *p_peek
;
102 uint64_t i_data_size
;
103 unsigned int i_extended
;
104 const char *psz_name
;
106 WAVEFORMATEXTENSIBLE
*p_wf_ext
= NULL
;
107 WAVEFORMATEX
*p_wf
= NULL
;
109 /* Is it a wav file ? */
110 if( vlc_stream_Peek( p_demux
->s
, &p_peek
, 12 ) < 12 )
113 b_is_rf64
= ( memcmp( p_peek
, "RF64", 4 ) == 0 );
114 if( ( !b_is_rf64
&& memcmp( p_peek
, "RIFF", 4 ) ) ||
115 memcmp( &p_peek
[8], "WAVE", 4 ) )
120 p_demux
->pf_demux
= Demux
;
121 p_demux
->pf_control
= Control
;
122 p_demux
->p_sys
= p_sys
= malloc( sizeof( *p_sys
) );
123 if( unlikely(!p_sys
) )
126 es_format_Init( &p_sys
->fmt
, AUDIO_ES
, 0 );
128 p_sys
->i_data_size
= 0;
129 p_sys
->i_chans_to_reorder
= 0;
130 p_sys
->i_channel_mask
= 0;
132 /* skip riff header */
133 if( vlc_stream_Read( p_demux
->s
, NULL
, 12 ) != 12 )
138 /* search datasize64 chunk */
139 if( ChunkFind( p_demux
, "ds64", &i_size
) )
141 msg_Err( p_demux
, "cannot find 'ds64' chunk" );
146 msg_Err( p_demux
, "invalid 'ds64' chunk" );
149 if( vlc_stream_Read( p_demux
->s
, NULL
, 8 ) != 8 )
151 if( vlc_stream_Peek( p_demux
->s
, &p_peek
, 24 ) < 24 )
153 i_data_size
= GetQWLE( &p_peek
[8] );
154 if( i_data_size
>> 62 )
155 p_sys
->i_data_size
= (int64_t)1 << 62;
157 p_sys
->i_data_size
= i_data_size
;
158 if( vlc_stream_Read( p_demux
->s
, NULL
, i_size
) != (int)i_size
||
159 ( (i_size
& 1) && vlc_stream_Read( p_demux
->s
, NULL
, 1 ) != 1 ) )
163 /* search fmt chunk */
164 if( ChunkFind( p_demux
, "fmt ", &i_size
) )
166 msg_Err( p_demux
, "cannot find 'fmt ' chunk" );
170 if( i_size
< sizeof( WAVEFORMATEX
) )
172 msg_Err( p_demux
, "invalid 'fmt ' chunk" );
175 if( vlc_stream_Read( p_demux
->s
, NULL
, 8 ) != 8 )
179 /* load waveformatex */
180 p_wf_ext
= malloc( i_size
);
181 if( unlikely( !p_wf_ext
) )
184 p_wf
= &p_wf_ext
->Format
;
187 if( vlc_stream_Read( p_demux
->s
, p_wf
, i_size
) != (int)i_size
||
188 ( ( i_size
& 1 ) && vlc_stream_Read( p_demux
->s
, NULL
, 1 ) != 1 ) )
190 msg_Err( p_demux
, "cannot load 'fmt ' chunk" );
194 wf_tag_to_fourcc( GetWLE( &p_wf
->wFormatTag
), &p_sys
->fmt
.i_codec
,
196 p_sys
->fmt
.audio
.i_channels
= GetWLE ( &p_wf
->nChannels
);
197 p_sys
->fmt
.audio
.i_rate
= GetDWLE( &p_wf
->nSamplesPerSec
);
198 p_sys
->fmt
.audio
.i_blockalign
= GetWLE( &p_wf
->nBlockAlign
);
199 p_sys
->fmt
.i_bitrate
= GetDWLE( &p_wf
->nAvgBytesPerSec
) * 8;
200 p_sys
->fmt
.audio
.i_bitspersample
= GetWLE( &p_wf
->wBitsPerSample
);
201 if( i_size
>= sizeof(WAVEFORMATEX
) )
202 p_sys
->fmt
.i_extra
= __MIN( GetWLE( &p_wf
->cbSize
), i_size
- sizeof(WAVEFORMATEX
) );
205 /* Handle new WAVE_FORMAT_EXTENSIBLE wav files */
206 /* see the following link for more information:
207 * http://www.microsoft.com/whdc/device/audio/multichaud.mspx#EFAA */
208 if( GetWLE( &p_wf
->wFormatTag
) == WAVE_FORMAT_EXTENSIBLE
&&
209 i_size
>= sizeof( WAVEFORMATEXTENSIBLE
) &&
210 ( p_sys
->fmt
.i_extra
+ sizeof( WAVEFORMATEX
)
211 >= sizeof( WAVEFORMATEXTENSIBLE
) ) )
213 unsigned i_channel_mask
;
216 guid_subformat
= p_wf_ext
->SubFormat
;
217 guid_subformat
.Data1
= GetDWLE( &p_wf_ext
->SubFormat
.Data1
);
218 guid_subformat
.Data2
= GetWLE( &p_wf_ext
->SubFormat
.Data2
);
219 guid_subformat
.Data3
= GetWLE( &p_wf_ext
->SubFormat
.Data3
);
221 sf_tag_to_fourcc( &guid_subformat
, &p_sys
->fmt
.i_codec
, &psz_name
);
223 msg_Dbg( p_demux
, "extensible format guid " GUID_FMT
, GUID_PRINT(guid_subformat
) );
225 i_extended
= sizeof( WAVEFORMATEXTENSIBLE
) - sizeof( WAVEFORMATEX
);
226 p_sys
->fmt
.i_extra
-= i_extended
;
228 i_channel_mask
= GetDWLE( &p_wf_ext
->dwChannelMask
);
232 p_sys
->i_channel_mask
= getChannelMask( &i_channel_mask
, p_sys
->fmt
.audio
.i_channels
, &i_match
);
234 msg_Warn( p_demux
, "Some channels are unrecognized or uselessly specified (0x%x)", i_channel_mask
);
235 if( i_match
< p_sys
->fmt
.audio
.i_channels
)
237 int i_missing
= p_sys
->fmt
.audio
.i_channels
- i_match
;
238 msg_Warn( p_demux
, "Trying to fill up unspecified position for %d channels", p_sys
->fmt
.audio
.i_channels
- i_match
);
240 static const uint32_t pi_pair
[] = { AOUT_CHAN_REARLEFT
|AOUT_CHAN_REARRIGHT
,
241 AOUT_CHAN_MIDDLELEFT
|AOUT_CHAN_MIDDLERIGHT
,
242 AOUT_CHAN_LEFT
|AOUT_CHAN_RIGHT
};
244 static const uint32_t pi_center[] = { AOUT_CHAN_REARCENTER,
246 AOUT_CHAN_CENTER }; */
248 /* Try to complete with pair */
249 for( unsigned i
= 0; i
< sizeof(pi_pair
)/sizeof(*pi_pair
); i
++ )
251 if( i_missing
>= 2 && !(p_sys
->i_channel_mask
& pi_pair
[i
] ) )
254 p_sys
->i_channel_mask
|= pi_pair
[i
];
257 /* Well fill up with what we can */
258 for( unsigned i
= 0; i
< sizeof(pi_channels_aout
)/sizeof(*pi_channels_aout
) && i_missing
> 0; i
++ )
260 if( !( p_sys
->i_channel_mask
& pi_channels_aout
[i
] ) )
262 p_sys
->i_channel_mask
|= pi_channels_aout
[i
];
270 i_match
= p_sys
->fmt
.audio
.i_channels
- i_missing
;
272 if( i_match
< p_sys
->fmt
.audio
.i_channels
)
274 msg_Err( p_demux
, "Invalid/unsupported channel mask" );
275 p_sys
->i_channel_mask
= 0;
279 if( p_sys
->i_channel_mask
== 0 && p_sys
->fmt
.audio
.i_channels
> 2
280 && p_sys
->fmt
.audio
.i_channels
<= AOUT_CHAN_MAX
)
282 /* A dwChannelMask of 0 tells the audio device to render the first
283 * channel to the first port on the device, the second channel to the
284 * second port on the device, and so on. pi_default_channels is
285 * different than pi_channels_aout. Indeed FLC/FRC must be treated a
286 * SL/SR in that case. See "Default Channel Ordering" and "Details
287 * about dwChannelMask" from msdn */
289 static const uint32_t pi_default_channels
[] = {
290 AOUT_CHAN_LEFT
, AOUT_CHAN_RIGHT
, AOUT_CHAN_CENTER
,
291 AOUT_CHAN_LFE
, AOUT_CHAN_REARLEFT
, AOUT_CHAN_REARRIGHT
,
292 AOUT_CHAN_MIDDLELEFT
, AOUT_CHAN_MIDDLERIGHT
, AOUT_CHAN_REARCENTER
};
294 for( unsigned i
= 0; i
< p_sys
->fmt
.audio
.i_channels
&&
295 i
< (sizeof(pi_default_channels
) / sizeof(*pi_default_channels
));
297 p_sys
->i_channel_mask
|= pi_default_channels
[i
];
300 if( p_sys
->i_channel_mask
)
302 if( p_sys
->fmt
.i_codec
== VLC_FOURCC('a','r','a','w') ||
303 p_sys
->fmt
.i_codec
== VLC_FOURCC('a','f','l','t') )
304 p_sys
->i_chans_to_reorder
=
305 aout_CheckChannelReorder( pi_channels_aout
, NULL
,
306 p_sys
->i_channel_mask
,
307 p_sys
->pi_chan_table
);
309 msg_Dbg( p_demux
, "channel mask: %x, reordering: %u",
310 p_sys
->i_channel_mask
, p_sys
->i_chans_to_reorder
);
313 p_sys
->fmt
.audio
.i_physical_channels
= p_sys
->i_channel_mask
;
315 if( p_sys
->fmt
.i_extra
> 0 )
317 p_sys
->fmt
.p_extra
= malloc( p_sys
->fmt
.i_extra
);
318 if( unlikely(!p_sys
->fmt
.p_extra
) )
320 p_sys
->fmt
.i_extra
= 0;
323 memcpy( p_sys
->fmt
.p_extra
, (uint8_t *)p_wf
+ sizeof( WAVEFORMATEX
) + i_extended
,
324 p_sys
->fmt
.i_extra
);
327 msg_Dbg( p_demux
, "format: 0x%4.4x, fourcc: %4.4s, channels: %d, "
328 "freq: %u Hz, bitrate: %uKo/s, blockalign: %d, bits/samples: %d, "
330 GetWLE( &p_wf
->wFormatTag
), (char *)&p_sys
->fmt
.i_codec
,
331 p_sys
->fmt
.audio
.i_channels
, p_sys
->fmt
.audio
.i_rate
,
332 p_sys
->fmt
.i_bitrate
/ 8 / 1024, p_sys
->fmt
.audio
.i_blockalign
,
333 p_sys
->fmt
.audio
.i_bitspersample
, p_sys
->fmt
.i_extra
);
338 switch( p_sys
->fmt
.i_codec
)
340 case VLC_FOURCC( 'a', 'r', 'a', 'w' ):
341 case VLC_FOURCC( 'a', 'f', 'l', 't' ):
342 case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
344 case VLC_CODEC_MULAW
:
345 if( FrameInfo_PCM( &p_sys
->i_frame_size
, &p_sys
->i_frame_samples
,
349 vlc_fourcc_GetCodecAudio( p_sys
->fmt
.i_codec
,
350 p_sys
->fmt
.audio
.i_bitspersample
);
351 if( p_sys
->fmt
.i_codec
== 0 ) {
352 msg_Err( p_demux
, "Unrecognized codec" );
356 case VLC_CODEC_ADPCM_MS
:
357 /* FIXME not sure at all FIXME */
358 case VLC_FOURCC( 'm', 's', 0x00, 0x61 ):
359 case VLC_FOURCC( 'm', 's', 0x00, 0x62 ):
360 if( FrameInfo_MS_ADPCM( &p_sys
->i_frame_size
, &p_sys
->i_frame_samples
,
364 case VLC_CODEC_ADPCM_IMA_WAV
:
365 if( FrameInfo_IMA_ADPCM( &p_sys
->i_frame_size
, &p_sys
->i_frame_samples
,
369 case VLC_CODEC_ADPCM_CREATIVE
:
370 if( FrameInfo_Creative_ADPCM( &p_sys
->i_frame_size
, &p_sys
->i_frame_samples
,
376 /* FIXME set end of area FIXME */
378 case VLC_CODEC_GSM_MS
:
379 case VLC_CODEC_ADPCM_G726
:
380 case VLC_CODEC_TRUESPEECH
:
381 case VLC_CODEC_ATRAC3P
:
382 case VLC_CODEC_ATRAC3
:
383 case VLC_CODEC_G723_1
:
385 if( FrameInfo_MSGSM( &p_sys
->i_frame_size
, &p_sys
->i_frame_samples
,
390 msg_Err( p_demux
, "unsupported codec (%4.4s)",
391 (char*)&p_sys
->fmt
.i_codec
);
395 if( p_sys
->i_frame_size
<= 0 || p_sys
->i_frame_samples
<= 0 )
397 msg_Dbg( p_demux
, "invalid frame size: %i %i", p_sys
->i_frame_size
,
398 p_sys
->i_frame_samples
);
401 if( p_sys
->fmt
.audio
.i_rate
== 0 )
403 msg_Dbg( p_demux
, "invalid sample rate: %i", p_sys
->fmt
.audio
.i_rate
);
407 msg_Dbg( p_demux
, "found %s audio format", psz_name
);
409 if( ChunkFind( p_demux
, "data", &i_size
) )
411 msg_Err( p_demux
, "cannot find 'data' chunk" );
414 if( !b_is_rf64
|| i_size
< UINT32_MAX
)
415 p_sys
->i_data_size
= i_size
;
416 if( vlc_stream_Read( p_demux
->s
, NULL
, 8 ) != 8 )
418 p_sys
->i_data_pos
= vlc_stream_Tell( p_demux
->s
);
420 if( p_sys
->fmt
.i_bitrate
<= 0 )
422 p_sys
->fmt
.i_bitrate
= (int64_t)p_sys
->i_frame_size
*
423 p_sys
->fmt
.audio
.i_rate
* 8 / p_sys
->i_frame_samples
;
426 p_sys
->p_es
= es_out_Add( p_demux
->out
, &p_sys
->fmt
);
428 date_Init( &p_sys
->pts
, p_sys
->fmt
.audio
.i_rate
, 1 );
429 date_Set( &p_sys
->pts
, 1 );
434 msg_Err( p_demux
, "An error occurred during wav demuxing" );
436 es_format_Clean( &p_sys
->fmt
);
441 /*****************************************************************************
442 * Demux: read packet and send them to decoders
443 *****************************************************************************
444 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
445 *****************************************************************************/
446 static int Demux( demux_t
*p_demux
)
448 demux_sys_t
*p_sys
= p_demux
->p_sys
;
450 const int64_t i_pos
= vlc_stream_Tell( p_demux
->s
);
451 unsigned int i_read_size
= p_sys
->i_frame_size
;
453 if( p_sys
->i_data_size
> 0 )
455 int64_t i_end
= p_sys
->i_data_pos
+ p_sys
->i_data_size
;
456 if ( i_pos
>= i_end
)
459 /* Don't read past data chunk boundary */
460 if ( i_end
< i_pos
+ i_read_size
)
461 i_read_size
= i_end
- i_pos
;
464 if( ( p_block
= vlc_stream_Block( p_demux
->s
, i_read_size
) ) == NULL
)
466 msg_Warn( p_demux
, "cannot read data" );
471 p_block
->i_pts
= VLC_TS_0
+ date_Get( &p_sys
->pts
);
474 es_out_SetPCR( p_demux
->out
, p_block
->i_pts
);
476 /* Do the channel reordering */
477 if( p_sys
->i_chans_to_reorder
)
478 aout_ChannelReorder( p_block
->p_buffer
, p_block
->i_buffer
,
479 p_sys
->fmt
.audio
.i_channels
,
480 p_sys
->pi_chan_table
, p_sys
->fmt
.i_codec
);
482 es_out_Send( p_demux
->out
, p_sys
->p_es
, p_block
);
484 date_Increment( &p_sys
->pts
, p_sys
->i_frame_samples
);
489 /*****************************************************************************
490 * Close: frees unused data
491 *****************************************************************************/
492 static void Close ( vlc_object_t
* p_this
)
494 demux_t
*p_demux
= (demux_t
*)p_this
;
495 demux_sys_t
*p_sys
= p_demux
->p_sys
;
497 es_format_Clean( &p_sys
->fmt
);
501 /*****************************************************************************
503 *****************************************************************************/
504 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
506 demux_sys_t
*p_sys
= p_demux
->p_sys
;
509 if( p_sys
->i_data_size
> 0 )
510 i_end
= p_sys
->i_data_pos
+ p_sys
->i_data_size
;
512 return demux_vaControlHelper( p_demux
->s
, p_sys
->i_data_pos
, i_end
,
513 p_sys
->fmt
.i_bitrate
,
514 p_sys
->fmt
.audio
.i_blockalign
,
518 /*****************************************************************************
520 *****************************************************************************/
521 static int ChunkFind( demux_t
*p_demux
, const char *fcc
, unsigned int *pi_size
)
523 const uint8_t *p_peek
;
529 if( vlc_stream_Peek( p_demux
->s
, &p_peek
, 8 ) < 8 )
531 msg_Err( p_demux
, "cannot peek" );
535 i_size
= GetDWLE( p_peek
+ 4 );
537 msg_Dbg( p_demux
, "chunk: fcc=`%4.4s` size=%"PRIu32
, p_peek
, i_size
);
539 if( !memcmp( p_peek
, fcc
, 4 ) )
549 if( vlc_stream_Read( p_demux
->s
, NULL
, 8 ) != 8 ||
550 vlc_stream_Read( p_demux
->s
, NULL
, i_size
) != (int)i_size
||
551 ( (i_size
& 1) && vlc_stream_Read( p_demux
->s
, NULL
, 1 ) != 1 ) )
556 static int FrameInfo_PCM( unsigned int *pi_size
, int *pi_samples
,
557 const es_format_t
*p_fmt
)
561 if( p_fmt
->audio
.i_rate
> 352800
562 || p_fmt
->audio
.i_bitspersample
> 64
563 || p_fmt
->audio
.i_channels
> WAV_CHAN_MAX
)
566 /* read samples for 50ms of */
567 *pi_samples
= __MAX( p_fmt
->audio
.i_rate
/ 20, 1 );
569 i_bytes
= *pi_samples
* p_fmt
->audio
.i_channels
*
570 ( (p_fmt
->audio
.i_bitspersample
+ 7) / 8 );
572 if( p_fmt
->audio
.i_blockalign
> 0 )
574 const int i_modulo
= i_bytes
% p_fmt
->audio
.i_blockalign
;
576 i_bytes
+= p_fmt
->audio
.i_blockalign
- i_modulo
;
583 static int FrameInfo_MS_ADPCM( unsigned int *pi_size
, int *pi_samples
,
584 const es_format_t
*p_fmt
)
586 if( p_fmt
->audio
.i_channels
== 0 )
589 *pi_samples
= 2 + 2 * ( p_fmt
->audio
.i_blockalign
-
590 7 * p_fmt
->audio
.i_channels
) / p_fmt
->audio
.i_channels
;
591 *pi_size
= p_fmt
->audio
.i_blockalign
;
596 static int FrameInfo_IMA_ADPCM( unsigned int *pi_size
, int *pi_samples
,
597 const es_format_t
*p_fmt
)
599 if( p_fmt
->audio
.i_channels
== 0 )
602 *pi_samples
= 2 * ( p_fmt
->audio
.i_blockalign
-
603 4 * p_fmt
->audio
.i_channels
) / p_fmt
->audio
.i_channels
;
604 *pi_size
= p_fmt
->audio
.i_blockalign
;
609 static int FrameInfo_Creative_ADPCM( unsigned int *pi_size
, int *pi_samples
,
610 const es_format_t
*p_fmt
)
612 if( p_fmt
->audio
.i_channels
== 0 )
615 /* 4 bits / sample */
616 *pi_samples
= p_fmt
->audio
.i_blockalign
* 2 / p_fmt
->audio
.i_channels
;
617 *pi_size
= p_fmt
->audio
.i_blockalign
;
622 static int FrameInfo_MSGSM( unsigned int *pi_size
, int *pi_samples
,
623 const es_format_t
*p_fmt
)
625 if( p_fmt
->i_bitrate
<= 0 )
628 *pi_samples
= ( p_fmt
->audio
.i_blockalign
* p_fmt
->audio
.i_rate
* 8)
630 *pi_size
= p_fmt
->audio
.i_blockalign
;