diff --git a/Makefile b/Makefile index 4cd42fd1..b3a0f9ea 100644 --- a/Makefile +++ b/Makefile @@ -11,13 +11,12 @@ hairtunes: hairtunes.c alac.c clean: -@rm -rf hairtunes -.PTHONY: all clean - prefix=/usr/local install: hairtunes install -m 0755 hairtunes $(prefix)/bin install -m 0755 shairport.pl $(prefix)/bin -.PHONY: install + +.PTHONY: all clean install .SILENT: clean diff --git a/alac.c b/alac.c index 19156f75..5c40b2e9 100644 --- a/alac.c +++ b/alac.c @@ -6,7 +6,7 @@ * This is the actual decoder. * * http://crazney.net/programs/itunes/alac.html - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -35,9 +35,9 @@ static const int host_bigendian = 0; #include #include #ifdef _WIN32 - #include "stdint_win.h" + #include "stdint_win.h" #else - #include + #include #endif #include "alac.h" @@ -62,9 +62,9 @@ void allocate_buffers(alac_file *alac) alac->outputsamples_buffer_a = malloc(alac->setinfo_max_samples_per_frame * 4); alac->outputsamples_buffer_b = malloc(alac->setinfo_max_samples_per_frame * 4); - - alac->uncompressed_bytes_buffer_a = malloc(alac->setinfo_max_samples_per_frame * 4); - alac->uncompressed_bytes_buffer_b = malloc(alac->setinfo_max_samples_per_frame * 4); + + alac->uncompressed_bytes_buffer_a = malloc(alac->setinfo_max_samples_per_frame * 4); + alac->uncompressed_bytes_buffer_b = malloc(alac->setinfo_max_samples_per_frame * 4); } void alac_set_info(alac_file *alac, char *inputbuffer) @@ -291,117 +291,117 @@ found: #define RICE_THRESHOLD 8 // maximum number of bits for a rice prefix. int32_t entropy_decode_value(alac_file* alac, - int readSampleSize, - int k, - int rice_kmodifier_mask) + int readSampleSize, + int k, + int rice_kmodifier_mask) { - int32_t x = 0; // decoded value - - // read x, number of 1s before 0 represent the rice value. - while (x <= RICE_THRESHOLD && readbit(alac)) - { - x++; - } - - if (x > RICE_THRESHOLD) - { - // read the number from the bit stream (raw value) - int32_t value; - - value = readbits(alac, readSampleSize); - - // mask value - value &= (((uint32_t)0xffffffff) >> (32 - readSampleSize)); - - x = value; - } - else - { - if (k != 1) - { - int extraBits = readbits(alac, k); - - // x = x * (2^k - 1) - x *= (((1 << k) - 1) & rice_kmodifier_mask); - - if (extraBits > 1) - x += extraBits - 1; - else - unreadbits(alac, 1); - } - } - - return x; + int32_t x = 0; // decoded value + + // read x, number of 1s before 0 represent the rice value. + while (x <= RICE_THRESHOLD && readbit(alac)) + { + x++; + } + + if (x > RICE_THRESHOLD) + { + // read the number from the bit stream (raw value) + int32_t value; + + value = readbits(alac, readSampleSize); + + // mask value + value &= (((uint32_t)0xffffffff) >> (32 - readSampleSize)); + + x = value; + } + else + { + if (k != 1) + { + int extraBits = readbits(alac, k); + + // x = x * (2^k - 1) + x *= (((1 << k) - 1) & rice_kmodifier_mask); + + if (extraBits > 1) + x += extraBits - 1; + else + unreadbits(alac, 1); + } + } + + return x; } void entropy_rice_decode(alac_file* alac, - int32_t* outputBuffer, - int outputSize, - int readSampleSize, - int rice_initialhistory, - int rice_kmodifier, - int rice_historymult, - int rice_kmodifier_mask) + int32_t* outputBuffer, + int outputSize, + int readSampleSize, + int rice_initialhistory, + int rice_kmodifier, + int rice_historymult, + int rice_kmodifier_mask) { - int outputCount; - int history = rice_initialhistory; - int signModifier = 0; - - for (outputCount = 0; outputCount < outputSize; outputCount++) - { - int32_t decodedValue; - int32_t finalValue; - int32_t k; - - k = 31 - rice_kmodifier - count_leading_zeros((history >> 9) + 3); - - if (k < 0) k += rice_kmodifier; - else k = rice_kmodifier; - - // note: don't use rice_kmodifier_mask here (set mask to 0xFFFFFFFF) - decodedValue = entropy_decode_value(alac, readSampleSize, k, 0xFFFFFFFF); - - decodedValue += signModifier; - finalValue = (decodedValue + 1) / 2; // inc by 1 and shift out sign bit - if (decodedValue & 1) // the sign is stored in the low bit - finalValue *= -1; - - outputBuffer[outputCount] = finalValue; - - signModifier = 0; - - // update history - history += (decodedValue * rice_historymult) - - ((history * rice_historymult) >> 9); - - if (decodedValue > 0xFFFF) - history = 0xFFFF; - - // special case, for compressed blocks of 0 - if ((history < 128) && (outputCount + 1 < outputSize)) - { - int32_t blockSize; - - signModifier = 1; - - k = count_leading_zeros(history) + ((history + 16) / 64) - 24; - - // note: blockSize is always 16bit - blockSize = entropy_decode_value(alac, 16, k, rice_kmodifier_mask); - - // got blockSize 0s - if (blockSize > 0) - { - memset(&outputBuffer[outputCount + 1], 0, blockSize * sizeof(*outputBuffer)); - outputCount += blockSize; - } - - if (blockSize > 0xFFFF) - signModifier = 0; - - history = 0; - } - } + int outputCount; + int history = rice_initialhistory; + int signModifier = 0; + + for (outputCount = 0; outputCount < outputSize; outputCount++) + { + int32_t decodedValue; + int32_t finalValue; + int32_t k; + + k = 31 - rice_kmodifier - count_leading_zeros((history >> 9) + 3); + + if (k < 0) k += rice_kmodifier; + else k = rice_kmodifier; + + // note: don't use rice_kmodifier_mask here (set mask to 0xFFFFFFFF) + decodedValue = entropy_decode_value(alac, readSampleSize, k, 0xFFFFFFFF); + + decodedValue += signModifier; + finalValue = (decodedValue + 1) / 2; // inc by 1 and shift out sign bit + if (decodedValue & 1) // the sign is stored in the low bit + finalValue *= -1; + + outputBuffer[outputCount] = finalValue; + + signModifier = 0; + + // update history + history += (decodedValue * rice_historymult) + - ((history * rice_historymult) >> 9); + + if (decodedValue > 0xFFFF) + history = 0xFFFF; + + // special case, for compressed blocks of 0 + if ((history < 128) && (outputCount + 1 < outputSize)) + { + int32_t blockSize; + + signModifier = 1; + + k = count_leading_zeros(history) + ((history + 16) / 64) - 24; + + // note: blockSize is always 16bit + blockSize = entropy_decode_value(alac, 16, k, rice_kmodifier_mask); + + // got blockSize 0s + if (blockSize > 0) + { + memset(&outputBuffer[outputCount + 1], 0, blockSize * sizeof(*outputBuffer)); + outputCount += blockSize; + } + + if (blockSize > 0xFFFF) + signModifier = 0; + + history = 0; + } + } } #define SIGN_EXTENDED32(val, bits) ((val << (32 - bits)) >> (32 - bits)) @@ -611,16 +611,16 @@ void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b, } void deinterlace_24(int32_t *buffer_a, int32_t *buffer_b, - int uncompressed_bytes, - int32_t *uncompressed_bytes_buffer_a, int32_t *uncompressed_bytes_buffer_b, + int uncompressed_bytes, + int32_t *uncompressed_bytes_buffer_a, int32_t *uncompressed_bytes_buffer_b, void *buffer_out, int numchannels, int numsamples, uint8_t interlacing_shift, uint8_t interlacing_leftweight) { - int i; + int i; if (numsamples <= 0) return; - + /* weighted interlacing */ if (interlacing_leftweight) { @@ -629,63 +629,63 @@ void deinterlace_24(int32_t *buffer_a, int32_t *buffer_b, int32_t difference, midright; int32_t left; int32_t right; - + midright = buffer_a[i]; difference = buffer_b[i]; - + right = midright - ((difference * interlacing_leftweight) >> interlacing_shift); left = right + difference; - - if (uncompressed_bytes) - { - uint32_t mask = ~(0xFFFFFFFF << (uncompressed_bytes * 8)); - left <<= (uncompressed_bytes * 8); - right <<= (uncompressed_bytes * 8); - - left |= uncompressed_bytes_buffer_a[i] & mask; - right |= uncompressed_bytes_buffer_b[i] & mask; - } - - ((uint8_t*)buffer_out)[i * numchannels * 3] = (left) & 0xFF; - ((uint8_t*)buffer_out)[i * numchannels * 3 + 1] = (left >> 8) & 0xFF; - ((uint8_t*)buffer_out)[i * numchannels * 3 + 2] = (left >> 16) & 0xFF; - - ((uint8_t*)buffer_out)[i * numchannels * 3 + 3] = (right) & 0xFF; - ((uint8_t*)buffer_out)[i * numchannels * 3 + 4] = (right >> 8) & 0xFF; - ((uint8_t*)buffer_out)[i * numchannels * 3 + 5] = (right >> 16) & 0xFF; + + if (uncompressed_bytes) + { + uint32_t mask = ~(0xFFFFFFFF << (uncompressed_bytes * 8)); + left <<= (uncompressed_bytes * 8); + right <<= (uncompressed_bytes * 8); + + left |= uncompressed_bytes_buffer_a[i] & mask; + right |= uncompressed_bytes_buffer_b[i] & mask; + } + + ((uint8_t*)buffer_out)[i * numchannels * 3] = (left) & 0xFF; + ((uint8_t*)buffer_out)[i * numchannels * 3 + 1] = (left >> 8) & 0xFF; + ((uint8_t*)buffer_out)[i * numchannels * 3 + 2] = (left >> 16) & 0xFF; + + ((uint8_t*)buffer_out)[i * numchannels * 3 + 3] = (right) & 0xFF; + ((uint8_t*)buffer_out)[i * numchannels * 3 + 4] = (right >> 8) & 0xFF; + ((uint8_t*)buffer_out)[i * numchannels * 3 + 5] = (right >> 16) & 0xFF; } - + return; } - + /* otherwise basic interlacing took place */ for (i = 0; i < numsamples; i++) { int32_t left, right; - + left = buffer_a[i]; right = buffer_b[i]; - - if (uncompressed_bytes) - { - uint32_t mask = ~(0xFFFFFFFF << (uncompressed_bytes * 8)); - left <<= (uncompressed_bytes * 8); - right <<= (uncompressed_bytes * 8); - - left |= uncompressed_bytes_buffer_a[i] & mask; - right |= uncompressed_bytes_buffer_b[i] & mask; - } - - ((uint8_t*)buffer_out)[i * numchannels * 3] = (left) & 0xFF; - ((uint8_t*)buffer_out)[i * numchannels * 3 + 1] = (left >> 8) & 0xFF; - ((uint8_t*)buffer_out)[i * numchannels * 3 + 2] = (left >> 16) & 0xFF; - - ((uint8_t*)buffer_out)[i * numchannels * 3 + 3] = (right) & 0xFF; - ((uint8_t*)buffer_out)[i * numchannels * 3 + 4] = (right >> 8) & 0xFF; - ((uint8_t*)buffer_out)[i * numchannels * 3 + 5] = (right >> 16) & 0xFF; - + + if (uncompressed_bytes) + { + uint32_t mask = ~(0xFFFFFFFF << (uncompressed_bytes * 8)); + left <<= (uncompressed_bytes * 8); + right <<= (uncompressed_bytes * 8); + + left |= uncompressed_bytes_buffer_a[i] & mask; + right |= uncompressed_bytes_buffer_b[i] & mask; + } + + ((uint8_t*)buffer_out)[i * numchannels * 3] = (left) & 0xFF; + ((uint8_t*)buffer_out)[i * numchannels * 3 + 1] = (left >> 8) & 0xFF; + ((uint8_t*)buffer_out)[i * numchannels * 3 + 2] = (left >> 16) & 0xFF; + + ((uint8_t*)buffer_out)[i * numchannels * 3 + 3] = (right) & 0xFF; + ((uint8_t*)buffer_out)[i * numchannels * 3 + 4] = (right >> 8) & 0xFF; + ((uint8_t*)buffer_out)[i * numchannels * 3 + 5] = (right >> 16) & 0xFF; + } - + } void decode_frame(alac_file *alac, @@ -764,21 +764,21 @@ void decode_frame(alac_file *alac, if (uncompressed_bytes) { - int i; - for (i = 0; i < outputsamples; i++) - { - alac->uncompressed_bytes_buffer_a[i] = readbits(alac, uncompressed_bytes * 8); - } + int i; + for (i = 0; i < outputsamples; i++) + { + alac->uncompressed_bytes_buffer_a[i] = readbits(alac, uncompressed_bytes * 8); + } } entropy_rice_decode(alac, - alac->predicterror_buffer_a, - outputsamples, - readsamplesize, - alac->setinfo_rice_initialhistory, - alac->setinfo_rice_kmodifier, - ricemodifier * alac->setinfo_rice_historymult / 4, - (1 << alac->setinfo_rice_kmodifier) - 1); + alac->predicterror_buffer_a, + outputsamples, + readsamplesize, + alac->setinfo_rice_initialhistory, + alac->setinfo_rice_kmodifier, + ricemodifier * alac->setinfo_rice_historymult / 4, + (1 << alac->setinfo_rice_kmodifier) - 1); if (prediction_type == 0) { /* adaptive fir */ @@ -828,7 +828,7 @@ void decode_frame(alac_file *alac, * as we'll be ORing the low 16bits into this */ audiobits = audiobits << (alac->setinfo_sample_size - 16); audiobits |= readbits(alac, alac->setinfo_sample_size - 16); - audiobits = SignExtend24(audiobits); + audiobits = SignExtend24(audiobits); alac->outputsamples_buffer_a[i] = audiobits; } @@ -850,27 +850,27 @@ void decode_frame(alac_file *alac, } break; } - case 24: - { - int i; - for (i = 0; i < outputsamples; i++) - { - int32_t sample = alac->outputsamples_buffer_a[i]; - - if (uncompressed_bytes) - { - uint32_t mask; - sample = sample << (uncompressed_bytes * 8); - mask = ~(0xFFFFFFFF << (uncompressed_bytes * 8)); - sample |= alac->uncompressed_bytes_buffer_a[i] & mask; - } - - ((uint8_t*)outbuffer)[i * alac->numchannels * 3] = (sample) & 0xFF; - ((uint8_t*)outbuffer)[i * alac->numchannels * 3 + 1] = (sample >> 8) & 0xFF; - ((uint8_t*)outbuffer)[i * alac->numchannels * 3 + 2] = (sample >> 16) & 0xFF; - } - break; - } + case 24: + { + int i; + for (i = 0; i < outputsamples; i++) + { + int32_t sample = alac->outputsamples_buffer_a[i]; + + if (uncompressed_bytes) + { + uint32_t mask; + sample = sample << (uncompressed_bytes * 8); + mask = ~(0xFFFFFFFF << (uncompressed_bytes * 8)); + sample |= alac->uncompressed_bytes_buffer_a[i] & mask; + } + + ((uint8_t*)outbuffer)[i * alac->numchannels * 3] = (sample) & 0xFF; + ((uint8_t*)outbuffer)[i * alac->numchannels * 3 + 1] = (sample >> 8) & 0xFF; + ((uint8_t*)outbuffer)[i * alac->numchannels * 3 + 2] = (sample >> 16) & 0xFF; + } + break; + } case 20: case 32: fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); @@ -962,23 +962,23 @@ void decode_frame(alac_file *alac, /*********************/ if (uncompressed_bytes) { /* see mono case */ - int i; - for (i = 0; i < outputsamples; i++) - { - alac->uncompressed_bytes_buffer_a[i] = readbits(alac, uncompressed_bytes * 8); - alac->uncompressed_bytes_buffer_b[i] = readbits(alac, uncompressed_bytes * 8); - } + int i; + for (i = 0; i < outputsamples; i++) + { + alac->uncompressed_bytes_buffer_a[i] = readbits(alac, uncompressed_bytes * 8); + alac->uncompressed_bytes_buffer_b[i] = readbits(alac, uncompressed_bytes * 8); + } } /* channel 1 */ entropy_rice_decode(alac, - alac->predicterror_buffer_a, - outputsamples, - readsamplesize, - alac->setinfo_rice_initialhistory, - alac->setinfo_rice_kmodifier, - ricemodifier_a * alac->setinfo_rice_historymult / 4, - (1 << alac->setinfo_rice_kmodifier) - 1); + alac->predicterror_buffer_a, + outputsamples, + readsamplesize, + alac->setinfo_rice_initialhistory, + alac->setinfo_rice_kmodifier, + ricemodifier_a * alac->setinfo_rice_historymult / 4, + (1 << alac->setinfo_rice_kmodifier) - 1); if (prediction_type_a == 0) { /* adaptive fir */ @@ -997,13 +997,13 @@ void decode_frame(alac_file *alac, /* channel 2 */ entropy_rice_decode(alac, - alac->predicterror_buffer_b, - outputsamples, - readsamplesize, - alac->setinfo_rice_initialhistory, - alac->setinfo_rice_kmodifier, - ricemodifier_b * alac->setinfo_rice_historymult / 4, - (1 << alac->setinfo_rice_kmodifier) - 1); + alac->predicterror_buffer_b, + outputsamples, + readsamplesize, + alac->setinfo_rice_initialhistory, + alac->setinfo_rice_kmodifier, + ricemodifier_b * alac->setinfo_rice_historymult / 4, + (1 << alac->setinfo_rice_kmodifier) - 1); if (prediction_type_b == 0) { /* adaptive fir */ @@ -1049,13 +1049,13 @@ void decode_frame(alac_file *alac, audiobits_a = readbits(alac, 16); audiobits_a = audiobits_a << (alac->setinfo_sample_size - 16); audiobits_a |= readbits(alac, alac->setinfo_sample_size - 16); - audiobits_a = SignExtend24(audiobits_a); + audiobits_a = SignExtend24(audiobits_a); audiobits_b = readbits(alac, 16); audiobits_b = audiobits_b << (alac->setinfo_sample_size - 16); audiobits_b |= readbits(alac, alac->setinfo_sample_size - 16); - audiobits_b = SignExtend24(audiobits_b); - + audiobits_b = SignExtend24(audiobits_b); + alac->outputsamples_buffer_a[i] = audiobits_a; alac->outputsamples_buffer_b[i] = audiobits_b; } @@ -1078,20 +1078,20 @@ void decode_frame(alac_file *alac, interlacing_leftweight); break; } - case 24: - { - deinterlace_24(alac->outputsamples_buffer_a, + case 24: + { + deinterlace_24(alac->outputsamples_buffer_a, alac->outputsamples_buffer_b, - uncompressed_bytes, - alac->uncompressed_bytes_buffer_a, - alac->uncompressed_bytes_buffer_b, + uncompressed_bytes, + alac->uncompressed_bytes_buffer_a, + alac->uncompressed_bytes_buffer_b, (int16_t*)outbuffer, alac->numchannels, outputsamples, interlacing_shift, - interlacing_leftweight); - break; - } + interlacing_leftweight); + break; + } case 20: case 32: fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); @@ -1115,3 +1115,4 @@ alac_file *create_alac(int samplesize, int numchannels) return newfile; } + diff --git a/alac.h b/alac.h index 17bd8b9d..dd130681 100644 --- a/alac.h +++ b/alac.h @@ -27,9 +27,9 @@ struct alac_file int32_t *outputsamples_buffer_a; int32_t *outputsamples_buffer_b; - - int32_t *uncompressed_bytes_buffer_a; - int32_t *uncompressed_bytes_buffer_b; + + int32_t *uncompressed_bytes_buffer_a; + int32_t *uncompressed_bytes_buffer_b; diff --git a/hairtunes.c b/hairtunes.c index 70cd6e31..0a9612f7 100644 --- a/hairtunes.c +++ b/hairtunes.c @@ -57,8 +57,8 @@ int debug = 0; // default buffer - about half a second //Changed these values to make sound synchronized with airport express during multi-room broadcast. -#define BUFFER_FRAMES 512 -#define START_FILL 282 +#define BUFFER_FRAMES 512 +#define START_FILL 282 #define MAX_PACKET 2048 @@ -137,7 +137,7 @@ int init_decoder(void) { int sample_size = fmtp[3]; if (sample_size != 16) die("only 16-bit samples supported!"); - + alac = create_alac(sample_size, 2); if (!alac) return 1; @@ -215,7 +215,7 @@ int main(int argc, char **argv) { init_rtp(); // open a UDP listen port and start a listener; decode into ring buffer fflush(stdout); init_output(); // resample and output from ring buffer - + char line[128]; int in_line = 0; int n; @@ -249,8 +249,8 @@ int main(int argc, char **argv) { } fprintf(stderr, "bye!\n"); fflush(stderr); - - uninit_output(); + + uninit_output(); return EXIT_SUCCESS; } @@ -372,7 +372,7 @@ void *rtp_thread_func(void *arg) { if (plen < 0) continue; assert(plen<=MAX_PACKET); - + type = packet[1] & ~0x80; if (type == 0x60 || type == 0x56) { // audio data / resend pktp = packet; @@ -440,27 +440,27 @@ int init_rtp(void) { unsigned short port = 6000; while(1) { - if(sock < 0) - sock = socket(type, SOCK_DGRAM, IPPROTO_UDP); - if (sock==-1) - die("Can't create data socket!"); - - if(csock < 0) - csock = socket(type, SOCK_DGRAM, IPPROTO_UDP); - if (csock==-1) - die("Can't create control socket!"); + if(sock < 0) + sock = socket(type, SOCK_DGRAM, IPPROTO_UDP); + if (sock==-1) + die("Can't create data socket!"); + + if(csock < 0) + csock = socket(type, SOCK_DGRAM, IPPROTO_UDP); + if (csock==-1) + die("Can't create control socket!"); *sin_port = htons(port); - int bind1 = bind(sock, (struct sockaddr*)&si, sizeof(si)); - *sin_port = htons(port + 1); - int bind2 = bind(csock, (struct sockaddr*)&si, sizeof(si)); + int bind1 = bind(sock, (struct sockaddr*)&si, sizeof(si)); + *sin_port = htons(port + 1); + int bind2 = bind(csock, (struct sockaddr*)&si, sizeof(si)); - if(bind1 != -1 && bind2 != -1) break; - if(bind1 != -1) { close(sock); sock = -1; } - if(bind2 != -1) { close(csock); csock = -1; } - - port += 3; - } + if(bind1 != -1 && bind2 != -1) break; + if(bind1 != -1) { close(sock); sock = -1; } + if(bind2 != -1) { close(csock); csock = -1; } + + port += 3; + } printf("port: %d\n", port); // let our handler know where we end up listening printf("cport: %d\n", port+1); @@ -525,7 +525,7 @@ static double biquad_filt(biquad_t *bq, double in) { double bf_playback_rate = 1.0; -static double bf_est_drift = 0.0; // local clock is slower by +static double bf_est_drift = 0.0; // local clock is slower by static biquad_t bf_drift_lpf; static double bf_est_err = 0.0, bf_last_err; static biquad_t bf_err_lpf, bf_err_deriv_lpf; @@ -560,7 +560,7 @@ void bf_est_update(short fill) { if (debug) fprintf(stderr, "bf %d err %f drift %f desiring %f ed %f estd %f\r", fill, bf_est_err, bf_est_drift, desired_fill, err_deriv, err_deriv + CONTROL_A*bf_est_err); bf_playback_rate = 1.0 + CONTROL_A*bf_est_err + bf_est_drift; - + bf_last_err = bf_est_err; } @@ -570,7 +570,7 @@ short *buffer_get_frame(void) { seq_t read; pthread_mutex_lock(&ab_mutex); - + buf_fill = ab_write - ab_read; if (buf_fill < 1 || !ab_synced) { // init or underrun. stop and wait if (ab_synced) @@ -648,7 +648,7 @@ void *audio_thread_func(void *arg) { #if HAVE_AO ao_device* dev = arg; #else - PaStream* stream = arg; + PaStream* stream = arg; #endif int i __attribute__((unused)), play_samples; @@ -662,7 +662,7 @@ void *audio_thread_func(void *arg) { if (fancy_resampling) { frame = malloc(frame_size*2*sizeof(float)); outframe = malloc(2*frame_size*2*sizeof(float)); - + srcdat.data_in = frame; srcdat.data_out = outframe; srcdat.input_frames = FRAME_BYTES; @@ -692,18 +692,18 @@ void *audio_thread_func(void *arg) { #endif play_samples = stuff_buffer(bf_playback_rate, inbuf, outbuf); -#if HAVE_AO +#if HAVE_AO ao_play(dev, (char *)outbuf, play_samples*4); #else - int err = Pa_WriteStream(stream, (char *)outbuf, play_samples*4); - if( err != paNoError ) { - printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); - exit(1); - } + int err = Pa_WriteStream(stream, (char *)outbuf, play_samples*4); + if( err != paNoError ) { + printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); + exit(1); + } #endif } - - return 0; + + return 0; } #define NUM_CHANNELS 2 @@ -721,48 +721,48 @@ int init_output(void) { fmt.rate = sampling_rate; fmt.channels = NUM_CHANNELS; fmt.byte_format = AO_FMT_LITTLE; - - ao_device *dev = ao_open_live(driver, &fmt, 0); - void* arg = dev; -#else - err = Pa_Initialize(); - if( err != paNoError ) { - printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); - exit(1); - } - PaStreamParameters outputParameters; - outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ + ao_device *dev = ao_open_live(driver, &fmt, 0); + void* arg = dev; +#else + err = Pa_Initialize(); + if( err != paNoError ) { + printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); + exit(1); + } + + PaStreamParameters outputParameters; + outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ outputParameters.channelCount = NUM_CHANNELS; outputParameters.sampleFormat = paInt16; outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; - + /* -- setup stream -- */ - PaStream* stream = NULL; + PaStream* stream = NULL; err = Pa_OpenStream( - &stream, - NULL, - &outputParameters, - sampling_rate, - OUTFRAME_BYTES, - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - NULL, /* no callback, use blocking API */ - NULL ); /* no callback, so no callback userData */ + &stream, + NULL, + &outputParameters, + sampling_rate, + OUTFRAME_BYTES, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + NULL, /* no callback, use blocking API */ + NULL ); /* no callback, so no callback userData */ if( err != paNoError ) { - printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); - exit(1); - } - - err = Pa_StartStream( stream ); + printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); + exit(1); + } + + err = Pa_StartStream( stream ); if( err != paNoError ) { - printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); - exit(1); - } - - void* arg = stream; + printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); + exit(1); + } + + void* arg = stream; #endif - + #ifdef FANCY_RESAMPLING if (fancy_resampling) src = src_new(SRC_SINC_MEDIUM_QUALITY, 2, &err); @@ -779,9 +779,10 @@ int init_output(void) { int uninit_output(void) { #if HAVE_AO #else - int err = Pa_Terminate(); - if( err != paNoError ) - printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); + int err = Pa_Terminate(); + if( err != paNoError ) + printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); #endif - return 0; + return 0; } + diff --git a/shairport.init.sample b/shairport.init.sample index 4cd73826..915ebbab 100755 --- a/shairport.init.sample +++ b/shairport.init.sample @@ -5,7 +5,7 @@ ### BEGIN INIT INFO # Provides: shairport # Required-Start: $network -# Required-Stop: +# Required-Stop: # Short-Description: shairport - Airtunes emulator! # Description: Airtunes emulator! # Default-Start: 2 3 4 5 diff --git a/shairport.pl b/shairport.pl index 92c9f291..c265892a 100755 --- a/shairport.pl +++ b/shairport.pl @@ -10,10 +10,10 @@ # copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -82,13 +82,13 @@ $SIG{CHLD} = \&REAP; my %conns; $SIG{TERM} = $SIG{INT} = sub { - print "killed\n"; + print "killed\n"; map { eval { kill $_->{decoder_pid} } } keys %conns; kill 9, $avahi_publish; exit 0; }; $SIG{__DIE__} = sub { - print "died\n"; + print "died\n"; map { eval { kill $_->{decoder_pid} } } keys %conns; kill 9, $avahi_publish; }; @@ -100,13 +100,13 @@ if ($avahi_publish==0) { "_raop._tcp", "5000", "tp=UDP","sm=false","sv=false","ek=1","et=0,1","cn=0,1","ch=2","ss=16","sr=44100","pw=false","vn=3","txtvers=1"; - exec 'dns-sd', '-R', - join('', map { sprintf "%02X", $_ } @hw_addr) . "\@$apname", - "_raop._tcp", - ".", - "5000", - "tp=UDP","sm=false","sv=false","ek=1","et=0,1","cn=0,1","ch=2","ss=16","sr=44100","pw=false","vn=3","txtvers=1"; - die "could not run avahi-publish-service nor dns-sd"; + exec 'dns-sd', '-R', + join('', map { sprintf "%02X", $_ } @hw_addr) . "\@$apname", + "_raop._tcp", + ".", + "5000", + "tp=UDP","sm=false","sv=false","ek=1","et=0,1","cn=0,1","ch=2","ss=16","sr=44100","pw=false","vn=3","txtvers=1"; + die "could not run avahi-publish-service nor dns-sd"; } my $airport_pem = join '', ; @@ -148,14 +148,14 @@ sub ip6bin { } pack('S>*', map { hex } (@left, @mid, @right)); -} +} my $sel = new IO::Select($listen); print "listening...\n"; -if ($daemon) { +if ($daemon) { use POSIX; POSIX::setsid or die "setsid: $!"; my $pid = fork(); @@ -178,7 +178,7 @@ while (1) { if ($fh==$listen) { my $new = $listen->accept; printf "new connection from %s\n", $new->sockhost; - + $sel->add($new); $new->blocking(0); $conns{$new} = {fh => $fh}; @@ -210,7 +210,7 @@ sub conn_handle_data { undef $conn->{req_need}; return; } - + read $fh, my $data, 4096; $conn->{data} .= $data; @@ -266,7 +266,7 @@ sub conn_handle_request { } else { $data .= ip6bin($ip); } - + $data .= join '', map { chr } @hw_addr; $data .= chr(0) x (0x20-length($data)); @@ -328,7 +328,7 @@ sub conn_handle_request { )); # print "decode command: $dec\n"; my $decoder = open2(my $dec_out, my $dec_in, $dec); - + $conn->{decoder_pid} = $decoder; $conn->{decoder_fh} = $dec_in; my $portdesc = <$dec_out>;