~ubuntu-branches/ubuntu/feisty/avidemux/feisty

« back to all changes in this revision

Viewing changes to avidemux/ADM_audiofilter/audioencoder_vorbis.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2006-12-15 17:13:20 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20061215171320-w79pvpehxx2fr217
Tags: 1:2.3.0-0.0ubuntu1
* Merge from debian-multimedia.org, remaining Ubuntu change:
  - desktop file,
  - no support for ccache and make -j.
* Closes Ubuntu: #69614.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
    copyright            : (C) 2006 by mean
 
3
    email                : fixounet@free.fr
 
4
 ***************************************************************************/
 
5
 
 
6
/***************************************************************************
 
7
 *                                                                         *
 
8
 *   This program is free software; you can redistribute it and/or modify  *
 
9
 *   it under the terms of the GNU General Public License as published by  *
 
10
 *   the Free Software Foundation; either version 2 of the License, or     *
 
11
 *   (at your option) any later version.                                   *
 
12
 *                                                                         *
 
13
 ***************************************************************************/
 
14
#include "config.h"
 
15
#ifdef USE_VORBIS
 
16
#include <stdio.h>
 
17
#include <stdlib.h>
 
18
#include <string.h>
 
19
#include <math.h>
 
20
 
 
21
#include <ADM_assert.h>
 
22
#include "ADM_library/default.h"
 
23
 
 
24
#include "audioprocess.hxx"
 
25
#include "audioeng_process.h"
 
26
#include "audioencoder.h"
 
27
//
 
28
#include "ADM_audiofilter/audioencoder_vorbis_param.h"
 
29
#include "ADM_audiofilter/audioencoder_vorbis.h"
 
30
 
 
31
 
 
32
#include "vorbis/vorbisenc.h"
 
33
#include "ADM_toolkit/ADM_debugID.h"
 
34
#define MODULE_NAME MODULE_AUDIO_FILTER
 
35
#include "ADM_toolkit/ADM_debug.h"
 
36
 
 
37
 
 
38
#define OPTIONS (twolame_options_struct *)_twolameOptions
 
39
 
 
40
#define VD (((vorbisStruct *)_handle)->vd)
 
41
#define VI (((vorbisStruct *)_handle)->vi)
 
42
#define VB (((vorbisStruct *)_handle)->vb)
 
43
#define VC (((vorbisStruct *)_handle)->vc)
 
44
typedef struct vorbisStruct
 
45
 
46
        vorbis_info      vi ;
 
47
        vorbis_dsp_state vd ;
 
48
        vorbis_block     vb ;
 
49
        vorbis_comment   vc ;
 
50
}vorbisStruct;
 
51
//__________
 
52
 
 
53
AUDMEncoder_Vorbis::AUDMEncoder_Vorbis(AUDMAudioFilter * instream)  :AUDMEncoder    (instream)
 
54
{
 
55
  printf("[Vorbis] Creating Vorbis\n");
 
56
  _handle=NULL;
 
57
  _wavheader->encoding=WAV_OGG;
 
58
  _oldpos=0;
 
59
  _handle=(void *)new  vorbisStruct; 
 
60
  ch_order[0] = CH_FRONT_LEFT;
 
61
  ch_order[1] = CH_FRONT_RIGHT;
 
62
  ch_order[2] = CH_REAR_LEFT;
 
63
  ch_order[3] = CH_REAR_RIGHT;
 
64
  ch_order[4] = CH_FRONT_CENTER;
 
65
  ch_order[5] = CH_LFE;
 
66
};
 
67
 
 
68
 
 
69
AUDMEncoder_Vorbis::~AUDMEncoder_Vorbis()
 
70
{
 
71
  printf("[Vorbis] Deleting Vorbis\n");
 
72
  if(_handle)
 
73
  {
 
74
    vorbis_block_clear(&VB);
 
75
    vorbis_dsp_clear(&VD);
 
76
    vorbis_info_clear(&VI);
 
77
    delete (vorbisStruct *)_handle;
 
78
  }     
 
79
  _handle=NULL;
 
80
  
 
81
  cleanup();
 
82
};
 
83
 
 
84
//________________________________________________
 
85
//   Init lame encoder
 
86
// frequence    : Impose frequency , 0 means reuse the incoming fq
 
87
// mode                         : ADM_STEREO etc...
 
88
// bitrate              : Bitrate in kbps (96,192...)
 
89
// return 0 : init failed
 
90
//                              1 : init succeeded
 
91
//_______________________________________________
 
92
uint8_t AUDMEncoder_Vorbis::init(ADM_audioEncoderDescriptor *config)
 
