Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* $Id: vorbis_interface.c,v 1.16 2001/03/18 14:31:29 aleidinger Exp $ */
2
 
3
 
4
/* Compile lame with
5
 
6
#! /bin/bash
7
 
8
OGGVORBIS_ROOT=/home/cvs/vorbis
9
 
10
export CPPFLAGS="-I${OGGVORBIS_ROOT}/ogg/include -I${OGGVORBIS_ROOT}/vorbis/lib"
11
export CONFIG_DEFS="-DUSE_FFT3DN"
12
 
13
make clean
14
../configure
15
make
16
 
17
You can also do this with the "--with-vorbis" options in configure.
18
 
19
 */
20
 
21
#ifdef HAVE_CONFIG_H
22
# include <config.h>
23
#endif
24
 
25
/* LAME interface to libvorbis */
26
 
27
#ifdef HAVE_VORBIS
28
#include <stdlib.h>
29
#include <limits.h>
30
#include <time.h>
31
#include "vorbis/codec.h"
32
#include "modes/modes.h"
33
#include "lame.h"
34
#include "util.h"
35
 
36
#ifdef WITH_DMALLOC
37
#include <dmalloc.h>
38
#endif
39
 
40
short int  convbuffer [4096];  /* take 8 KByte out of the data segment, not the stack */
41
int        convsize;
42
 
43
ogg_sync_state    oy;  // sync and verify incoming physical bitstream
44
ogg_stream_state  os;  // take physical pages, weld into a logical stream of packets
45
ogg_page          og;  // one Ogg bitstream page. Vorbis packets are inside
46
ogg_packet        op;  // one raw packet of data for decode
47
vorbis_info       vi;  // struct that stores all the static vorbis bitstream settings
48
vorbis_comment    vc;  // struct that stores all the bitstream user comments
49
vorbis_dsp_state  vd;  // central working state for the packet->PCM decoder
50
vorbis_block      vb;  // local working space for packet->PCM decode
51
 
52
 
53
 
54
int lame_decode_ogg_initfile( lame_global_flags*  gfp,
55
                              FILE*               fd,
56
                              mp3data_struct*     mp3data )
