enc_base.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *             __________               __   ___.
00003  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
00004  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
00005  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
00006  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
00007  *                     \/            \/     \/    \/            \/
00008  * $Id$
00009  *
00010  * Base declarations for working with software encoders
00011  *
00012  * Copyright (C) 2006 Michael Sevakis
00013  *
00014  * This program is free software; you can redistribute it and/or
00015  * modify it under the terms of the GNU General Public License
00016  * as published by the Free Software Foundation; either version 2
00017  * of the License, or (at your option) any later version.
00018  *
00019  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00020  * KIND, either express or implied.
00021  *
00022  ****************************************************************************/
00023 
00024 #ifndef ENC_BASE_H
00025 #define ENC_BASE_H
00026 
00027 /* firmware/export/system.h */
00028 /* return p incremented by specified number of bytes */
00029 #define SKIPBYTES(p, count) ((typeof (p))((char *)(p) + (count)))
00030 
00031 #define P2_M1(p2)  ((1 << (p2))-1)
00032 
00033 /* align up or down to nearest 2^p2 */
00034 #define ALIGN_DOWN_P2(n, p2) ((n) & ~P2_M1(p2))
00035 #define ALIGN_UP_P2(n, p2)   ALIGN_DOWN_P2((n) + P2_M1(p2),p2)
00036 /* end of firmware/export/system.h */
00037 
00038 /** encoder config structures **/
00039 
00040 /** aiff_enc.codec **/
00041 struct aiff_enc_config
00042 {
00043 #if 0
00044     unsigned long sample_depth;
00045 #endif
00046 };
00047 
00048 /** mp3_enc.codec **/
00049 #define MP3_BITR_CAP_8      (1 << 0)
00050 #define MP3_BITR_CAP_16     (1 << 1)
00051 #define MP3_BITR_CAP_24     (1 << 2)
00052 #define MP3_BITR_CAP_32     (1 << 3)
00053 #define MP3_BITR_CAP_40     (1 << 4)
00054 #define MP3_BITR_CAP_48     (1 << 5)
00055 #define MP3_BITR_CAP_56     (1 << 6)
00056 #define MP3_BITR_CAP_64     (1 << 7)
00057 #define MP3_BITR_CAP_80     (1 << 8)
00058 #define MP3_BITR_CAP_96     (1 << 9)
00059 #define MP3_BITR_CAP_112    (1 << 10)
00060 #define MP3_BITR_CAP_128    (1 << 11)
00061 #define MP3_BITR_CAP_144    (1 << 12)
00062 #define MP3_BITR_CAP_160    (1 << 13)
00063 #define MP3_BITR_CAP_192    (1 << 14)
00064 #define MP3_BITR_CAP_224    (1 << 15)
00065 #define MP3_BITR_CAP_256    (1 << 16)
00066 #define MP3_BITR_CAP_320    (1 << 17)
00067 #define MP3_ENC_NUM_BITR    18
00068 
00069 /* MPEG 1 */
00070 #define MPEG1_SAMPR_CAPS    (SAMPR_CAP_32 | SAMPR_CAP_48 | SAMPR_CAP_44)
00071 #define MPEG1_BITR_CAPS     (MP3_BITR_CAP_32  | MP3_BITR_CAP_40  | MP3_BITR_CAP_48  | \
00072                              MP3_BITR_CAP_56  | MP3_BITR_CAP_64  | MP3_BITR_CAP_80  | \
00073                              MP3_BITR_CAP_96  | MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \
00074                              MP3_BITR_CAP_160 | MP3_BITR_CAP_192 | MP3_BITR_CAP_224 | \
00075                              MP3_BITR_CAP_256 | MP3_BITR_CAP_320)
00076 
00077 /* MPEG 2 */
00078 #define MPEG2_SAMPR_CAPS    (SAMPR_CAP_22 | SAMPR_CAP_24 | SAMPR_CAP_16)
00079 #define MPEG2_BITR_CAPS     (MP3_BITR_CAP_8   | MP3_BITR_CAP_16  | MP3_BITR_CAP_24  | \
00080                              MP3_BITR_CAP_32  | MP3_BITR_CAP_40  | MP3_BITR_CAP_48  | \
00081                              MP3_BITR_CAP_56  | MP3_BITR_CAP_64  | MP3_BITR_CAP_80  | \
00082                              MP3_BITR_CAP_96  | MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \
00083                              MP3_BITR_CAP_144 | MP3_BITR_CAP_160)
00084 
00085 #if 0
00086 /* MPEG 2.5 */
00087 #define MPEG2_5_SAMPR_CAPS  (SAMPR_CAP_8  | SAMPR_CAP_12 | SAMPR_CAP_11)
00088 #define MPEG2_5_BITR_CAPS   MPEG2_BITR_CAPS
00089 #endif
00090 
00091 #if 0
00092 /* HAVE_MPEG* defines mainly apply to the bitrate menu */
00093 #if (REC_SAMPR_CAPS & MPEG1_SAMPR_CAPS) || defined (HAVE_SPDIF_REC)
00094 #define HAVE_MPEG1_SAMPR
00095 #endif
00096 
00097 #if (REC_SAMPR_CAPS & MPEG2_SAMPR_CAPS) || defined (HAVE_SPDIF_REC)
00098 #define HAVE_MPEG2_SAMPR
00099 #endif
00100 #endif
00101 
00102 #if 0
00103 #if (REC_SAMPR_CAPS & MPEG2_5_SAMPR_CAPS) || defined (HAVE_SPDIF_REC)
00104 #define HAVE_MPEG2_5_SAMPR
00105 #endif
00106 #endif /* 0 */
00107 
00108 #define MP3_ENC_SAMPR_CAPS      (MPEG1_SAMPR_CAPS | MPEG2_SAMPR_CAPS)
00109 
00110 /* This number is count of full encoder set */
00111 #define MP3_ENC_NUM_SAMPR       6
00112 
00113 extern const unsigned long mp3_enc_sampr[MP3_ENC_NUM_SAMPR];
00114 extern const unsigned long mp3_enc_bitr[MP3_ENC_NUM_BITR];
00115 
00116 struct mp3_enc_config
00117 {
00118     unsigned long bitrate;
00119 };
00120 
00121 #define MP3_ENC_BITRATE_CFG_DEFAULT     11 /* 128 */
00122 #define MP3_ENC_BITRATE_CFG_VALUE_LIST  "8,16,24,32,40,48,56,64,80,96," \
00123                                         "112,128,144,160,192,224,256,320"
00124 
00125 /** wav_enc.codec **/
00126 #define WAV_ENC_SAMPR_CAPS      SAMPR_CAP_ALL
00127 
00128 struct wav_enc_config
00129 {
00130 #if 0
00131     unsigned long sample_depth;
00132 #endif
00133 };
00134 
00135 /** wavpack_enc.codec **/
00136 #define WAVPACK_ENC_SAMPR_CAPS  SAMPR_CAP_ALL
00137 
00138 struct wavpack_enc_config
00139 {
00140 #if 0
00141     unsigned long sample_depth;
00142 #endif
00143 };
00144 
00145 struct encoder_config
00146 {
00147     union
00148     {
00149         /* states which *_enc_config member is valid */
00150         int rec_format; /* REC_FORMAT_* value */
00151         int afmt;       /* AFMT_* value       */
00152     };
00153 
00154     union
00155     {
00156         struct mp3_enc_config     mp3_enc;
00157         struct wavpack_enc_config wavpack_enc;
00158         struct wav_enc_config     wav_enc;
00159     };
00160 };
00161 
00162 /** Encoder chunk macros and definitions **/
00163 #define CHUNKF_START_FILE 0x0001ul /* This chunk starts a new file         */
00164 #define CHUNKF_END_FILE   0x0002ul /* This chunk ends the current file     */
00165 #define CHUNKF_PRERECORD  0x0010ul /* This chunk is prerecord data,
00166                                       a new file could start anytime       */
00167 #define CHUNKF_ABORT      0x0020ul /* Encoder should not finish this
00168                                       chunk                                */
00169 #define CHUNKF_ERROR    (~0ul ^ (~0ul >> 1)) /* An error has occured
00170                                       (passed to/from encoder). Use the
00171                                       sign bit to check (long)flags < 0.   */
00172 #define CHUNKF_ALLFLAGS (0x0033ul | CHUNKF_ERROR)
00173 
00174 /* Header at the beginning of every encoder chunk */
00175 #ifdef DEBUG
00176 #define ENC_CHUNK_MAGIC H_TO_BE32(('P' << 24) | ('T' << 16) | ('Y' << 8) | 'R')
00177 #endif
00178 struct enc_chunk_hdr
00179 {
00180 #ifdef DEBUG
00181     unsigned long id;         /* overflow detection - 'PTYR' - acronym for
00182                                  "PTYR Tells You Right" ;)                 */
00183 #endif
00184     unsigned long flags;      /* in/out: flags used by encoder and file
00185                                          writing                           */
00186     size_t        enc_size;   /* out:    amount of encoder data written to
00187                                          chunk                             */
00188     unsigned long num_pcm;    /* out:    number of PCM samples eaten during
00189                                          processing
00190                                          (<= size of allocated buffer)     */
00191     unsigned char *enc_data;  /* out:    pointer to enc_size_written bytes
00192                                          of encoded audio data in chunk    */
00193     /* Encoder defined data follows header. Can be audio data + any other
00194        stuff the encoder needs to handle on a per chunk basis */
00195 };
00196 
00197 /* Paranoia: be sure header size is 4-byte aligned */
00198 #define ENC_CHUNK_HDR_SIZE \
00199             ALIGN_UP_P2(sizeof (struct enc_chunk_hdr), 2)
00200 /* Skip the chunk header and return data */
00201 #define ENC_CHUNK_SKIP_HDR(t, hdr) \
00202             ((typeof (t))((char *)hdr + ENC_CHUNK_HDR_SIZE))
00203 /* Cast p to struct enc_chunk_hdr * */
00204 #define ENC_CHUNK_HDR(p) \
00205             ((struct enc_chunk_hdr *)(p))
00206 
00207 enum enc_events
00208 {
00209     /* File writing events - data points to enc_file_event_data            */
00210     ENC_START_FILE = 0,  /* a new file has been opened and no data has yet
00211                             been written                                   */
00212     ENC_WRITE_CHUNK,     /* write the current chunk to disk                */
00213     ENC_END_FILE,        /* current file about to be closed and all valid
00214                             data has been written                          */
00215     /* Encoder buffer events - data points to enc_buffer_event_data        */
00216     ENC_REC_NEW_STREAM,  /* Take steps to finish current stream and start
00217                             new                                            */
00218 };
00219 
00220 /**
00221  * encoder can write extra data to the file such as headers or more encoded
00222  * samples and must update sizes and samples accordingly.
00223  */
00224 struct enc_file_event_data
00225 {
00226     struct enc_chunk_hdr *chunk;   /* Current chunk                        */
00227     size_t        new_enc_size;    /* New size of chunk                    */
00228     unsigned long new_num_pcm;     /* New number of pcm in chunk           */
00229     const char   *filename;        /* filename to open if ENC_START_FILE   */
00230     int           rec_file;        /* Current file or < 0 if none          */
00231     unsigned long num_pcm_samples; /* Current pcm sample count written to
00232                                       file so far.                         */
00233 };
00234 
00235 /**
00236  * encoder may add some data to the end of the last and start of the next
00237  * but must never yield when called so any encoding done should be absolutely
00238  * minimal.
00239  */
00240 struct enc_buffer_event_data
00241 {
00242     unsigned long         flags;       /* in: One or more of:
00243                                         *     CHUNKF_PRERECORD
00244                                         *     CHUNKF_END_FILE
00245                                         *     CHUNKF_START_FILE
00246                                         */
00247     struct enc_chunk_hdr *pre_chunk;   /* in: pointer to first prerecord
00248                                         *     chunk
00249                                         */
00250     struct enc_chunk_hdr *chunk;       /* in,out: chunk were split occurs -
00251                                         *         first chunk of start
00252                                         */
00253 };
00254 
00255 /** Callbacks called by encoder codec **/
00256 
00257 /* parameters passed to encoder by enc_get_inputs */
00258 struct enc_inputs
00259 {
00260     unsigned long sample_rate;     /* out - pcm frequency                  */
00261     int           num_channels;    /* out - number of audio channels       */
00262     struct encoder_config *config; /* out - encoder settings               */
00263 };
00264 
00265 void enc_get_inputs(struct enc_inputs *inputs);
00266 
00267 /* parameters pass from encoder to enc_set_parameters */
00268 struct enc_parameters
00269 {
00270     /* IN parameters */
00271     int           afmt;            /* AFMT_* id - sanity checker           */
00272     size_t        chunk_size;      /* max chunk size required              */
00273     unsigned long enc_sample_rate; /* actual sample rate used by encoder
00274                                       (for recorded time calculation)      */
00275     size_t        reserve_bytes;   /* number of bytes to reserve immediately
00276                                       following chunks                     */
00277     void (*events_callback)(enum enc_events event,
00278                             void *data); /*  pointer to events callback    */
00279     /* OUT parameters */
00280     unsigned char *enc_buffer;     /* pointer to enc_buffer                */
00281     size_t         buf_chunk_size; /* size of chunks in enc_buffer         */
00282     int            num_chunks;     /* number of chunks allotted to encoder */
00283     unsigned char *reserve_buffer; /* pointer to reserve_bytes bytes       */
00284 };
00285 
00286 /* set the encoder dimensions - called by encoder codec at initialization
00287    and termination */
00288 void   enc_set_parameters(struct enc_parameters *params);
00289 /* returns pointer to next write chunk in circular buffer */
00290 struct enc_chunk_hdr * enc_get_chunk(void);
00291 /* releases the current chunk into the available chunks */
00292 void   enc_finish_chunk(void);
00293 
00294 #define PCM_MAX_FEED_SIZE       20000 /* max pcm size passed to encoder    */
00295 
00296 /* passes a pointer to next chunk of unprocessed wav data */
00297 unsigned char * enc_get_pcm_data(size_t size);
00298 /* puts some pcm data back in the queue */
00299 size_t          enc_unget_pcm_data(size_t size);
00300 
00301 #endif /* ENC_BASE_H */

Generated on Tue May 25 08:04:54 2010 for VLC by  doxygen 1.5.6