93
{
 
94
  int ret;
 
95
  VORBIS_encoderParam *vorbisConf=(VORBIS_encoderParam *)config->param;
 
96
  ADM_assert(config->paramSize==sizeof(VORBIS_encoderParam));
 
97
 
 
98
  ogg_packet header1,header2,header3;
 
99
  int err;
 
100
 
 
101
  
 
102
  
 
103
  vorbis_info_init(&VI) ;
 
104
 
 
105
  switch(vorbisConf->mode)
 
106
  {
 
107
    case ADM_VORBIS_CBR:
 
108
                      err=vorbis_encode_init(&VI,
 
109
                              _wavheader->channels,
 
110
                              _wavheader->frequency,
 
111
                              -1, // Max bitrate      
 
112
                              config->bitrate*1000, //long nominal_bitrate,
 
113
                              -1 //long min_bitrate))
 
114
                            );
 
115
                      break;
 
116
    case  ADM_VORBIS_VBR :
 
117
                    err=vorbis_encode_init_vbr(&VI,
 
118
                                _wavheader->channels,
 
119
                                _wavheader->frequency,
 
120
                                vorbisConf->quality/10
 
121
                              );
 
122
                    break;
 
123
    default:
 
124
      ADM_assert(0);
 
125
  }
 
126
  if (err!=0) 
 
127
  {
 
128
    printf("[vorbis] init error %d\n",err);
 
129
    return 0;
 
130
  }
 
131
  vorbis_analysis_init(&VD, &VI) ;
 
132
  vorbis_block_init(&VD, &VB);
 
133
  vorbis_comment_init(&VC);
 
134
  vorbis_comment_add_tag(&VC, "encoder", "AVIDEMUX2") ;
 
135
 
 
136
  vorbis_analysis_headerout(&VD, &VC, &header1,
 
137
                             &header2, &header3);
 
138
 
 
139
 
 
140
// Store all headers as extra data
 
141
// see ogg vorbis decode for details
 
142
// we need 3 packets
 
143
 
 
144
  _extraSize=header1.bytes+header2.bytes+header3.bytes+3*sizeof(uint32_t);
 
145
  _extraData=new uint8_t[_extraSize];
 
146
 
 
147
  uint32_t *ex=(uint32_t *)_extraData;
 
148
  uint8_t *d;
 
149
  d=_extraData+sizeof(uint32_t)*3;
 
150
  ex[0]=header1.bytes;
 
151
  ex[1]=header2.bytes;
 
152
  ex[2]=header3.bytes;
 
153
  memcpy(d,header1.packet,ex[0]);
 
154
  d+=ex[0];
 
155
  memcpy(d,header2.packet,ex[1]);
 
156
  d+=ex[1];
 
157
  memcpy(d,header3.packet,ex[2]);
 
158
  vorbis_comment_clear(&VC);
 
159
                        
 
160
  printf("\n[Vorbis]Vorbis encoder initialized\n");
 
161
  switch(vorbisConf->mode)
 
162
  {
 
163
    case ADM_VORBIS_CBR:
 
164
      printf("[Vorbis]CBR Bitrate:%lu\n",config->bitrate);
 
165
      break;
 
166
    case ADM_VORBIS_VBR: //FIXME FIXME FIXME
 
167
      printf("[Vorbis]VBR Quality:%.1f\n",vorbisConf->quality);
 
168
    break;
 
169
    default:
 
170
      ADM_assert(0);
 
171
  }
 
172
   
 
173
  printf("[Vorbis]Channels  :%lu\n",_wavheader->channels);
 
174
  printf("[Vorbis]Frequency :%lu\n",_wavheader->frequency);
 
175
  return 1;
 
176
}
 
177
 
 
178
#define ROUNDMAX 3000
 
179
 
 
180
uint8_t AUDMEncoder_Vorbis::getPacket(uint8_t *dest, uint32_t *len, uint32_t *samples)
 
181
{
 
182
  uint32_t nbout;
 
183
  uint32_t consumed=0;
 
184
  float **float_samples;
 
185
  ogg_packet op ;
 
186
 
 
187
  *len = 0;
 
188
  _chunk=1024*_wavheader->channels;
 
189
  int count=ROUNDMAX;
 
190
// Check that we have packet from previous pass
 
191
  while(count--)
 
192
  {
 
193
    if(!refillBuffer(_chunk ))
 
194
    {
 
195
      return 0; 
 
196
    }
 
197
        
 
198
    if(tmptail-tmphead<_chunk)
 
199
    {
 
200
      return 0; 
 
201
    }
 
202
    
 
203
        //printf("Round %d\n",ROUNDMAX-count);
 
204
    if(vorbis_analysis_blockout(&VD, &VB) == 1) 
 
205
    {
 
206
      vorbis_analysis(&VB, NULL);
 
207
      vorbis_bitrate_addblock(&VB) ;
 
208
        //printf("Blockout\n");
 
209
        
 
210
      if(vorbis_bitrate_flushpacket(&VD, &op)) 
 
211
      {
 
212
        if(op.bytes<2) continue; // avoid the 1byte sized packet
 
213
 
 
214
        memcpy(dest, op.packet,op.bytes);
 
215
        *len=op.bytes;
 
216
        *samples=op.granulepos-_oldpos;
 
217
        _oldpos=op.granulepos;
 
218
        //  aprintf("1st packet :sampl:%lu len :%lu sample:%lu abs:%llu\n",*samples,op.bytes,total,op.granulepos);
 
219
        return 1;
 
220
      }
 
221
    }
 
222
 
 
223
    
 
224
    uint32_t nbSample=(tmptail-tmphead)/_wavheader->channels;
 
225
    if(nbSample>1024) nbSample=1024;
 
226
    float_samples=vorbis_analysis_buffer(&VD, nbSample) ;
 
227
    int index=tmphead;
 
228
    // Put our samples in incoming buffer
 
229
    for (int i = 0; i < nbSample; i++)
 
230
      for (int j = 0; j < _wavheader->channels; j++) {
 
231
      float_samples[j][i] = tmpbuffer[index++];
 
232
      if (float_samples[j][i] > 1) float_samples[j][i] = 1;
 
233
      if (float_samples[j][i] < -1) float_samples[j][i] = -1;
 
234
      }
 
235
      reorderChannels(&(tmpbuffer[tmphead]),tmptail-tmphead);
 
236
      // Buffer full, go go go
 
237
      vorbis_analysis_wrote(&VD, nbSample) ;  
 
238
      tmphead+=nbSample*_wavheader->channels;   
 
239
  }
 
240
  return 0;
 
241
        
 
242
}
 
243
#endif          
 
244
// EOF