57
{
58
 
59
  lame_internal_flags *gfc = gfp->internal_flags;
60
  char *buffer;
61
  int  bytes;
62
  int i;
63
 
64
 
65
  /********** Decode setup ************/
66
 
67
  ogg_sync_init(&oy); /* Now we can read pages */
68
 
69
 
70
  /* grab some data at the head of the stream.  We want the first page
71
     (which is guaranteed to be small and only contain the Vorbis
72
     stream initial header) We need the first page to get the stream
73
     serialno. */
74
 
75
  /* submit a 4k block to libvorbis' Ogg layer */
76
  buffer=ogg_sync_buffer(&oy,4096);
77
  bytes=fread(buffer,1,4096,fd);
78
  ogg_sync_wrote(&oy,bytes);
79
 
80
  /* Get the first page. */
81
  if(ogg_sync_pageout(&oy,&og)!=1){
82
    /* error case.  Must not be Vorbis data */
83
    ERRORF( gfc, "Error initializing Ogg bitstream data.\n" );
84
    return -1;
85
  }
86
 
87
  /* Get the serial number and set up the rest of decode. */
88
  /* serialno first; use it to set up a logical stream */
89
  ogg_stream_init(&os,ogg_page_serialno(&og));
90
 
91
  /* extract the initial header from the first page and verify that the
92
     Ogg bitstream is in fact Vorbis data */
93
 
94
  /* I handle the initial header first instead of just having the code
95
     read all three Vorbis headers at once because reading the initial
96
     header is an easy way to identify a Vorbis bitstream and it's
97
     useful to see that functionality seperated out. */
98
 
99
  vorbis_info_init(&vi);
100
  vorbis_comment_init(&vc);
101
  if(ogg_stream_pagein(&os,&og)<0){ 
102
    /* error; stream version mismatch perhaps */
103
    ERRORF( gfc, "Error reading first page of Ogg bitstream data.\n" );
104
    return -1;
105
  }
106
 
107
  if(ogg_stream_packetout(&os,&op)!=1){ 
108
    /* no page? must not be vorbis */
109
    ERRORF( gfc, "Error reading initial header packet.\n" );
110
    return -1;
111
  }
112
 
113
  if(vorbis_synthesis_headerin(&vi,&vc,&op)<0){ 
114
    /* error case; not a vorbis header */
115
    ERRORF( gfc, "This Ogg bitstream does not contain Vorbis "
116
	    "audio data.\n");
117
    return -1;
118
  }
119
 
120
  /* At this point, we're sure we're Vorbis.  We've set up the logical
121
     (Ogg) bitstream decoder.  Get the comment and codebook headers and
122
     set up the Vorbis decoder */
123
 
124
  /* The next two packets in order are the comment and codebook headers.
125
     They're likely large and may span multiple pages.  Thus we reead
126
     and submit data until we get our two pacakets, watching that no
127
     pages are missing.  If a page is missing, error out; losing a
128
     header page is the only place where missing data is fatal. */
129
 
130
  i=0;
131
  while(i<2){
132
    while(i<2){
133
      int result=ogg_sync_pageout(&oy,&og);
134
      if(result==0)break; /* Need more data */
135
      /* Don't complain about missing or corrupt data yet.  We'll
136
	 catch it at the packet output phase */
137
      if(result==1){
138
	ogg_stream_pagein(&os,&og); /* we can ignore any errors here
139
				       as they'll also become apparent
140
				       at packetout */
141
	while(i<2){
142
	  result=ogg_stream_packetout(&os,&op);
143
	  if(result==0)break;
144
	  if(result==-1){
145
	    /* Uh oh; data at some point was corrupted or missing!
146
	       We can't tolerate that in a header.  Die. */
147
	    ERRORF( gfc, "Corrupt secondary header.  Exiting.\n" );
148
	    return -1;
149
	  }
150
	  vorbis_synthesis_headerin(&vi,&vc,&op);
151
	  i++;
152
	}
153
      }
154
    }
155
    /* no harm in not checking before adding more */
156
    buffer=ogg_sync_buffer(&oy,4096);
157
    bytes=fread(buffer,1,4096,fd);
158
    if(bytes==0 && i<2){
159
      ERRORF( gfc, "End of file before finding all Vorbis headers!\n" );
160
      return -1;
161
    }
162
    ogg_sync_wrote(&oy,bytes);
163
  }
164
 
165
  /* Throw the comments plus a few lines about the bitstream we're
166
     decoding */
167
  {
168
    /*
169
    char **ptr=vc.user_comments;
170
    while(*ptr){
171
      MSGF( gfc, "%s\n", *ptr );
172
      ++ptr;
173
    }
174
    MSGF( gfc, "\nBitstream is %d channel, %ldHz\n", vi.channels, vi.rate );
175
    MSGF( gfc, "Encoded by: %s\n\n", vc.vendor );
176
    */
177
  }
178
 
179
 
180
  /* OK, got and parsed all three headers. Initialize the Vorbis
181
     packet->PCM decoder. */
182
  vorbis_synthesis_init(&vd,&vi); /* central decode state */
183
  vorbis_block_init(&vd,&vb);     /* local state for most of the decode
184
				     so multiple block decodes can
185
				     proceed in parallel.  We could init
186
				     multiple vorbis_block structures
187
				     for vd here */
188
 
189
  mp3data->stereo = vi.channels;
190
  mp3data->samplerate = vi.rate;
191
  mp3data->bitrate = 0; //ov_bitrate_instant(&vf);
192
  mp3data->nsamp=MAX_U_32_NUM;
193
 
194
  return 0;
195
}
196
 
197
 
198
 
199
/*
200
  For lame_decode_fromfile:  return code
201
  -1     error, or eof
202
 
203
  n     number of samples output.  
204
*/
205
int lame_decode_ogg_fromfile( lame_global_flags*  gfp,
206
                              FILE*               fd,
207
                              short int           pcm_l[],
208
                              short int           pcm_r[],
209
                              mp3data_struct*     mp3data )
