1 /*****************************************************************************
2 * voc.c : Creative Voice File (.VOC) demux module for vlc
3 *****************************************************************************
4 * Copyright (C) 2005 Rémi Denis-Courmont
7 * Authors: Rémi Denis-Courmont <rem # videolan.org>
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 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_demux.h>
36 /*****************************************************************************
38 *****************************************************************************/
39 static int Open ( vlc_object_t
* );
40 static void Close( vlc_object_t
* );
43 set_description( N_("VOC demuxer") )
44 set_category( CAT_INPUT
)
45 set_subcategory( SUBCAT_INPUT_DEMUX
)
46 set_capability( "demux", 10 )
47 set_callbacks( Open
, Close
)
50 /*****************************************************************************
52 *****************************************************************************/
53 static int Demux ( demux_t
* );
54 static int Control( demux_t
*, int i_query
, va_list args
);
61 int64_t i_block_start
;
64 int64_t i_loop_offset
;
65 unsigned i_loop_count
;
66 unsigned i_silence_countdown
;
71 static const char ct_header
[] = "Creative Voice File\x1a";
73 /*****************************************************************************
74 * Open: check file and initializes structures
75 *****************************************************************************/
76 static int Open( vlc_object_t
* p_this
)
78 demux_t
*p_demux
= (demux_t
*)p_this
;
81 uint16_t i_data_offset
, i_version
;
83 if( vlc_stream_Peek( p_demux
->s
, &p_buf
, 26 ) < 26 )
86 if( memcmp( p_buf
, ct_header
, 20 ) )
90 i_data_offset
= GetWLE( p_buf
);
91 if ( i_data_offset
< 26 /* not enough room for full VOC header */ )
95 i_version
= GetWLE( p_buf
);
96 if( ( i_version
!= 0x10A ) && ( i_version
!= 0x114 ) )
97 return VLC_EGENERIC
; /* unknown VOC version */
100 if( GetWLE( p_buf
) != (uint16_t)(0x1234 + ~i_version
) )
103 /* We have a valid VOC header */
104 msg_Dbg( p_demux
, "CT Voice file v%d.%d", i_version
>> 8,
107 /* skip VOC header */
108 if( vlc_stream_Read( p_demux
->s
, NULL
, i_data_offset
) < i_data_offset
)
111 p_demux
->pf_demux
= Demux
;
112 p_demux
->pf_control
= Control
;
113 p_demux
->p_sys
= p_sys
= malloc( sizeof( demux_sys_t
) );
117 p_sys
->i_silence_countdown
= p_sys
->i_block_start
= p_sys
->i_block_end
=
118 p_sys
->i_loop_count
= 0;
121 date_Init( &p_sys
->pts
, 1, 1 );
122 date_Set( &p_sys
->pts
, 1 );
124 es_format_Init( &p_sys
->fmt
, AUDIO_ES
, 0 );
130 static int fmtcmp( es_format_t
*ofmt
, es_format_t
*nfmt
)
132 return (ofmt
->audio
.i_bitspersample
!= nfmt
->audio
.i_bitspersample
)
133 || (ofmt
->audio
.i_rate
!= nfmt
->audio
.i_rate
)
134 || (ofmt
->audio
.i_channels
!= nfmt
->audio
.i_channels
);
139 * Converts old-style VOC sample rates to commonly used ones
140 * so as not to confuse sound card drivers.
141 * (I assume 16k, 24k and 32k are never found in .VOC files)
143 static unsigned int fix_voc_sr( unsigned int sr
)
161 static int ReadBlockHeader( demux_t
*p_demux
)
165 int32_t i_block_size
;
166 demux_sys_t
*p_sys
= p_demux
->p_sys
;
168 if( vlc_stream_Read( p_demux
->s
, buf
, 4 ) < 4 )
169 return VLC_EGENERIC
; /* EOF */
171 i_block_size
= GetDWLE( buf
) >> 8;
172 msg_Dbg( p_demux
, "new block: type: %u, size: %u",
173 (unsigned)*buf
, i_block_size
);
175 es_format_Init( &new_fmt
, AUDIO_ES
, 0 );
179 case 0: /* not possible : caught with earlier vlc_stream_Read */
183 if( i_block_size
< 2 )
187 if( vlc_stream_Read( p_demux
->s
, buf
, 2 ) < 2 )
190 switch( buf
[1] ) /* codec id */
193 new_fmt
.i_codec
= VLC_CODEC_U8
;
194 new_fmt
.audio
.i_bytes_per_frame
= 1;
195 new_fmt
.audio
.i_bitspersample
= 8;
198 new_fmt
.i_codec
= VLC_CODEC_ADPCM_SBPRO_4
;
199 new_fmt
.audio
.i_bytes_per_frame
= 1;
200 new_fmt
.audio
.i_bitspersample
= 4;
203 new_fmt
.i_codec
= VLC_CODEC_ADPCM_SBPRO_3
;
204 new_fmt
.audio
.i_bytes_per_frame
= 3;
205 new_fmt
.audio
.i_bitspersample
= 3;
208 new_fmt
.i_codec
= VLC_CODEC_ADPCM_SBPRO_2
;
209 new_fmt
.audio
.i_bytes_per_frame
= 1;
210 new_fmt
.audio
.i_bitspersample
= 2;
213 new_fmt
.i_codec
= VLC_CODEC_S16L
;
214 new_fmt
.audio
.i_bytes_per_frame
= 2;
215 new_fmt
.audio
.i_bitspersample
= 16;
218 new_fmt
.i_codec
= VLC_CODEC_ALAW
;
219 new_fmt
.audio
.i_bytes_per_frame
= 1;
220 new_fmt
.audio
.i_bitspersample
= 8;
223 new_fmt
.i_codec
= VLC_CODEC_MULAW
;
224 new_fmt
.audio
.i_bytes_per_frame
= 1;
225 new_fmt
.audio
.i_bitspersample
= 8;
228 msg_Err( p_demux
, "unsupported compression 0x%"PRIx8
, buf
[1] );
232 new_fmt
.audio
.i_channels
= 1;
233 new_fmt
.audio
.i_bytes_per_frame
*= new_fmt
.audio
.i_channels
;
234 new_fmt
.audio
.i_blockalign
= new_fmt
.audio
.i_bytes_per_frame
;
236 new_fmt
.audio
.i_frame_length
= new_fmt
.audio
.i_bytes_per_frame
* 8
237 / new_fmt
.audio
.i_bitspersample
;
239 new_fmt
.audio
.i_rate
= fix_voc_sr( 1000000L / (256L - buf
[0]) );
240 new_fmt
.i_bitrate
= new_fmt
.audio
.i_rate
* new_fmt
.audio
.i_bitspersample
241 * new_fmt
.audio
.i_channels
;
245 case 2: /* data block with same format as the previous one */
246 if( p_sys
->p_es
== NULL
)
247 goto corrupt
; /* no previous block! */
249 memcpy( &new_fmt
, &p_sys
->fmt
, sizeof( new_fmt
) );
252 case 3: /* silence block */
253 if( ( i_block_size
!= 3 )
254 || ( vlc_stream_Read( p_demux
->s
, buf
, 3 ) < 3 ) )
258 p_sys
->i_silence_countdown
= GetWLE( buf
);
260 new_fmt
.i_codec
= VLC_CODEC_U8
;
261 new_fmt
.audio
.i_rate
= fix_voc_sr( 1000000L / (256L - buf
[0]) );
262 new_fmt
.audio
.i_bytes_per_frame
= 1;
263 new_fmt
.audio
.i_frame_length
= 1;
264 new_fmt
.audio
.i_channels
= 1;
265 new_fmt
.audio
.i_blockalign
= 1;
266 new_fmt
.audio
.i_bitspersample
= 8;
267 new_fmt
.i_bitrate
= new_fmt
.audio
.i_rate
* 8;
270 case 6: /* repeat block */
271 if( ( i_block_size
!= 2 )
272 || ( vlc_stream_Read( p_demux
->s
, buf
, 2 ) < 2 ) )
276 p_sys
->i_loop_count
= GetWLE( buf
);
277 p_sys
->i_loop_offset
= vlc_stream_Tell( p_demux
->s
);
280 case 7: /* repeat end block */
281 if( i_block_size
!= 0 )
284 if( p_sys
->i_loop_count
> 0 )
286 if( vlc_stream_Seek( p_demux
->s
, p_sys
->i_loop_offset
) )
287 msg_Warn( p_demux
, "cannot loop: seek failed" );
289 p_sys
->i_loop_count
--;
295 * Block 8 is a big kludge to add stereo support to block 1 :
296 * A block of type 8 is always followed by a block of type 1
297 * and specifies the number of channels in that 1-block
298 * (normally block 1 are always mono). In practice, block type 9
299 * is used for stereo rather than 8
301 if( ( i_block_size
!= 4 )
302 || ( vlc_stream_Read( p_demux
->s
, buf
, 4 ) < 4 ) )
307 msg_Err( p_demux
, "unsupported compression" );
311 new_fmt
.i_codec
= VLC_CODEC_U8
;
314 new_fmt
.audio
.i_channels
= buf
[3] + 1; /* can't be nul */
315 new_fmt
.audio
.i_rate
= 256000000L /
316 ((65536L - GetWLE(buf
)) * new_fmt
.audio
.i_channels
);
317 new_fmt
.audio
.i_bytes_per_frame
= new_fmt
.audio
.i_channels
;
318 new_fmt
.audio
.i_frame_length
= 1;
319 new_fmt
.audio
.i_blockalign
= new_fmt
.audio
.i_bytes_per_frame
;
320 new_fmt
.audio
.i_bitspersample
= 8 * new_fmt
.audio
.i_bytes_per_frame
;
321 new_fmt
.i_bitrate
= new_fmt
.audio
.i_rate
* 8;
323 /* read subsequent block 1 */
324 if( vlc_stream_Read( p_demux
->s
, buf
, 4 ) < 4 )
325 return VLC_EGENERIC
; /* EOF */
327 i_block_size
= GetDWLE( buf
) >> 8;
328 msg_Dbg( p_demux
, "new block: type: %u, size: %u",
329 (unsigned)*buf
, i_block_size
);
330 if( i_block_size
< 2 )
334 if( vlc_stream_Read( p_demux
->s
, buf
, 2 ) < 2 )
339 msg_Err( p_demux
, "unsupported compression" );
345 case 9: /* newer data block with channel number and bits resolution */
346 if( i_block_size
< 12 )
350 if( ( vlc_stream_Read( p_demux
->s
, buf
, 8 ) < 8 )
351 || ( vlc_stream_Read( p_demux
->s
, NULL
, 4 ) < 4 ) )
354 new_fmt
.audio
.i_rate
= GetDWLE( buf
);
355 new_fmt
.audio
.i_bitspersample
= buf
[4];
356 new_fmt
.audio
.i_channels
= buf
[5];
358 switch( GetWLE( &buf
[6] ) ) /* format */
360 case 0x0000: /* PCM */
361 switch( new_fmt
.audio
.i_bitspersample
)
364 new_fmt
.i_codec
= VLC_CODEC_U8
;
368 new_fmt
.i_codec
= VLC_CODEC_U16L
;
372 msg_Err( p_demux
, "unsupported bit res.: %u bits",
373 new_fmt
.audio
.i_bitspersample
);
378 case 0x0004: /* signed */
379 switch( new_fmt
.audio
.i_bitspersample
)
382 new_fmt
.i_codec
= VLC_CODEC_S8
;
386 new_fmt
.i_codec
= VLC_CODEC_S16L
;
390 msg_Err( p_demux
, "unsupported bit res.: %u bits",
391 new_fmt
.audio
.i_bitspersample
);
397 msg_Err( p_demux
, "unsupported compression" );
401 if( new_fmt
.audio
.i_channels
== 0 )
403 msg_Err( p_demux
, "0 channels detected" );
407 new_fmt
.audio
.i_bytes_per_frame
= new_fmt
.audio
.i_channels
408 * (new_fmt
.audio
.i_bitspersample
/ 8);
409 new_fmt
.audio
.i_frame_length
= 1;
410 new_fmt
.audio
.i_blockalign
= new_fmt
.audio
.i_bytes_per_frame
;
411 new_fmt
.i_bitrate
= 8 * new_fmt
.audio
.i_rate
412 * new_fmt
.audio
.i_bytes_per_frame
;
416 msg_Dbg( p_demux
, "unknown block type %u - skipping block",
419 case 4: /* blocks of non-audio types can be skipped */
421 if( vlc_stream_Read( p_demux
->s
, NULL
,
422 i_block_size
) < i_block_size
)
428 p_sys
->i_block_start
= vlc_stream_Tell( p_demux
->s
);
429 p_sys
->i_block_end
= p_sys
->i_block_start
+ i_block_size
;
431 if( i_block_size
|| p_sys
->i_silence_countdown
)
433 /* we've read a block with data in it - update decoder */
434 msg_Dbg( p_demux
, "fourcc: %4.4s, channels: %d, "
435 "freq: %d Hz, bitrate: %dKo/s, blockalign: %d, "
436 "bits/samples: %d", (char *)&new_fmt
.i_codec
,
437 new_fmt
.audio
.i_channels
, new_fmt
.audio
.i_rate
,
438 new_fmt
.i_bitrate
/ 8192, new_fmt
.audio
.i_blockalign
,
439 new_fmt
.audio
.i_bitspersample
);
441 if( ( p_sys
->p_es
!= NULL
) && fmtcmp( &p_sys
->fmt
, &new_fmt
) )
443 msg_Dbg( p_demux
, "codec change needed" );
444 es_out_Del( p_demux
->out
, p_sys
->p_es
);
448 if( p_sys
->p_es
== NULL
)
450 memcpy( &p_sys
->fmt
, &new_fmt
, sizeof( p_sys
->fmt
) );
451 date_Change( &p_sys
->pts
, p_sys
->fmt
.audio
.i_rate
, 1 );
452 p_sys
->p_es
= es_out_Add( p_demux
->out
, &p_sys
->fmt
);
459 msg_Err( p_demux
, "corrupted file - halting demux" );
463 /*****************************************************************************
464 * Demux: read packet and send them to decoders
465 *****************************************************************************
466 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
467 *****************************************************************************/
468 #define MAX_READ_FRAME 1000
469 static int Demux( demux_t
*p_demux
)
471 demux_sys_t
*p_sys
= p_demux
->p_sys
;
473 int64_t i_read_frames
;
475 if( p_sys
->i_silence_countdown
== 0 )
477 int64_t i_offset
= vlc_stream_Tell( p_demux
->s
);
478 if( i_offset
>= p_sys
->i_block_end
)
480 if( ReadBlockHeader( p_demux
) != VLC_SUCCESS
)
485 i_read_frames
= ( p_sys
->i_block_end
- i_offset
)
486 / p_sys
->fmt
.audio
.i_bytes_per_frame
;
488 if( i_read_frames
> MAX_READ_FRAME
)
489 i_read_frames
= MAX_READ_FRAME
;
491 p_block
= vlc_stream_Block( p_demux
->s
,
492 p_sys
->fmt
.audio
.i_bytes_per_frame
494 if( p_block
== NULL
)
496 msg_Warn( p_demux
, "cannot read data" );
501 { /* emulates silence from the stream */
502 i_read_frames
= p_sys
->i_silence_countdown
;
503 if( i_read_frames
> MAX_READ_FRAME
)
504 i_read_frames
= MAX_READ_FRAME
;
506 p_block
= block_Alloc( i_read_frames
);
507 if( p_block
== NULL
)
510 memset( p_block
->p_buffer
, 0, i_read_frames
);
511 p_sys
->i_silence_countdown
-= i_read_frames
;
514 p_block
->i_dts
= p_block
->i_pts
= VLC_TS_0
+ date_Get( &p_sys
->pts
);
515 p_block
->i_nb_samples
= i_read_frames
* p_sys
->fmt
.audio
.i_frame_length
;
516 date_Increment( &p_sys
->pts
, p_block
->i_nb_samples
);
517 es_out_SetPCR( p_demux
->out
, p_block
->i_pts
);
518 es_out_Send( p_demux
->out
, p_sys
->p_es
, p_block
);
523 /*****************************************************************************
524 * Close: frees unused data
525 *****************************************************************************/
526 static void Close ( vlc_object_t
* p_this
)
528 demux_sys_t
*p_sys
= ((demux_t
*)p_this
)->p_sys
;
533 /*****************************************************************************
535 *****************************************************************************/
536 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
538 demux_sys_t
*p_sys
= p_demux
->p_sys
;
540 return demux_vaControlHelper( p_demux
->s
, p_sys
->i_block_start
,
542 p_sys
->fmt
.i_bitrate
,
543 p_sys
->fmt
.audio
.i_blockalign
,