int decode_chunk( ape_ctx_t* ape_ctx, unsigned char* inbuffer, int* firstbyte, int* bytesconsumed, int32_t* decoded0, int32_t* decoded1, int count) { int res; int32_t left, right; #define SCALE(x) (x) if ((ape_ctx->channels==1) || (ape_ctx->frameflags & APE_FRAMECODE_PSEUDO_STEREO)) { if (ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) { res = entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, decoded1, count); /* We are pure silence, so we're done. */ return 0; } else { res = entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, NULL, count); } switch (ape_ctx->compressiontype) { case 2000: apply_filter_16_11(ape_ctx->fileversion,decoded0,NULL,count); break; case 3000: apply_filter_64_11(ape_ctx->fileversion,decoded0,NULL,count); break; case 4000: apply_filter_32_10(ape_ctx->fileversion,decoded0,NULL,count); apply_filter_256_13(ape_ctx->fileversion,decoded0,NULL,count); break; case 5000: apply_filter_16_11(ape_ctx->fileversion,decoded0,NULL,count); apply_filter_256_13(ape_ctx->fileversion,decoded0,NULL,count); apply_filter_1280_15(ape_ctx->fileversion,decoded0,NULL,count); } /* Now apply the predictor decoding */ predictor_decode_mono(ape_ctx,decoded0,count); if (ape_ctx->channels==2) { /* Pseudo-stereo - just copy left channel to right channel */ while (count--) { left = *decoded0; *(decoded1++) = *(decoded0++) = SCALE(left); } } else { /* Mono - do nothing unless it's 8-bit audio */ if (ape_ctx->bps == 8) { /* TODO: Handle 8-bit streams */ } } } else { /* Stereo */ if (ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) { /* We are pure silence, so we're done. */ return 0; } res = entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, decoded1, count); /* Apply filters - compression type 1000 doesn't have any */ switch (ape_ctx->compressiontype) { case 2000: apply_filter_16_11(ape_ctx->fileversion,decoded0,decoded1,count); break; case 3000: apply_filter_64_11(ape_ctx->fileversion,decoded0,decoded1,count); break; case 4000: apply_filter_32_10(ape_ctx->fileversion,decoded0,decoded1,count); apply_filter_256_13(ape_ctx->fileversion,decoded0,decoded1,count); break; case 5000: apply_filter_16_11(ape_ctx->fileversion,decoded0,decoded1,count); apply_filter_256_13(ape_ctx->fileversion,decoded0,decoded1,count); apply_filter_1280_15(ape_ctx->fileversion,decoded0,decoded1,count); } /* Now apply the predictor decoding */ predictor_decode_stereo(ape_ctx,decoded0,decoded1,count); if (ape_ctx->bps == 8) { /* TODO: Handle 8-bit streams */ } else { /* Decorrelate and scale to output depth */ while (count--) { left = *decoded1 - (*decoded0 / 2); right = left + *decoded0; *(decoded0++) = SCALE(left); *(decoded1++) = SCALE(right); } } } return res; }
int ICODE_ATTR_DEMAC decode_chunk(struct ape_ctx_t* ape_ctx, unsigned char* inbuffer, int* firstbyte, int* bytesconsumed, int32_t* decoded0, int32_t* decoded1, int count) { int32_t left, right; #ifdef ROCKBOX int scale = (APE_OUTPUT_DEPTH - ape_ctx->bps); #define SCALE(x) ((x) << scale) #else #define SCALE(x) (x) #endif if ((ape_ctx->channels==1) || ((ape_ctx->frameflags & (APE_FRAMECODE_PSEUDO_STEREO|APE_FRAMECODE_STEREO_SILENCE)) == APE_FRAMECODE_PSEUDO_STEREO)) { entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, NULL, count); if (ape_ctx->frameflags & APE_FRAMECODE_MONO_SILENCE) { /* We are pure silence, so we're done. */ return 0; } switch (ape_ctx->compressiontype) { case 2000: apply_filter_16_11(ape_ctx->fileversion,decoded0,NULL,count); break; case 3000: apply_filter_64_11(ape_ctx->fileversion,decoded0,NULL,count); break; case 4000: apply_filter_32_10(ape_ctx->fileversion,decoded0,NULL,count); apply_filter_256_13(ape_ctx->fileversion,decoded0,NULL,count); break; case 5000: apply_filter_16_11(ape_ctx->fileversion,decoded0,NULL,count); apply_filter_256_13(ape_ctx->fileversion,decoded0,NULL,count); apply_filter_1280_15(ape_ctx->fileversion,decoded0,NULL,count); } /* Now apply the predictor decoding */ predictor_decode_mono(&ape_ctx->predictor,decoded0,count); if (ape_ctx->channels==2) { /* Pseudo-stereo - copy left channel to right channel */ while (count--) { left = *decoded0; *(decoded1++) = *(decoded0++) = SCALE(left); } } #ifdef ROCKBOX else { /* Scale to output depth */ while (count--) { left = *decoded0; *(decoded0++) = SCALE(left); } } #endif } else { /* Stereo */ entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed, decoded0, decoded1, count); if ((ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) == APE_FRAMECODE_STEREO_SILENCE) { /* We are pure silence, so we're done. */ return 0; } /* Apply filters - compression type 1000 doesn't have any */ switch (ape_ctx->compressiontype) { case 2000: apply_filter_16_11(ape_ctx->fileversion,decoded0,decoded1,count); break; case 3000: apply_filter_64_11(ape_ctx->fileversion,decoded0,decoded1,count); break; case 4000: apply_filter_32_10(ape_ctx->fileversion,decoded0,decoded1,count); apply_filter_256_13(ape_ctx->fileversion,decoded0,decoded1,count); break; case 5000: apply_filter_16_11(ape_ctx->fileversion,decoded0,decoded1,count); apply_filter_256_13(ape_ctx->fileversion,decoded0,decoded1,count); apply_filter_1280_15(ape_ctx->fileversion,decoded0,decoded1,count); } /* Now apply the predictor decoding */ predictor_decode_stereo(&ape_ctx->predictor,decoded0,decoded1,count); /* Decorrelate and scale to output depth */ while (count--) { left = *decoded1 - (*decoded0 / 2); right = left + *decoded0; *(decoded0++) = SCALE(left); *(decoded1++) = SCALE(right); } } return 0; }