1 /*------------------------------------------------------------------------------
2 
3    Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
4 
5    Tyrell DarkIce
6 
7    File     : LameLibEncoder.h
8    Version  : $Revision$
9    Author   : $Author$
10    Location : $HeadURL$
11 
12    Copyright notice:
13 
14     This program is free software; you can redistribute it and/or
15     modify it under the terms of the GNU General Public License
16     as published by the Free Software Foundation; either version 3
17     of the License, or (at your option) any later version.
18 
19     This program is distributed in the hope that it will be useful,
20     but WITHOUT ANY WARRANTY; without even the implied warranty of
21     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22     GNU General Public License for more details.
23 
24     You should have received a copy of the GNU General Public License
25     along with this program; if not, write to the Free Software
26     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27 
28 ------------------------------------------------------------------------------*/
29 #ifndef LAME_LIB_ENCODER_H
30 #define LAME_LIB_ENCODER_H
31 
32 #ifndef __cplusplus
33 #error This is a C++ include file
34 #endif
35 
36 
37 /* ============================================================ include files */
38 
39 #ifdef HAVE_CONFIG_H
40 #include "config.h"
41 #endif
42 
43 #ifdef HAVE_LAME_LIB
44 #include <lame/lame.h>
45 #else
46 #error configure with lame
47 #endif
48 
49 
50 #include "Ref.h"
51 #include "Exception.h"
52 #include "Reporter.h"
53 #include "AudioEncoder.h"
54 #include "Sink.h"
55 
56 
57 /* ================================================================ constants */
58 
59 
60 /* =================================================================== macros */
61 
62 
63 /* =============================================================== data types */
64 
65 /**
66  *  A class representing the lame encoder linked as a shared object or as
67  *  a static library.
68  *
69  *  @author  $Author$
70  *  @version $Revision$
71  */
72 class LameLibEncoder : public AudioEncoder, public virtual Reporter
73 {
74     private:
75 
76         /**
77          *  Lame library global flags
78          */
79         lame_global_flags             * lameGlobalFlags;
80 
81         /**
82          *  Lowpass filter. Sound frequency in Hz, from where up the
83          *  input is cut.
84          */
85         int                             lowpass;
86 
87         /**
88          *  Highpass filter. Sound frequency in Hz, from where down the
89          *  input is cut.
90          */
91         int                             highpass;
92 
93         /**
94          *  Initialize the object.
95          *
96          *  @param lowpass frequency threshold for the lowpass filter.
97          *                 Input above this frequency is cut.
98          *                 If 0, lame's default values are used,
99          *                 which depends on the out sample rate.
100          *  @param highpass frequency threshold for the highpass filter.
101          *                  Input below this frequency is cut.
102          *                  If 0, lame's default values are used,
103          *                  which depends on the out sample rate.
104          *  @exception Exception
105          */
106         inline void
init(int lowpass,int highpass)107         init ( int              lowpass,
108                int              highpass )              throw ( Exception )
109         {
110             this->lameGlobalFlags = NULL;
111             this->lowpass         = lowpass;
112             this->highpass        = highpass;
113 
114             if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) {
115                 throw Exception( __FILE__, __LINE__,
116                                  "specified bits per sample not supported",
117                                  getInBitsPerSample() );
118             }
119 
120             if ( getInChannel() != 1 && getInChannel() != 2 ) {
121                 throw Exception( __FILE__, __LINE__,
122                          "unsupported number of input channels for the encoder",
123                                  getInChannel() );
124             }
125             if ( getOutChannel() != 1 && getOutChannel() != 2 ) {
126                 throw Exception( __FILE__, __LINE__,
127                         "unsupported number of output channels for the encoder",
128                                  getOutChannel() );
129             }
130             if ( getInChannel() < getOutChannel() ) {
131                 throw Exception( __FILE__, __LINE__,
132                                  "output channels greater then input channels",
133                                  getOutChannel() );
134             }
135         }
136 
137         /**
138          *  De-initialize the object.
139          *
140          *  @exception Exception
141          */
142         inline void
strip(void)143         strip ( void )                                  throw ( Exception )
144         {
145         }
146 
147 
148     protected:
149 
150         /**
151          *  Default constructor. Always throws an Exception.
152          *
153          *  @exception Exception
154          */
155         inline
LameLibEncoder(void)156         LameLibEncoder ( void )                         throw ( Exception )
157         {
158             throw Exception( __FILE__, __LINE__);
159         }
160 
161 
162     public:
163 
164         /**
165          *  Constructor.
166          *
167          *  @param sink the sink to send mp3 output to
168          *  @param inSampleRate sample rate of the input.
169          *  @param inBitsPerSample number of bits per sample of the input.
170          *  @param inChannel number of channels  of the input.
171          *  @param inBigEndian shows if the input is big or little endian
172          *  @param outBitrateMode the bit rate mode of the output.
173          *  @param outBitrate bit rate of the output (kbits/sec).
174          *  @param outQuality the quality of the stream.
175          *  @param outSampleRate sample rate of the output.
176          *                       If 0, inSampleRate is used.
177          *  @param outChannel number of channels of the output.
178          *                    If 0, inChannel is used.
179          *  @param lowpass frequency threshold for the lowpass filter.
180          *                 Input above this frequency is cut.
181          *                 If 0, lame's default values are used,
182          *                 which depends on the out sample rate.
183          *  @param highpass frequency threshold for the highpass filter.
184          *                  Input below this frequency is cut.
185          *                  If 0, lame's default values are used,
186          *                  which depends on the out sample rate.
187          *  @exception Exception
188          */
189         inline
190         LameLibEncoder (    Sink          * sink,
191                             unsigned int    inSampleRate,
192                             unsigned int    inBitsPerSample,
193                             unsigned int    inChannel,
194                             bool            inBigEndian,
195                             BitrateMode     outBitrateMode,
196                             unsigned int    outBitrate,
197                             double          outQuality,
198                             unsigned int    outSampleRate = 0,
199                             unsigned int    outChannel    = 0,
200                             int             lowpass       = 0,
201                             int             highpass      = 0 )
throw(Exception)202                                                         throw ( Exception )
203 
204                     : AudioEncoder ( sink,
205                                      inSampleRate,
206                                      inBitsPerSample,
207                                      inChannel,
208                                      inBigEndian,
209                                      outBitrateMode,
210                                      outBitrate,
211                                      outQuality,
212                                      outSampleRate,
213                                      outChannel )
214         {
215             init( lowpass, highpass);
216         }
217 
218         /**
219          *  Constructor.
220          *
221          *  @param sink the sink to send mp3 output to
222          *  @param as get input sample rate, bits per sample and channels
223          *            from this AudioSource.
224          *  @param outBitrateMode the bit rate mode of the output.
225          *  @param outBitrate bit rate of the output (kbits/sec).
226          *  @param outQuality the quality of the stream.
227          *  @param outSampleRate sample rate of the output.
228          *                       If 0, input sample rate is used.
229          *  @param outChannel number of channels of the output.
230          *                    If 0, input channel is used.
231          *  @param lowpass frequency threshold for the lowpass filter.
232          *                 Input above this frequency is cut.
233          *                 If 0, lame's default values are used,
234          *                 which depends on the out sample rate.
235          *  @param highpass frequency threshold for the highpass filter.
236          *                  Input below this frequency is cut.
237          *                  If 0, lame's default values are used,
238          *                  which depends on the out sample rate.
239          *  @exception Exception
240          */
241         inline
242         LameLibEncoder (    Sink                  * sink,
243                             const AudioSource     * as,
244                             BitrateMode             outBitrateMode,
245                             unsigned int            outBitrate,
246                             double                  outQuality,
247                             unsigned int            outSampleRate = 0,
248                             unsigned int            outChannel    = 0,
249                             int                     lowpass       = 0,
250                             int                     highpass      = 0 )
throw(Exception)251                                                             throw ( Exception )
252 
253                     : AudioEncoder ( sink,
254                                      as,
255                                      outBitrateMode,
256                                      outBitrate,
257                                      outQuality,
258                                      outSampleRate,
259                                      outChannel )
260         {
261             init( lowpass, highpass);
262         }
263 
264         /**
265          *  Copy constructor.
266          *
267          *  @param encoder the LameLibEncoder to copy.
268          */
269         inline
270         LameLibEncoder (  const LameLibEncoder &    encoder )
throw(Exception)271                                                             throw ( Exception )
272                     : AudioEncoder( encoder )
273         {
274             init( encoder.lowpass, encoder.highpass );
275         }
276 
277 
278         /**
279          *  Destructor.
280          *
281          *  @exception Exception
282          */
283         inline virtual
~LameLibEncoder(void)284         ~LameLibEncoder ( void )                            throw ( Exception )
285         {
286             if ( isOpen() ) {
287                 close();
288             }
289             strip();
290         }
291 
292         /**
293          *  Assignment operator.
294          *
295          *  @param encoder the LameLibEncoder to assign this to.
296          *  @return a reference to this LameLibEncoder.
297          *  @exception Exception
298          */
299         inline virtual LameLibEncoder &
throw(Exception)300         operator= ( const LameLibEncoder &      encoder )   throw ( Exception )
301         {
302             if ( this != &encoder ) {
303                 strip();
304                 AudioEncoder::operator=( encoder);
305                 init( encoder.lowpass, encoder.highpass );
306             }
307 
308             return *this;
309         }
310 
311         /**
312          *  Get the version string of the underlying lame library.
313          *
314          *  @return the version string of the underlying lame library.
315          */
316         inline const char *
getLameVersion(void)317         getLameVersion( void )
318         {
319             return get_lame_version();
320         }
321 
322         /**
323          *  Check whether encoding is in progress.
324          *
325          *  @return true if encoding is in progress, false otherwise.
326          */
327         inline virtual bool
isRunning(void)328         isRunning ( void ) const           throw ()
329         {
330             return isOpen();
331         }
332 
333         /**
334          *  Start encoding. This function returns as soon as possible,
335          *  with encoding started in the background.
336          *
337          *  @return true if encoding has started, false otherwise.
338          *  @exception Exception
339          */
340         inline virtual bool
start(void)341         start ( void )                      throw ( Exception )
342         {
343             return open();
344         }
345 
346         /**
347          *  Stop encoding. Stops the encoding running in the background.
348          *
349          *  @exception Exception
350          */
351         inline virtual void
stop(void)352         stop ( void )                       throw ( Exception )
353         {
354             return close();
355         }
356 
357         /**
358          *  Open an encoding session.
359          *
360          *  @return true if opening was successfull, false otherwise.
361          *  @exception Exception
362          */
363         virtual bool
364         open ( void )                               throw ( Exception );
365 
366         /**
367          *  Check if the encoding session is open.
368          *
369          *  @return true if the encoding session is open, false otherwise.
370          */
371         inline virtual bool
isOpen(void)372         isOpen ( void ) const                       throw ()
373         {
374             return lameGlobalFlags != 0;
375         }
376 
377         /**
378          *  Check if the encoder is ready to accept data.
379          *
380          *  @param sec the maximum seconds to block.
381          *  @param usec micro seconds to block after the full seconds.
382          *  @return true if the encoder is ready to accept data,
383          *          false otherwise.
384          *  @exception Exception
385          */
386         inline virtual bool
canWrite(unsigned int sec,unsigned int usec)387         canWrite (     unsigned int    sec,
388                        unsigned int    usec )       throw ( Exception )
389         {
390             if ( !isOpen() ) {
391                 return false;
392             }
393 
394             return true;
395         }
396 
397         /**
398          *  Write data to the encoder.
399          *  Buf is expected to be a sequence of big-endian 16 bit values,
400          *  with left and right channels interleaved. Len is the number of
401          *  bytes, must be a multiple of 4.
402          *
403          *  @param buf the data to write.
404          *  @param len number of bytes to write from buf.
405          *  @return the number of bytes written (may be less than len).
406          *  @exception Exception
407          */
408         virtual unsigned int
409         write (        const void    * buf,
410                        unsigned int    len )        throw ( Exception );
411 
412         /**
413          *  Flush all data that was written to the encoder to the underlying
414          *  connection.
415          *
416          *  @exception Exception
417          */
418         virtual void
419         flush ( void )                              throw ( Exception );
420 
421         /**
422          *  Close the encoding session.
423          *
424          *  @exception Exception
425          */
426         virtual void
427         close ( void )                              throw ( Exception );
428 };
429 
430 
431 /* ================================================= external data structures */
432 
433 
434 /* ====================================================== function prototypes */
435 
436 
437 #endif  /* LAME_LIB_ENCODER_H */
438 
439