From: Mike Brady Date: Sat, 11 Mar 2017 14:18:52 +0000 (+0000) Subject: Merge stability changes to develoment branch and its convolution additions X-Git-Tag: 3.1.d1~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=684565679cebfdb27095da421a961e7e63450590;p=thirdparty%2Fshairport-sync.git Merge stability changes to develoment branch and its convolution additions --- 684565679cebfdb27095da421a961e7e63450590 diff --cc player.c index ebc98843,f6187c84..8dba9bc8 --- a/player.c +++ b/player.c @@@ -80,61 -76,9 +80,11 @@@ #include "apple_alac.h" #endif +#include "loudness.h" + - // parameters from the source - static unsigned char *aesiv; - #ifdef HAVE_LIBSSL - static AES_KEY aes; - #endif - static int input_rate, input_bit_depth, input_num_channels, max_frames_per_packet; - - static uint32_t timestamp_epoch, last_timestamp, - maximum_timestamp_interval; // timestamp_epoch of zero means not initialised, could start at 2 - // or 1. - - static int input_bytes_per_frame = 4; - static int output_bytes_per_frame; - static int output_sample_ratio; - static int output_rate; - static int64_t previous_random_number = 0; - - // The maximum frame size change there can be is +/- 1; - static int max_frame_size_change; - // #define FRAME_BYTES(max_frames_per_packet) (4 * max_frames_per_packet) - // maximal resampling shift - conservative - //#define OUTFRAME_BYTES(max_frames_per_packet) (4 * (max_frames_per_packet + 3)) - - #ifdef HAVE_LIBMBEDTLS - static mbedtls_aes_context dctx; - #endif - - #ifdef HAVE_LIBPOLARSSL - static aes_context dctx; - #endif - - // static pthread_t player_thread = NULL; - static int please_stop; - static int encrypted; // Normally the audio is encrypted, but it may not be - - static int - connection_state_to_output; // if true, then play incoming stuff; if false drop everything - - static alac_file *decoder_info; - - // debug variables - static int late_packet_message_sent; - static uint64_t packet_count = 0; - static int32_t last_seqno_read; - static int decoder_in_use = 0; - - // interthread variables - static int fix_volume = 0x10000; - static pthread_mutex_t vol_mutex = PTHREAD_MUTEX_INITIALIZER; - // default buffer size // needs to be a power of 2 because of the way BUFIDX(seqno) works - #define BUFFER_FRAMES 512 + //#define BUFFER_FRAMES 512 #define MAX_PACKET 2048 // DAC buffer occupancy stuff @@@ -642,19 -548,14 +554,19 @@@ int32_t rand_in_range(int32_t exclusive } static inline void process_sample(int32_t sample, char **outp, enum sps_format_t format, int volume, - int dither) { + int dither,rtsp_conn_info *conn) { int64_t hyper_sample = sample; int result; - int64_t hyper_volume = (int64_t)volume << 16; - hyper_sample = hyper_sample * hyper_volume; // this is 64 bit bit multiplication -- we may need to - // dither it down to its - // target resolution - + + if (config.loudness) { + hyper_sample <<= 32; // Do not apply volume as it has already been done with the Loudness DSP filter + } else { + int64_t hyper_volume = (int64_t)volume << 16; + hyper_sample = hyper_sample * hyper_volume; // this is 64 bit bit multiplication -- we may need to + // dither it down to its + // target resolution + } + // next, do dither, if necessary if (dither) { @@@ -1486,7 -1404,7 +1414,7 @@@ static void *player_thread_func(void *a debug(1, "Output bit depth is %d.", output_bit_depth); - if (input_bit_depth > output_bit_depth) { - if (conn->input_bit_depth > output_bit_depth) { ++ if (conn->input_bit_depth >output_bit_depth) { debug(1, "Dithering will be enabled because the input bit depth is greater than the output bit " "depth"); } @@@ -1495,37 -1413,36 +1423,35 @@@ } // we need an intermediate "transition" buffer - - // debug(1,"Define tbuf of length - // %d.",output_bytes_per_frame*(max_frames_per_packet*output_sample_ratio+max_frame_size_change)); - - tbuf = malloc(sizeof(int32_t) * 2 * - (max_frames_per_packet * output_sample_ratio + max_frame_size_change)); - if (tbuf == NULL) - die("Failed to allocate memory for the transition buffer."); - sbuf = 0; - if (config.packet_stuffing == ST_soxr) { // needed for stuffing - sbuf = malloc(sizeof(int32_t) * 2 * - (max_frames_per_packet * output_sample_ratio + max_frame_size_change)); - if (sbuf == NULL) - die("Failed to allocate sbuf memory for the transition buffer."); - } - + + // if ((input_rate!=config.output_rate) || (input_bit_depth!=output_bit_depth)) { + // debug(1,"Define tbuf of length + // %d.",output_bytes_per_frame*(max_frames_per_packet*output_sample_ratio+max_frame_size_change)); + tbuf = malloc(sizeof(int32_t) * 2 * + (conn->max_frames_per_packet * conn->output_sample_ratio + conn->max_frame_size_change)); + if (tbuf == NULL) - debug(1, "Failed to allocate memory for the transition buffer."); ++ die("Failed to allocate memory for the transition buffer."); + sbuf = 0; + if (config.packet_stuffing == ST_soxr) { // needed for stuffing + sbuf = malloc(sizeof(int32_t) * 2 * + (conn->max_frames_per_packet * conn->output_sample_ratio + conn->max_frame_size_change)); + if (sbuf == NULL) - debug(1, "Failed to allocate memory for the transition buffer."); ++ debug(1, "Failed to allocate memory for the sbuf buffer."); + } - // We might need an output buffer and a buffer of silence. // The size of these dependents on the number of frames, the size of each frame and the maximum // size change - outbuf = malloc(output_bytes_per_frame * - (max_frames_per_packet * output_sample_ratio + max_frame_size_change)); + outbuf = malloc(conn->output_bytes_per_frame * + (conn->max_frames_per_packet * conn->output_sample_ratio + conn->max_frame_size_change)); if (outbuf == NULL) - debug(1, "Failed to allocate memory for an output buffer."); + die("Failed to allocate memory for an output buffer."); - silence = malloc(output_bytes_per_frame * max_frames_per_packet * output_sample_ratio); + silence = malloc(conn->output_bytes_per_frame * conn->max_frames_per_packet * conn->output_sample_ratio); if (silence == NULL) - debug(1, "Failed to allocate memory for a silence buffer."); + die("Failed to allocate memory for a silence buffer."); - memset(silence, 0, output_bytes_per_frame * max_frames_per_packet * output_sample_ratio); - late_packet_message_sent = 0; - first_packet_timestamp = 0; - missing_packets = late_packets = too_late_packets = resend_requests = 0; - flush_rtp_timestamp = 0; // it seems this number has a special significance -- it seems to be used + memset(silence, 0, conn->output_bytes_per_frame * conn->max_frames_per_packet * conn->output_sample_ratio); + conn->first_packet_timestamp = 0; + conn->missing_packets = conn->late_packets = conn->too_late_packets = conn->resend_requests = 0; + conn->flush_rtp_timestamp = 0; // it seems this number has a special significance -- it seems to be used // as a null operand, so we'll use it like that too int sync_error_out_of_bounds = 0; // number of times in a row that there's been a serious sync error @@@ -1596,7 -1505,8 +1514,7 @@@ // here, let's transform the frame of data, if necessary - switch (input_bit_depth) { - if (tbuf != NULL) { // this will be null if no changes are needed - switch (conn->input_bit_depth) { ++ switch (conn->input_bit_depth) { case 16: { int i, j; int16_t ls, rs; @@@ -1670,10 -1580,12 +1588,10 @@@ } break; default: die("Shairport Sync only supports 16 bit input"); - } - - // inbuf = tbuf; - inbuflength *= conn->output_sample_ratio; } - inbuflength *= output_sample_ratio; ++ inbuflength *= conn->output_sample_ratio; + // We have a frame of data. We need to see if we want to add or remove a frame from it to // keep in sync. // So we calculate the timing error for the first frame in the DAC. @@@ -1826,67 -1738,6 +1744,67 @@@ if (config.no_sync != 0) amount_to_stuff = 0; // no stuffing if it's been disabled + + // Apply DSP here + if (config.loudness +#ifdef CONFIG_CONVOLUTION + || config.convolution +#endif + ) + { + int32_t *tbuf32 = (int32_t*)tbuf; + float fbuf_l[inbuflength]; + float fbuf_r[inbuflength]; + + // Deinterleave, and convert to float + int i; + for (i=0; ifix_volume / 65536.0f; + float gain_db = 20*log10(gain); + //debug(1, "Applying soft volume dB: %f k: %f", gain_db, gain); + + for (i=0; ivol_mutex); + conn->fix_volume = temp_fix_volume; + pthread_mutex_unlock(&conn->vol_mutex); + + if (config.loudness) + loudness_set_volume(software_attenuation/100); + #ifdef CONFIG_METADATA char *dv = malloc(128); // will be freed in the metadata thread if (dv) {