210
{
211
  lame_internal_flags *gfc = gfp->internal_flags;
212
  int samples,result,i,j,eof=0,eos=0,bout=0;
213
  double **pcm;
214
 
215
  while(1){
216
 
217
    /* 
218
    **pcm is a multichannel double vector.  In stereo, for
219
    example, pcm[0] is left, and pcm[1] is right.  samples is
220
    the size of each channel.  Convert the float values
221
    (-1.<=range<=1.) to whatever PCM format and write it out */
222
    /* unpack the buffer, if it has at least 1024 samples */
223
    convsize=1024;
224
    samples=vorbis_synthesis_pcmout(&vd,&pcm);
225
    if (samples >= convsize || eos || eof) {
226
      /* read 1024 samples, or if eos, read what ever is in buffer */
227
      int clipflag=0;
228
      bout=(samples<convsize?samples:convsize);
229
 
230
      /* convert doubles to 16 bit signed ints (host order) and
231
	 interleave */
232
      for(i=0;i<vi.channels;i++){
233
	double  *mono=pcm[i];
234
	for(j=0;j<bout;j++){
235
	  int val=mono[j]*32767.;
236
	  /* might as well guard against clipping */
237
	  if(val>32767){
238
	    val=32767;
239
	    clipflag=1;
240
	  }
241
	  if(val<-32768){
242
	    val=-32768;
243
	    clipflag=1;
244
	  }
245
	  if (i==0) pcm_l[j]=val;
246
	  if (i==1) pcm_r[j]=val;
247
	}
248
      }
249
 
250
      /*
251
      if(clipflag)
252
	MSGF( gfc, "Clipping in frame %ld\n", vd.sequence );
253
      */
254
 
255
      /* tell libvorbis how many samples we actually consumed */
256
      vorbis_synthesis_read(&vd,bout); 
257
 
258
      break;
259
    }    
260
 
261
    result=ogg_sync_pageout(&oy,&og);
262
 
263
    if(result==0) {
264
      /* need more data */
265
    }else if (result==-1){ /* missing or corrupt data at this page position */
266
      ERRORF( gfc, "Corrupt or missing data in bitstream; "
267
	      "continuing...\n");
268
    }else{
269
      /* decode this page */
270
      ogg_stream_pagein(&os,&og); /* can safely ignore errors at
271
				       this point */
272
      do {
273
	result=ogg_stream_packetout(&os,&op);
274
	if(result==0) {
275
	  /* need more data */
276
	} else if(result==-1){ /* missing or corrupt data at this page position */
277
	  /* no reason to complain; already complained above */
278
	}else{
279
	  /* we have a packet.  Decode it */
280
	  vorbis_synthesis(&vb,&op);
281
	  vorbis_synthesis_blockin(&vd,&vb);
282
	}
283
      } while (result!=0);
284
    }
285
 
286
    /* is this the last page? */    
287
    if(ogg_page_eos(&og))eos=1;
288
 
289
    if(!eos){
290
      char *buffer;
291
      int bytes;
292
      buffer=ogg_sync_buffer(&oy,4096);
293
      bytes=fread(buffer,1,4096,fd);
294
      ogg_sync_wrote(&oy,bytes);
295
      if(bytes==0)eof=1;
296
    }
297
  }
298
 
299
  mp3data->stereo = vi.channels;
300
  mp3data->samplerate = vi.rate;
301
  mp3data->bitrate = 0; //ov_bitrate_instant(&vf);
302
  /*  mp3data->nsamp=MAX_U_32_NUM;*/
303
 
304
 
305
  if (bout==0) {
306
    /* clean up this logical bitstream; before exit we see if we're
307
       followed by another [chained] */
308
    ogg_stream_clear(&os);
309
 
310
    /* ogg_page and ogg_packet structs always point to storage in
311
       libvorbis.  They're never freed or manipulated directly */
312
 
313
    vorbis_block_clear(&vb);
314
    vorbis_dsp_clear(&vd);
315
    vorbis_info_clear(&vi);  /* must be called last */
316
 
317
    /* OK, clean up the framer */
318
    ogg_sync_clear(&oy);
319
    return -1;
320
  }
321
  return bout;
322
}
323
 
324
 
325
 
326
 
327
 
328
 
329
 
330
 
331
 
332
 
333
 
334
 
335
 
336
ogg_stream_state  os2;  // take physical pages, weld into a logical stream of packets
337
ogg_page          og2;  // one Ogg bitstream page. Vorbis packets are inside
338
ogg_packet        op2;  // one raw packet of data for decode
339
 
340
vorbis_info       vi2;  // struct that stores all the static vorbis bitstream settings
341
vorbis_comment    vc2;  // struct that stores all the bitstream user comments
342
vorbis_dsp_state  vd2;  // central working state for the packet->PCM decoder
343
vorbis_block      vb2;  // local working space for packet->PCM decode
344
 
345
 
346
 
347
 
348
#define MAX_COMMENT_LENGTH 255
349
 
350
int lame_encode_ogg_init(lame_global_flags *gfp)
351
{
352
  lame_internal_flags *gfc=gfp->internal_flags;
353
  char comment[MAX_COMMENT_LENGTH+1];
354
 
355
 
356
  /********** Encode setup ************/
357
 
358
  /* choose an encoding mode */
359
  /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
360
  if (gfp->compression_ratio < 5.01) {
361
    memcpy(&vi2,&info_E,sizeof(vi2));
362
    MSGF( gfc, "Encoding with Vorbis mode info_E \n" );
363
  } else if (gfp->compression_ratio < 6) {
364
    memcpy(&vi2,&info_D,sizeof(vi2));
365
    MSGF( gfc, "Encoding with Vorbis mode info_D \n" );
366
  } else if (gfp->compression_ratio < 8) {
367
    memcpy(&vi2,&info_C,sizeof(vi2));
368
    MSGF( gfc, "Encoding with Vorbis mode info_C \n" );
369
  } else if (gfp->compression_ratio < 10) {
370
    memcpy(&vi2,&info_B,sizeof(vi2));
371
    MSGF( gfc, "Encoding with Vorbis mode info_B \n" );
372
  } else if (gfp->compression_ratio < 12) {
373
    memcpy(&vi2,&info_A,sizeof(vi2));
374
    MSGF( gfc, "Encoding with Vorbis mode info_A \n" );
375
  } else {
376
    memcpy(&vi2,&info_A,sizeof(vi2));
377
    MSGF( gfc, "Encoding with Vorbis mode info_A \n" );
378
  }
379
 
380
  vi2.channels = gfc->channels_out;
381
  vi2.rate = gfp->out_samplerate;
382
 
383
 
384
  /* add a comment */
385
  vorbis_comment_init(&vc2);
386
  vorbis_comment_add(&vc2,"Track encoded using L.A.M.E. libvorbis interface.");
387
 
388
  /* Add ID3-style comments to the output using (for the time being) the
389
     "private data members" in the "id3tag_spec" data structure. This was
390
     from a patch by Ralph Giles <giles@a3a32260.sympatico.bconnected.net> */
391
 
392
#ifdef THIS_CODE_IS_NOT_BROKEN_ANYMORE     
393
  if(gfp->tag_spec.title) {
394
    strcpy(comment,"TITLE=");
395
    strncat(comment,gfp->tag_spec.title,MAX_COMMENT_LENGTH-strlen(comment));
396
    vorbis_comment_add(&vc2,comment);
397
  }
398
  if(gfp->tag_spec.artist) {
399
    strcpy(comment,"ARTIST=");
400
    strncat(comment,gfp->tag_spec.artist,MAX_COMMENT_LENGTH-strlen(comment));
401
    vorbis_comment_add(&vc2,comment);
402
  }
403
  if(gfp->tag_spec.album) {
404
    strcpy(comment,"ALBUM=");
405
    strncat(comment,gfp->tag_spec.album,MAX_COMMENT_LENGTH-strlen(comment));
406
    vorbis_comment_add(&vc2,comment);
407
  }
408
  /* pretend that the ID3 fields are equivalent to the Vorbis fields */
409
  if(gfp->tag_spec.year) {
410
    sprintf(comment, "DATE=%d", gfp->tag_spec.year);
411
    vorbis_comment_add(&vc2,comment);
412
  }
413
  if(gfp->tag_spec.comment) {
414
    strcpy(comment,"DESCRIPTION=");
415
    strncat(comment,gfp->tag_spec.comment,MAX_COMMENT_LENGTH-strlen(comment));
416
    vorbis_comment_add(&vc2,comment);
417
  }
418
  /* TODO -- support for track and genre */
419
#endif  
420
 
421
  /* set up the analysis state and auxiliary encoding storage */
422
  vorbis_analysis_init(&vd2,&vi2);
423
  vorbis_block_init(&vd2,&vb2);
424
 
425
  /* set up our packet->stream encoder */
426
  /* pick a random serial number; that way we can more likely build
427
     chained streams just by concatenation */
428
  srand(time(NULL));
429
  ogg_stream_init(&os2,rand());
430
 
431
  /* Vorbis streams begin with three headers; the initial header (with
432
     most of the codec setup parameters) which is mandated by the Ogg
433
     bitstream spec.  The second header holds any comment fields.  The
434
     third header holds the bitstream codebook.  We merely need to
435
     make the headers, then pass them to libvorbis one at a time;
436
     libvorbis handles the additional Ogg bitstream constraints */
437
 
438
  {
439
    ogg_packet header;
440
    ogg_packet header_comm;
441
    ogg_packet header_code;
442
 
443
    vorbis_analysis_headerout(&vd2,&vc2,&header,&header_comm,&header_code);
444
    ogg_stream_packetin(&os2,&header); /* automatically placed in its own
445
					 page */
446
    ogg_stream_packetin(&os2,&header_comm);
447
    ogg_stream_packetin(&os2,&header_code);
448
 
449
    /* no need to write out here.  We'll get to that in the main loop */
450
  }
451
 
452
  return 0;
453
}
454
 
455
 
456
 
457
int lame_encode_ogg_finish(lame_global_flags *gfp,
458
			  char *mp3buf, int mp3buf_size)
459
{
460
  int eos=0,bytes=0;
461
 
462
  vorbis_analysis_wrote(&vd2,0);
463
 
464
  while(vorbis_analysis_blockout(&vd2,&vb2)==1){
465
 
466
    /* analysis */
467
    vorbis_analysis(&vb2,&op2);
468
 
469
      /* weld the packet into the bitstream */
470
      ogg_stream_packetin(&os2,&op2);
471
 
472
      /* write out pages (if any) */
473
      while(!eos){
474
	int result=ogg_stream_pageout(&os2,&og2);
475
	if(result==0)break;
476
 
477
 
478
	/* check if mp3buffer is big enough for the output */
479
	bytes += og2.header_len + og2.body_len;
480
	if (bytes > mp3buf_size && mp3buf_size>0)
481
	  return -5;
482
 
483
	memcpy(mp3buf,og2.header,og2.header_len);
484
	memcpy(mp3buf+og2.header_len,og2.body,og2.body_len);
485
 
486
	/* this could be set above, but for illustrative purposes, I do
487
	   it here (to show that vorbis does know where the stream ends) */
488
	if(ogg_page_eos(&og2))eos=1;
489
 
490
      }
491
    }
492
 
493
 
494
  /* clean up and exit.  vorbis_info_clear() must be called last */
495
  ogg_stream_clear(&os2);
496
  vorbis_block_clear(&vb2);
497
  vorbis_dsp_clear(&vd2);
498
 
499
 
500
  /* ogg_page and ogg_packet structs always point to storage in
501
     libvorbis.  They're never freed or manipulated directly */
502
  return bytes;
503
 
504
}
505
 
506
 
507
 
508
int  lame_encode_ogg_frame (
509
	lame_global_flags*  gfp,
510
	const sample_t*     inbuf_l, 
511
	const sample_t*     inbuf_r,
512
	unsigned char*      mp3buf, 
513
	size_t              mp3buf_size )
514
{
515
    lame_internal_flags *gfc = gfp->internal_flags;
516
    int  i;
517
    int  eos   = 0;
518
    int  bytes = 0;
519
 
520
    /* expose the buffer to submit data */
521
    double **buffer = vorbis_analysis_buffer(&vd2,gfp->framesize);
522
 
523
    /* change level of input by -90 dB (no de-interleaving!) */
524
    for ( i = 0; i < gfp->framesize; i++ )
525
        buffer [0] [i] = (1/32768.) * inbuf_l [i];
526
    if ( gfc->channels_out == 2 )
527
        for ( i = 0; i < gfp->framesize; i++ )
528
            buffer [1] [i] = (1/32768.) * inbuf_r [i];
529
 
530
  /* tell the library how much we actually submitted */
531
  vorbis_analysis_wrote(&vd2,i);
532
 
533
  /* vorbis does some data preanalysis, then divvies up blocks for
534
     more involved (potentially parallel) processing.  Get a single
535
     block for encoding now */
536
  while(vorbis_analysis_blockout(&vd2,&vb2)==1){
537
    int result;
538
    /* analysis */
539
    vorbis_analysis(&vb2,&op2);
540
 
541
    /* weld the packet into the bitstream */
542
    ogg_stream_packetin(&os2,&op2);
543
 
544
    /* write out pages (if any) */
545
    do {
546
      result=ogg_stream_pageout(&os2,&og2);
547
      if (result==0) break;
548
 
549
      /* check if mp3buffer is big enough for the output */
550
      bytes += og2.header_len + og2.body_len;
551
      /*
552
      DEBUGF("\n\n*********\ndecoded bytes=%i  %i \n",bytes,mp3buf_size);
553
      */
554
      if (bytes > mp3buf_size && mp3buf_size>0)
555
	return -6;
556
 
557
      memcpy(mp3buf,og2.header,og2.header_len);
558
      memcpy(mp3buf+og2.header_len,og2.body,og2.body_len);
559
      mp3buf += og2.header_len + og2.body_len;
560
 
561
      if(ogg_page_eos(&og2))eos=1;
562
    } while (1);
563
  }
564
  (gfp -> frameNum)++;
565
  return bytes;
566
}
567
 
568
#endif
569
 
570
/* end of vorbis_interface.c */
571