From 7345ac124e3b56a402b6a004d968d40b4ffeaa50 Mon Sep 17 00:00:00 2001 From: Andree Buschmann Date: Thu, 3 Feb 2011 08:28:23 +0000 Subject: Submit FS#11918: Add 2 more codec types to be able to differentiate between AAC / AAC-HE and MPC SV7 / SV8. Additionally handle ATARI soundfiles in get_codec_base_type() as intended. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29199 a1c6a512-1295-4272-9138-f99709370657 --- apps/buffering.c | 19 +++++++++++++++---- apps/codec_thread.c | 33 +++++++++++++++++++++++++++++++-- apps/codecs/libm4a/demux.c | 3 ++- apps/metadata.c | 12 +++++++++--- apps/metadata.h | 4 +++- apps/metadata/mp4.c | 11 ++++++++--- apps/metadata/mpc.c | 4 ++++ 7 files changed, 72 insertions(+), 14 deletions(-) diff --git a/apps/buffering.c b/apps/buffering.c index 8d41324190..4516959cab 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -25,6 +25,8 @@ #include #include #include +#define assert(a) + #include "buffering.h" #include "storage.h" @@ -611,6 +613,16 @@ static inline bool buffer_is_low(void) return data_counters.useful < (conf_watermark / 2); } +static uintptr_t beyond_handle(struct memory_handle *h) +{ + /* + * the last handle on the chain must leave at least one byte + * between itself and the first handle, to avoid overflowing the + * ring by advancing buf_widx up to buf_ridx + */ + return h->next != 0 ? ringbuf_offset(h->next) : ringbuf_sub(buf_ridx, 1); +} + /* Buffer data for the given handle. Return whether or not the buffering should continue explicitly. */ static bool buffer_handle(int handle_id) @@ -669,10 +681,10 @@ static bool buffer_handle(int handle_id) buffer_len - h->widx); ssize_t overlap; - uintptr_t next_handle = ringbuf_offset(h->next); + uintptr_t next_handle = beyond_handle(h); /* stop copying if it would overwrite the reading position */ - if (ringbuf_add_cross(h->widx, copy_n, buf_ridx) >= 0) + if (h->widx == next_handle || ringbuf_add_cross(h->widx, copy_n, buf_ridx) >= 0) return false; /* FIXME: This would overwrite the next handle @@ -789,8 +801,7 @@ static void rebuffer_handle(int handle_id, size_t newpos) LOGFQUEUE("buffering >| Q_RESET_HANDLE %d", handle_id); queue_send(&buffering_queue, Q_RESET_HANDLE, handle_id); - uintptr_t next = ringbuf_offset(h->next); - if (ringbuf_sub(next, h->data) < h->filesize - newpos) + if (ringbuf_sub(beyond_handle(h), h->data) < h->filesize - newpos) { /* There isn't enough space to rebuffer all of the track from its new offset, so we ask the user to free some */ diff --git a/apps/codec_thread.c b/apps/codec_thread.c index 21d55a7779..ef02f70811 100644 --- a/apps/codec_thread.c +++ b/apps/codec_thread.c @@ -102,16 +102,45 @@ static bool codec_load_next_track(void); /** misc external functions */ +/* Used to check whether a new codec must be loaded. See array audio_formats[] + * in metadata.c */ int get_codec_base_type(int type) { + int base_type = type; switch (type) { case AFMT_MPA_L1: case AFMT_MPA_L2: case AFMT_MPA_L3: - return AFMT_MPA_L3; + base_type = AFMT_MPA_L3; + break; + case AFMT_MPC_SV7: + case AFMT_MPC_SV8: + base_type = AFMT_MPC_SV7; + break; + case AFMT_MP4_AAC: + case AFMT_MP4_AAC_HE: + base_type = AFMT_MP4_AAC; + break; + case AFMT_SAP: + case AFMT_CMC: + case AFMT_CM3: + case AFMT_CMR: + case AFMT_CMS: + case AFMT_DMC: + case AFMT_DLT: + case AFMT_MPT: + case AFMT_MPD: + case AFMT_RMT: + case AFMT_TMC: + case AFMT_TM8: + case AFMT_TM2: + base_type = AFMT_SAP; + break; + default: + break; } - return type; + return base_type; } const char *get_codec_filename(int cod_spec) diff --git a/apps/codecs/libm4a/demux.c b/apps/codecs/libm4a/demux.c index 8fc90c8092..e584c37858 100644 --- a/apps/codecs/libm4a/demux.c +++ b/apps/codecs/libm4a/demux.c @@ -257,7 +257,8 @@ static bool read_chunk_stsd(qtmovie_t *qtmovie, size_t chunk_len) stream_skip(qtmovie->stream, entry_remaining); } else if (qtmovie->res->format==MAKEFOURCC('m','p','4','a')) { - if (qtmovie->stream->ci->id3->codectype!=AFMT_MP4_AAC) { + if (qtmovie->stream->ci->id3->codectype!=AFMT_MP4_AAC && + qtmovie->stream->ci->id3->codectype!=AFMT_MP4_AAC_HE) { return false; } diff --git a/apps/metadata.c b/apps/metadata.c index 79ef7ebcad..8ffd1a6af1 100644 --- a/apps/metadata.c +++ b/apps/metadata.c @@ -86,9 +86,12 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] = /* FLAC */ [AFMT_FLAC] = AFMT_ENTRY("FLAC", "flac", NULL, get_flac_metadata, "flac\0"), - /* Musepack */ - [AFMT_MPC] = - AFMT_ENTRY("MPC", "mpc", NULL, get_musepack_metadata,"mpc\0"), + /* Musepack SV7 */ + [AFMT_MPC_SV7] = + AFMT_ENTRY("MPCv7", "mpc", NULL, get_musepack_metadata,"mpc\0"), + /* Musepack SV8 */ + [AFMT_MPC_SV8] = + AFMT_ENTRY("MPCv8", "mpc", NULL, get_musepack_metadata,"mpc\0"), /* A/52 (aka AC3) audio */ [AFMT_A52] = AFMT_ENTRY("AC3", "a52", NULL, get_a52_metadata, "a52\0ac3\0"), @@ -101,6 +104,9 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] = /* Advanced Audio Coding in M4A container */ [AFMT_MP4_AAC] = AFMT_ENTRY("AAC", "aac", NULL, get_mp4_metadata, "mp4\0"), + /* Advanced Audio Coding High Efficiency in M4A container */ + [AFMT_MP4_AAC_HE] = + AFMT_ENTRY("AAC-HE","aac", NULL, get_mp4_metadata, "mp4\0"), /* Shorten */ [AFMT_SHN] = AFMT_ENTRY("SHN","shorten", NULL, get_shn_metadata, "shn\0"), diff --git a/apps/metadata.h b/apps/metadata.h index 93b9891763..8c350fcca3 100644 --- a/apps/metadata.h +++ b/apps/metadata.h @@ -46,11 +46,13 @@ enum AFMT_PCM_WAV, /* Uncompressed PCM in a WAV file */ AFMT_OGG_VORBIS, /* Ogg Vorbis */ AFMT_FLAC, /* FLAC */ - AFMT_MPC, /* Musepack */ + AFMT_MPC_SV7, /* Musepack SV7 */ + AFMT_MPC_SV8, /* Musepack SV8 */ AFMT_A52, /* A/52 (aka AC3) audio */ AFMT_WAVPACK, /* WavPack */ AFMT_MP4_ALAC, /* Apple Lossless Audio Codec */ AFMT_MP4_AAC, /* Advanced Audio Coding (AAC) in M4A container */ + AFMT_MP4_AAC_HE, /* Advanced Audio Coding (AAC-HE) in M4A container */ AFMT_SHN, /* Shorten */ AFMT_SID, /* SID File Format */ AFMT_ADX, /* ADX File Format */ diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c index a3721f0e9a..9ae174af7e 100644 --- a/apps/metadata/mp4.c +++ b/apps/metadata/mp4.c @@ -300,8 +300,7 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, uint32_t* size) /* Skip 13 bits from above, plus 3 bits, then read 11 bits */ else if ((length >= 4) && (((bits >> 5) & 0x7ff) == 0x2b7)) { - /* extensionAudioObjectType */ - DEBUGF("MP4: extensionAudioType\n"); + /* We found an extensionAudioObjectType */ type = bits & 0x1f; /* Object type - 5 bits*/ bits = get_long_be(&buf[4]); @@ -680,7 +679,6 @@ static bool read_mp4_container(int fd, struct mp3entry* id3, { uint32_t frequency; - id3->codectype = (type == MP4_mp4a) ? AFMT_MP4_AAC : AFMT_MP4_ALAC; lseek(fd, 22, SEEK_CUR); read_uint32be(fd, &frequency); size -= 26; @@ -700,11 +698,13 @@ static bool read_mp4_container(int fd, struct mp3entry* id3, read_mp4_atom(fd, &subsize, &subtype, size); size -= 10; + id3->codectype = AFMT_MP4_AAC; if (subtype == MP4_esds) { sbr_used = read_mp4_esds(fd, id3, &size); if (sbr_used) { + id3->codectype = AFMT_MP4_AAC_HE; if (SBR_upsampling_used) DEBUGF("MP4: AAC-HE, SBR upsampling\n"); else @@ -712,6 +712,11 @@ static bool read_mp4_container(int fd, struct mp3entry* id3, } } } + else + { + id3->codectype = AFMT_MP4_ALAC; + } + } break; diff --git a/apps/metadata/mpc.c b/apps/metadata/mpc.c index 0dd76fcc4b..0387dc9f77 100644 --- a/apps/metadata/mpc.c +++ b/apps/metadata/mpc.c @@ -125,6 +125,8 @@ bool get_musepack_metadata(int fd, struct mp3entry *id3) bufused = set_replaygain_sv7(id3, false, header[3], bufused); bufused = set_replaygain_sv7(id3, true , header[4], bufused); + + id3->codectype = AFMT_MPC_SV7; } else { return false; /* only SV7 is allowed within a "MP+" signature */ } @@ -191,6 +193,8 @@ bool get_musepack_metadata(int fd, struct mp3entry *id3) bufused += set_replaygain_sv8(id3, true , gain, peak, bufused); } } + + id3->codectype = AFMT_MPC_SV8; } else { /* No sv8 stream header found */ return false; -- cgit v1.2.3