Commit a9098e45 authored by Gildas Bazin's avatar Gildas Bazin

* modules/demux/wav.c: started support for WAVEFORMATEXTENSIBLE (aka multichannel).
   support for float32 format.
* include/codecs.h: added WAVEFORMATEXTENSIBLE structure.
* modules/codec/araw.c: fixes.
parent 5fd3dab4
......@@ -2,7 +2,7 @@
* codecs.h: codec related structures needed by the demuxers and decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: codecs.h,v 1.10 2004/01/25 18:17:08 zorglub Exp $
* $Id: codecs.h,v 1.11 2004/02/14 17:03:33 gbazin Exp $
*
* Author: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -26,6 +26,17 @@
/* Structures exported to the demuxers and decoders */
#if !(defined _GUID_DEFINED || defined GUID_DEFINED)
#define GUID_DEFINED
typedef struct _GUID
{
uint32_t Data1;
uint16_t Data2;
uint16_t Data3;
uint8_t Data4[8];
} GUID, *REFGUID, *LPGUID;
#endif /* GUID_DEFINED */
#ifndef _WAVEFORMATEX_
#define _WAVEFORMATEX_
typedef struct
......@@ -43,6 +54,47 @@ _WAVEFORMATEX {
} WAVEFORMATEX, *PWAVEFORMATEX, *NPWAVEFORMATEX, *LPWAVEFORMATEX;
#endif /* _WAVEFORMATEX_ */
#ifndef _WAVEFORMATEXTENSIBLE_
#define _WAVEFORMATEXTENSIBLE_
typedef struct
#ifdef HAVE_ATTRIBUTE_PACKED
__attribute__((__packed__))
#endif
_WAVEFORMATEXTENSIBLE {
WAVEFORMATEX Format;
union {
uint16_t wValidBitsPerSample;
uint16_t wSamplesPerBlock;
uint16_t wReserved;
} Samples;
uint32_t dwChannelMask;
GUID SubFormat;
} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE;
#endif /* _WAVEFORMATEXTENSIBLE_ */
#ifndef _WAVEHEADER_
#define _WAVEHEADER_
typedef struct
#ifdef HAVE_ATTRIBUTE_PACKED
__attribute__((__packed__))
#endif
_WAVEHEADER {
uint32_t MainChunkID;
uint32_t Length;
uint32_t ChunkTypeID;
uint32_t SubChunkID;
uint32_t SubChunkLength;
uint16_t Format;
uint16_t Modus;
uint32_t SampleFreq;
uint32_t BytesPerSec;
uint16_t BytesPerSample;
uint16_t BitsPerSample;
uint32_t DataChunkID;
uint32_t DataLength;
} WAVEHEADER;
#endif /* _WAVEHEADER_ */
#if !defined(_BITMAPINFOHEADER_) && !defined(WIN32)
#define _BITMAPINFOHEADER_
typedef struct
......@@ -113,6 +165,7 @@ wave_format_tag_to_fourcc[] =
{
{ WAVE_FORMAT_PCM, VLC_FOURCC( 'a', 'r', 'a', 'w' ), "Raw audio" },
{ WAVE_FORMAT_ADPCM, VLC_FOURCC( 'm', 's', 0x00,0x02), "Adpcm" },
{ WAVE_FORMAT_IEEE_FLOAT, VLC_FOURCC( 'f', 'l', '3', '2' ), "IEEE Float audio" },
{ WAVE_FORMAT_ALAW, VLC_FOURCC( 'a', 'l', 'a', 'w' ), "A-Law" },
{ WAVE_FORMAT_MULAW, VLC_FOURCC( 'm', 'l', 'a', 'w' ), "Mu-Law" },
{ WAVE_FORMAT_IMA_ADPCM,VLC_FOURCC( 'm', 's', 0x00,0x11), "Ima-Adpcm" },
......@@ -175,4 +228,3 @@ typedef struct es_sys_t
} subtitle_data_t;
#endif /* "codecs.h" */
......@@ -2,7 +2,7 @@
* file.c : audio output which writes the samples to a file
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: file.c,v 1.29 2004/02/06 18:15:44 gbazin Exp $
* $Id: file.c,v 1.30 2004/02/14 17:03:33 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
......@@ -38,23 +38,6 @@
#define FRAME_SIZE 2048
#define A52_FRAME_NB 1536
typedef struct WAVEHEADER
{
uint32_t MainChunkID; // it will be 'RIFF'
uint32_t Length;
uint32_t ChunkTypeID; // it will be 'WAVE'
uint32_t SubChunkID; // it will be 'fmt '
uint32_t SubChunkLength;
uint16_t Format;
uint16_t Modus;
uint32_t SampleFreq;
uint32_t BytesPerSec;
uint16_t BytesPerSample;
uint16_t BitsPerSample;
uint32_t DataChunkID; // it will be 'data'
uint32_t DataLength;
} WAVEHEADER;
/*****************************************************************************
* aout_sys_t: audio output method descriptor
*****************************************************************************
......
......@@ -2,7 +2,7 @@
* araw.c: Pseudo audio decoder; for raw pcm data
*****************************************************************************
* Copyright (C) 2001, 2003 VideoLAN
* $Id: araw.c,v 1.28 2004/01/25 20:40:59 gbazin Exp $
* $Id: araw.c,v 1.29 2004/02/14 17:03:32 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -62,15 +62,18 @@ struct decoder_sys_t
audio_date_t end_date;
};
static int pi_channels_maps[6] =
static int pi_channels_maps[7] =
{
0,
AOUT_CHAN_CENTER,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE
};
static int16_t ulawtos16[256] =
......@@ -157,6 +160,7 @@ static int DecoderOpen( vlc_object_t *p_this )
{
/* from wav/avi/asf file */
case VLC_FOURCC('a','r','a','w'):
case VLC_FOURCC('f','l','3','2'):
/* _signed_ big endian samples (mov)*/
case VLC_FOURCC('t','w','o','s'):
/* _signed_ little endian samples (mov)*/
......@@ -180,9 +184,9 @@ static int DecoderOpen( vlc_object_t *p_this )
}
if( p_dec->fmt_in.audio.i_channels <= 0 ||
p_dec->fmt_in.audio.i_channels > 5 )
p_dec->fmt_in.audio.i_channels > 6 )
{
msg_Err( p_dec, "bad channels count(1-5)" );
msg_Err( p_dec, "bad channels count(1-6)" );
return VLC_EGENERIC;
}
......@@ -198,16 +202,13 @@ static int DecoderOpen( vlc_object_t *p_this )
p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
p_dec->fmt_in.audio.i_bitspersample );
if( 0 /* p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT */ )
if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', '3', '2' ) )
{
switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
{
case 4:
p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
break;
case 8:
p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
break;
default:
msg_Err( p_dec, "bad parameters(bits/sample)" );
return VLC_EGENERIC;
......
......@@ -2,7 +2,7 @@
* wav.c : wav file input module for vlc
*****************************************************************************
* Copyright (C) 2001-2003 VideoLAN
* $Id: wav.c,v 1.12 2004/02/05 22:56:11 gbazin Exp $
* $Id: wav.c,v 1.13 2004/02/14 17:03:32 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -81,10 +81,12 @@ static int Open( vlc_object_t * p_this )
demux_sys_t *p_sys;
uint8_t *p_peek;
WAVEFORMATEX *p_wf;
unsigned int i_size;
unsigned int i_size, i_extended;
char *psz_name;
WAVEFORMATEXTENSIBLE *p_wf_ext;
WAVEFORMATEX *p_wf;
/* Is it a wav file ? */
if( input_Peek( p_input, &p_peek, 12 ) < 12 )
{
......@@ -93,7 +95,6 @@ static int Open( vlc_object_t * p_this )
}
if( strncmp( p_peek, "RIFF", 4 ) || strncmp( &p_peek[8], "WAVE", 4 ) )
{
msg_Warn( p_input, "WAV module discarded (not a valid file)" );
return VLC_EGENERIC;
}
......@@ -120,7 +121,7 @@ static int Open( vlc_object_t * p_this )
stream_Read( p_input->s, NULL, 8 ); /* cannot fail */
/* load waveformatex */
p_wf = malloc( __EVEN( i_size ) + 2 ); /* +2, for raw audio -> no cbSize */
p_wf = (WAVEFORMATEX *)p_wf_ext = malloc( __EVEN( i_size ) + 2 );
p_wf->cbSize = 0;
if( stream_Read( p_input->s,
p_wf, __EVEN( i_size ) ) < (int)__EVEN( i_size ) )
......@@ -134,29 +135,43 @@ static int Open( vlc_object_t * p_this )
&psz_name );
p_sys->fmt.audio.i_channels = GetWLE ( &p_wf->nChannels );
p_sys->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
p_sys->fmt.audio.i_blockalign = GetWLE ( &p_wf->nBlockAlign );
p_sys->fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign );
p_sys->fmt.i_bitrate = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
p_sys->fmt.audio.i_bitspersample = GetWLE ( &p_wf->wBitsPerSample );;
p_sys->fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample );
p_sys->fmt.i_extra = GetWLE( &p_wf->cbSize );
i_extended = 0;
/* Handle new WAVE_FORMAT_EXTENSIBLE wav files */
if( GetWLE( &p_wf->wFormatTag ) == WAVE_FORMAT_EXTENSIBLE &&
i_size >= sizeof( WAVEFORMATEXTENSIBLE ) - 2 )
{
wf_tag_to_fourcc( GetWLE( &p_wf_ext->SubFormat ),
&p_sys->fmt.i_codec, &psz_name );
i_extended = sizeof( WAVEFORMATEXTENSIBLE ) - sizeof( WAVEFORMATEX );
p_sys->fmt.i_extra -= i_extended;
}
p_sys->fmt.i_extra = GetWLE ( &p_wf->cbSize );
if( p_sys->fmt.i_extra > 0 )
{
p_sys->fmt.p_extra = malloc( p_sys->fmt.i_extra );
memcpy( p_sys->fmt.p_extra, &p_wf[1], p_sys->fmt.i_extra );
memcpy( p_sys->fmt.p_extra, ((uint8_t *)p_wf) + i_extended,
p_sys->fmt.i_extra );
}
msg_Dbg( p_input, "format:0x%4.4x channels:%d %dHz %dKo/s "
"blockalign:%d bits/samples:%d extra size:%d",
GetWLE( &p_wf->wFormatTag ), p_sys->fmt.audio.i_channels,
p_sys->fmt.audio.i_rate, p_sys->fmt.i_bitrate / 8 / 1024,
p_sys->fmt.audio.i_blockalign, p_sys->fmt.audio.i_bitspersample,
p_sys->fmt.i_extra );
msg_Dbg( p_input, "format: 0x%4.4x fourcc: %4.4s channels: %d "
"freq: %d Hz bitrate: %dKo/s blockalign: %d bits/samples: %d "
"extra size: %d",
GetWLE( &p_wf->wFormatTag ), (char *)&p_sys->fmt.i_codec,
p_sys->fmt.audio.i_channels, p_sys->fmt.audio.i_rate,
p_sys->fmt.i_bitrate / 8 / 1024, p_sys->fmt.audio.i_blockalign,
p_sys->fmt.audio.i_bitspersample, p_sys->fmt.i_extra );
free( p_wf );
switch( p_sys->fmt.i_codec )
{
case VLC_FOURCC( 'a', 'r', 'a', 'w' ):
case VLC_FOURCC( 'f', 'l', '3', '2' ):
case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
FrameInfo_PCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length );
......@@ -241,25 +256,26 @@ static int Demux( input_thread_t *p_input )
if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
{
i_pos = stream_Tell( p_input->s );
}
input_ClockManageRef( p_input, p_input->stream.p_selected_program,
p_sys->i_time * 9 / 100 );
i_pos = stream_Tell( p_input->s );
/* Check alignment */
if( p_sys->fmt.audio.i_blockalign != 0 &&
i_pos % p_sys->fmt.audio.i_blockalign )
{
i_pos = p_sys->fmt.audio.i_blockalign -
int i_skip = p_sys->fmt.audio.i_blockalign -
i_pos % p_sys->fmt.audio.i_blockalign;
/* Skip some data to realign the stream */
if( stream_Read( p_input->s, NULL, i_pos ) != i_pos )
if( stream_Read( p_input->s, NULL, i_skip ) != i_skip )
{
msg_Err( p_input, "stream_Sekk failed (cannot resync)" );
}
msg_Err( p_input, "failed to re-align stream" );
}
}
input_ClockManageRef( p_input, p_input->stream.p_selected_program,
p_sys->i_time * 9 / 100 );
i_pos = stream_Tell( p_input->s );
if( p_sys->i_data_size > 0 &&
i_pos >= p_sys->i_data_pos + p_sys->i_data_size )
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment