]> git.sesse.net Git - vlc/commitdiff
* modules/demux/wav.c: started support for WAVEFORMATEXTENSIBLE (aka multichannel).
authorGildas Bazin <gbazin@videolan.org>
Sat, 14 Feb 2004 17:03:33 +0000 (17:03 +0000)
committerGildas Bazin <gbazin@videolan.org>
Sat, 14 Feb 2004 17:03:33 +0000 (17:03 +0000)
   support for float32 format.
* include/codecs.h: added WAVEFORMATEXTENSIBLE structure.
* modules/codec/araw.c: fixes.

include/codecs.h
modules/audio_output/file.c
modules/codec/araw.c
modules/demux/wav.c

index 63b41326128765c127f1d496ec2eed3827cd0b61..82179f50f054703347279d6d82058539621c03c0 100644 (file)
@@ -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>
  *
 
 /* 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
@@ -100,7 +152,7 @@ typedef struct
 #define WAVE_FORMAT_DK4                 0x0062
 
 #if !defined(WAVE_FORMAT_EXTENSIBLE)
-#define  WAVE_FORMAT_EXTENSIBLE         0xFFFE /* Microsoft */
+#define WAVE_FORMAT_EXTENSIBLE          0xFFFE /* Microsoft */
 #endif
 
 static 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" */
-
index cd67348620961ddfa9412b3f8397d7a07e5ae79a..000110577c0b23f0d389c76b411b45b9c95b0f89 100644 (file)
@@ -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>
 #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
  *****************************************************************************
index 16133285ef2c327c77b10eda7aa60e04a6c373fd..219610c1f249e6a0fc7ba1115a8f600f9385a642 100644 (file)
@@ -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;
index af5c28b4c1c25971893b638014445be62906722d..8aef31e46ff3a21ddbd93dc36559e587bb90abd4 100644 (file)
@@ -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,18 +256,6 @@ 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 );
-        if( p_sys->fmt.audio.i_blockalign != 0 &&
-            i_pos % p_sys->fmt.audio.i_blockalign )
-        {
-            i_pos = 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 )
-            {
-                msg_Err( p_input, "stream_Sekk failed (cannot resync)" );
-            }
-        }
     }
 
     input_ClockManageRef( p_input, p_input->stream.p_selected_program,
@@ -260,6 +263,19 @@ static int Demux( input_thread_t *p_input )
 
     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 )
+    {
+        int i_skip = p_sys->fmt.audio.i_blockalign -
+            i_pos % p_sys->fmt.audio.i_blockalign;
+
+        if( stream_Read( p_input->s, NULL, i_skip ) != i_skip )
+        {
+            msg_Err( p_input, "failed to re-align stream" );
+        }
+    }
+
     if( p_sys->i_data_size > 0 &&
         i_pos >= p_sys->i_data_pos + p_sys->i_data_size )
     {