]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Merge stability changes to develoment branch and its convolution additions
authorMike Brady <mikebrady@eircom.net>
Sat, 11 Mar 2017 14:18:52 +0000 (14:18 +0000)
committerMike Brady <mikebrady@eircom.net>
Sat, 11 Mar 2017 14:18:52 +0000 (14:18 +0000)
1  2 
player.c

diff --cc player.c
index ebc988437196a398876a96cfebc38bcff61c7762,f6187c84ba16361405733bb8be1b1810d269de57..8dba9bc864db862d78d03d7af55abaf7d89ae6d1
+++ b/player.c
  #include "apple_alac.h"
  #endif
  
- // 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;
 +#include "loudness.h"
 +
  // 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");
    }
    }
  
    // 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
  
            // 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;
              } 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.
              if (config.no_sync != 0)
                amount_to_stuff = 0; // no stuffing if it's been disabled
  
-                 float gain = fix_volume / 65536.0f;
 +            
 +            // 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; i<inbuflength; ++i)
 +              {
 +                fbuf_l[i] = tbuf32[2*i];
 +                fbuf_r[i] = tbuf32[2*i+1];
 +              }
 +              
 +#ifdef CONFIG_CONVOLUTION
 +              // Apply convolution
 +              if (config.convolution)
 +              {
 +                convolver_process_l(fbuf_l, inbuflength);
 +                convolver_process_r(fbuf_r, inbuflength);
 +                
 +                float gain = pow(10.0, config.convolution_gain/20.0);
 +                for (i=0; i<inbuflength; ++i)
 +                {
 +                  fbuf_l[i] *= gain;
 +                  fbuf_r[i] *= gain;
 +                }
 +                
 +              }
 +#endif
 +              
 +              if (config.loudness)
 +              {
 +                // Apply volume and loudness
 +                // Volume must be applied here because the loudness filter will increase the signal level and it would saturate the int32_t otherwise                
++                float gain = conn->fix_volume / 65536.0f;
 +                float gain_db = 20*log10(gain);
 +                //debug(1, "Applying soft volume dB: %f k: %f", gain_db, gain);
 +                
 +                for (i=0; i<inbuflength; ++i)
 +                {
 +                  fbuf_l[i] = loudness_process(&loudness_l, fbuf_l[i] * gain);
 +                  fbuf_r[i] = loudness_process(&loudness_r, fbuf_r[i] * gain);
 +                }
 +              }
 +              
 +              // Interleave and convert back to int32_t
 +              for (i=0; i<inbuflength; ++i)
 +              {
 +                tbuf32[2*i]   = fbuf_l[i];
 +                tbuf32[2*i+1] = fbuf_r[i];
 +              }
 +              
 +            }
 +            
  #ifdef HAVE_LIBSOXR
              switch (config.packet_stuffing) {
              case ST_basic:
@@@ -2326,13 -2195,10 +2262,13 @@@ void player_volume(double airplay_volum
    // debug(1,"Software attenuation set to %f, i.e %f out of 65,536, for airplay volume of
    // %f",software_attenuation,temp_fix_volume,airplay_volume);
  
-   pthread_mutex_lock(&vol_mutex);
-   fix_volume = temp_fix_volume;
-   pthread_mutex_unlock(&vol_mutex);
-   
+   pthread_mutex_lock(&conn->vol_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) {