From 0479994c4cea0a917468f79713583d58892d17d9 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Tue, 30 Aug 2016 23:33:08 +0100 Subject: [PATCH] Apple ALAC decoder not working -- magic cookie contents are faulty. --- apple_alac.cpp | 30 ++++++++++++++---------------- apple_alac.h | 2 +- player.c | 4 ++-- shairport.c | 2 +- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/apple_alac.cpp b/apple_alac.cpp index 5c633fb9..3996cfe3 100644 --- a/apple_alac.cpp +++ b/apple_alac.cpp @@ -16,25 +16,23 @@ typedef struct magicCookie { magicCookie cookie; ALACDecoder * theDecoder; -extern "C" int apple_alac_init(int frame_size,int sample_size,int sample_rate) { +extern "C" int apple_alac_init(int32_t fmtp[12]) { memset(&cookie,0,sizeof(magicCookie)); - #define CHANNELS_PER_FRAME 2 - - //create a magic cookie for the decoder + //create a magic cookie for the decoder from the fmtp information. It seems to be in the same format as a simple magic cookie - cookie.config.frameLength = Swap32NtoB(frame_size); - cookie.config.compatibleVersion = 0; - cookie.config.bitDepth = sample_size; - cookie.config.pb = 40; - cookie.config.mb = 10; - cookie.config.kb = 14; - cookie.config.numChannels = CHANNELS_PER_FRAME; - cookie.config.maxRun = Swap16NtoB(255); - cookie.config.maxFrameBytes = 0; - cookie.config.avgBitRate = 0; - cookie.config.sampleRate = Swap32NtoB(sample_rate); + cookie.config.frameLength = Swap32NtoB(352); + cookie.config.compatibleVersion = fmtp[2]; // should be zero, uint8_t + cookie.config.bitDepth = fmtp[3]; // uint8_t expected to be 16 + cookie.config.pb = fmtp[4]; // uint8_t should be 40; + cookie.config.mb = fmtp[5]; // uint8_t should be 10; + cookie.config.kb = fmtp[6]; // uint8_t should be 14; + cookie.config.numChannels = fmtp[7]; // uint8_t expected to be 2 + cookie.config.maxRun = Swap16NtoB(fmtp[8]); // uint16_t expected to be 255 + cookie.config.maxFrameBytes = Swap32NtoB(fmtp[9]); // uint32_t should be 0; + cookie.config.avgBitRate = Swap32NtoB(fmtp[10]); // uint32_t should be 0;; + cookie.config.sampleRate = Swap32NtoB(fmtp[11]); // uint32_t expected to be 44100; theDecoder = new ALACDecoder; theDecoder->Init(&cookie, sizeof(magicCookie)); @@ -47,7 +45,7 @@ extern "C" int apple_alac_decode_frame(unsigned char *sampleBuffer, uint32_t buf uint32_t numFrames = 0; BitBuffer theInputBuffer; BitBufferInit(&theInputBuffer, sampleBuffer, bufferLength); - theDecoder->Decode(&theInputBuffer, dest, Swap32BtoN(cookie.config.frameLength), CHANNELS_PER_FRAME, &numFrames); + theDecoder->Decode(&theInputBuffer, dest, Swap32BtoN(cookie.config.frameLength), cookie.config.numChannels, &numFrames); *outsize = numFrames; return 0; } diff --git a/apple_alac.h b/apple_alac.h index 61eb685c..11ed4ded 100644 --- a/apple_alac.h +++ b/apple_alac.h @@ -11,7 +11,7 @@ #endif -EXTERNC int apple_alac_init(int frame_size,int sample_size,int sample_rate); +EXTERNC int apple_alac_init(int32_t fmtp[12]); EXTERNC int apple_alac_terminate(); EXTERNC int apple_alac_decode_frame(unsigned char *sampleBuffer, uint32_t bufferLength, unsigned char *dest, int *outsize); diff --git a/player.c b/player.c index 9cfda6d1..933ee1bc 100644 --- a/player.c +++ b/player.c @@ -365,7 +365,7 @@ static int init_decoder(int32_t fmtp[12]) { input_num_channels = fmtp[7]; input_bit_depth = fmtp[3]; - input_bytes_per_frame = input_num_channels*(input_bit_depth+7)/8; + input_bytes_per_frame = input_num_channels*((input_bit_depth+7)/8); alac = alac_create(input_bit_depth, input_num_channels); if (!alac) @@ -386,7 +386,7 @@ static int init_decoder(int32_t fmtp[12]) { alac_allocate_buffers(alac); #ifdef HAVE_APPLE_ALAC - apple_alac_init(max_frames_per_packet,input_bit_depth,input_sample_rate); + apple_alac_init(fmtp); #endif return 0; diff --git a/shairport.c b/shairport.c index 219f95e1..afcccac3 100644 --- a/shairport.c +++ b/shairport.c @@ -442,7 +442,7 @@ int parse_options(int argc, char **argv) { } /* Get the alac_decoder setting. */ - if (config_lookup_string(config.cfg, "alac_decoder", &str)) { + if (config_lookup_string(config.cfg, "general.alac_decoder", &str)) { if (strcasecmp(str, "hammerton") == 0) config.use_apple_decoder = 0; else if (strcasecmp(str, "apple") == 0) {