/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Base declarations for working with software encoders * * Copyright (C) 2006 Michael Sevakis * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #ifndef ENC_BASE_H #define ENC_BASE_H /** encoder config structures **/ /** mp3_enc.codec **/ #define MP3_BITR_CAP_8 (1 << 0) #define MP3_BITR_CAP_16 (1 << 1) #define MP3_BITR_CAP_24 (1 << 2) #define MP3_BITR_CAP_32 (1 << 3) #define MP3_BITR_CAP_40 (1 << 4) #define MP3_BITR_CAP_48 (1 << 5) #define MP3_BITR_CAP_56 (1 << 6) #define MP3_BITR_CAP_64 (1 << 7) #define MP3_BITR_CAP_80 (1 << 8) #define MP3_BITR_CAP_96 (1 << 9) #define MP3_BITR_CAP_112 (1 << 10) #define MP3_BITR_CAP_128 (1 << 11) #define MP3_BITR_CAP_144 (1 << 12) #define MP3_BITR_CAP_160 (1 << 13) #define MP3_BITR_CAP_192 (1 << 14) #define MP3_BITR_CAP_224 (1 << 15) #define MP3_BITR_CAP_256 (1 << 16) #define MP3_BITR_CAP_320 (1 << 17) #define MP3_ENC_NUM_BITR 18 /* MPEG 1 */ #define MPEG1_SAMPR_CAPS (SAMPR_CAP_32 | SAMPR_CAP_48 | SAMPR_CAP_44) #define MPEG1_BITR_CAPS (MP3_BITR_CAP_32 | MP3_BITR_CAP_40 | MP3_BITR_CAP_48 | \ MP3_BITR_CAP_56 | MP3_BITR_CAP_64 | MP3_BITR_CAP_80 | \ MP3_BITR_CAP_96 | MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \ MP3_BITR_CAP_160 | MP3_BITR_CAP_192 | MP3_BITR_CAP_224 | \ MP3_BITR_CAP_256 | MP3_BITR_CAP_320) /* MPEG 2 */ #define MPEG2_SAMPR_CAPS (SAMPR_CAP_22 | SAMPR_CAP_24 | SAMPR_CAP_16) #define MPEG2_BITR_CAPS (MP3_BITR_CAP_8 | MP3_BITR_CAP_16 | MP3_BITR_CAP_24 | \ MP3_BITR_CAP_32 | MP3_BITR_CAP_40 | MP3_BITR_CAP_48 | \ MP3_BITR_CAP_56 | MP3_BITR_CAP_64 | MP3_BITR_CAP_80 | \ MP3_BITR_CAP_96 | MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \ MP3_BITR_CAP_144 | MP3_BITR_CAP_160) #if 0 /* MPEG 2.5 */ #define MPEG2_5_SAMPR_CAPS (SAMPR_CAP_8 | SAMPR_CAP_12 | SAMPR_CAP_11) #define MPEG2_5_BITR_CAPS MPEG2_BITR_CAPS #endif /* Assume 44100 is always available and therefore MPEG1 */ /* HAVE_MPEG* defines mainly apply to the bitrate menu */ #if (REC_SAMPR_CAPS & MPEG2_SAMPR_CAPS) || defined (HAVE_SPDIF_IN) #define HAVE_MPEG2_SAMPR #endif #if 0 #if (REC_SAMPR_CAPS & MPEG2_5_SAMPR_CAPS) || defined (HAVE_SPDIF_IN) #define HAVE_MPEG2_5_SAMPR #endif #endif /* 0 */ #define MP3_ENC_SAMPR_CAPS (MPEG1_SAMPR_CAPS | MPEG2_SAMPR_CAPS) /* This number is count of full encoder set */ #define MP3_ENC_NUM_SAMPR 6 extern const unsigned long mp3_enc_sampr[MP3_ENC_NUM_SAMPR]; extern const unsigned long mp3_enc_bitr[MP3_ENC_NUM_BITR]; struct mp3_enc_config { unsigned long bitrate; }; #define MP3_ENC_BITRATE_CFG_DEFAULT 11 /* 128 */ #define MP3_ENC_BITRATE_CFG_VALUE_LIST "8,16,24,32,40,48,56,64,80,96," \ "112,128,144,160,192,224,256,320" /** wav_enc.codec **/ #define WAV_ENC_SAMPR_CAPS SAMPR_CAP_ALL struct wav_enc_config { #if 0 unsigned long sample_depth; #endif }; /** wavpack_enc.codec **/ #define WAVPACK_ENC_SAMPR_CAPS SAMPR_CAP_ALL struct wavpack_enc_config { #if 0 unsigned long sample_depth; #endif }; struct encoder_config { union { /* states which *_enc_config member is valid */ int rec_format; /* REC_FORMAT_* value */ int afmt; /* AFMT_* value */ }; union { struct mp3_enc_config mp3_enc; struct wavpack_enc_config wavpack_enc; struct wav_enc_config wav_enc; }; }; /** Encoder chunk macros and definitions **/ #define CHUNKF_START_FILE 0x0001 /* This chunk starts a new file */ #define CHUNKF_END_FILE 0x0002 /* This chunk ends the current file */ #define CHUNKF_PRERECORD 0x0010 /* This chunk is prerecord data, a new file could start anytime */ #define CHUNKF_ABORT 0x0020 /* Encoder should not finish this chunk */ #define CHUNKF_ERROR 0x80000000 /* An error has occured (passed to/ from encoder). Use the sign bit to check (long)flags < 0. */ /* Header at the beginning of every encoder chunk */ struct enc_chunk_hdr { unsigned long flags; /* in/out: flags used by encoder and file writing */ size_t enc_size; /* out: amount of encoder data written to chunk */ unsigned long num_pcm; /* out: number of PCM samples eaten during processing (<= size of allocated buffer) */ unsigned char *enc_data; /* out: pointer to enc_size_written bytes of encoded audio data in chunk */ /* Encoder defined data follows header. Can be audio data + any other stuff the encoder needs to handle on a per chunk basis */ }; /* Paranoia: be sure header size is 4-byte aligned */ #define ENC_CHUNK_HDR_SIZE \ ALIGN_UP_P2(sizeof (struct enc_chunk_hdr), 2) /* Skip the chunk header and return data */ #define ENC_CHUNK_SKIP_HDR(t, hdr) \ ((typeof (t))((char *)hdr + ENC_CHUNK_HDR_SIZE)) /* Cast p to struct enc_chunk_hdr * */ #define ENC_CHUNK_HDR(p) \ ((struct enc_chunk_hdr *)(p)) enum enc_events { /* File writing events - data points to enc_file_event_data */ ENC_START_FILE = 0, /* a new file has been opened and no data has yet been written */ ENC_WRITE_CHUNK, /* write the current chunk to disk */ ENC_END_FILE, /* current file about to be closed and all valid data has been written */ /* Encoder buffer events - data points to enc_buffer_event_data */ ENC_REC_NEW_STREAM, /* Take steps to finish current stream and start new */ }; /** * encoder can write extra data to the file such as headers or more encoded * samples and must update sizes and samples accordingly. */ struct enc_file_event_data { struct enc_chunk_hdr *chunk; /* Current chunk */ size_t new_enc_size; /* New size of chunk */ unsigned long new_num_pcm; /* New number of pcm in chunk */ const char *filename; /* filename to open if ENC_START_FILE */ int rec_file; /* Current file or < 0 if none */ unsigned long num_pcm_samples; /* Current pcm sample count written to file so far. */ }; /** * encoder may add some data to the end of the last and start of the next * but must never yield when called so any encoding done should be absolutely * minimal. */ struct enc_buffer_event_data { unsigned long flags; /* in: One or more of: * CHUNKF_PRERECORD * CHUNKF_END_FILE * CHUNKF_START_FILE */ struct enc_chunk_hdr *pre_chunk; /* in: pointer to first prerecord * chunk */ struct enc_chunk_hdr *chunk; /* in,out: chunk were split occurs - * first chunk of start */ }; /** Callbacks called by encoder codec **/ /* parameters passed to encoder by enc_get_inputs */ struct enc_inputs { unsigned long sample_rate; /* out - pcm frequency */ int num_channels; /* out - number of audio channels */ struct encoder_config *config; /* out - encoder settings */ }; void enc_get_inputs(struct enc_inputs *inputs); /* parameters pass from encoder to enc_set_parameters */ struct enc_parameters { /* IN parameters */ int afmt; /* AFMT_* id - sanity checker */ size_t chunk_size; /* max chunk size required */ unsigned long enc_sample_rate; /* actual sample rate used by encoder (for recorded time calculation) */ size_t reserve_bytes; /* number of bytes to reserve immediately following chunks */ void (*events_callback)(enum enc_events event, void *data); /* pointer to events callback */ /* OUT parameters */ unsigned char *enc_buffer; /* pointer to enc_buffer */ size_t buf_chunk_size; /* size of chunks in enc_buffer */ int num_chunks; /* number of chunks allotted to encoder */ unsigned char *reserve_buffer; /* pointer to reserve_bytes bytes */ }; /* set the encoder dimensions - called by encoder codec at initialization and termination */ void enc_set_parameters(struct enc_parameters *params); /* returns pointer to next write chunk in circular buffer */ struct enc_chunk_hdr * enc_get_chunk(void); /* releases the current chunk into the available chunks */ void enc_finish_chunk(void); /* checks near empty state on pcm input buffer */ int enc_pcm_buf_near_empty(void); #define PCM_MAX_FEED_SIZE 20000 /* max pcm size passed to encoder */ /* passes a pointer to next chunk of unprocessed wav data */ unsigned char * enc_get_pcm_data(size_t size); /* puts some pcm data back in the queue */ size_t enc_unget_pcm_data(size_t size); #endif /* ENC_BASE_H */