Adrian,

Not pretty I know. I'll leave it to you for an elegant solution.

If the track rate already equals the max we can resample to, don't
resample! (If you try to create the soxr process with input_rate ==
output_rate, it's SEGV's. ;))

The values that you pass into sox_process really do need to be size_t!
;) I spent 20 mins trying to figure out why process.sample_factor was
getting set to zero, before realizing it was getting blatted after a
call to soxr_process.


Code:
--------------------
    
  --- /home/clivem/development/git/squeezelite/process.c        2013-06-01 
22:12:46.218869180 +0100
  +++ process.c 2013-06-02 13:39:15.053954507 +0100
  @@ -44,54 +44,80 @@
        // transfer all frames after processing to the output buf
        // this wastes an extra buffer and memcpy to avoid holding the output 
mutex during processing
        // not sure if this is beneficial yet...
  -     size_t frames = process.out_frames;
  -     u32_t *iptr   = (u32_t *)process.outbuf;
  +     size_t frames;
  +     u32_t *iptr;
  +
  +     if (process.sample_factor > 1) {
  +             frames = process.out_frames;
  +             iptr = (u32_t *)process.outbuf;
  +     } else {
  +             frames = process.in_frames;
  +             iptr = (u32_t *)process.inbuf;
  +     }
  +
  +     LOG_SDEBUG("START: frames to process: %d", frames);
  
        LOCK_O;
  
        while (frames > 0) {
                frames_t f = min(_buf_space(outputbuf), 
_buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
  -             u32_t *optr = (u32_t *)outputbuf->writep;
  -
  -             f = min(f, frames);
  -
  -             memcpy(optr, iptr, f * BYTES_PER_FRAME);
  -             
  -             frames -= f;
  -
  -             _buf_inc_writep(outputbuf, f * BYTES_PER_FRAME);
  -             iptr += f * BYTES_PER_FRAME / sizeof(*iptr);
  +             LOG_DEBUG("avail: %d", f);
  +             if (f > 0) {
  +                     u32_t *optr = (u32_t *)outputbuf->writep;
  +
  +                     f = min(f, frames);
  +
  +                     memcpy(optr, iptr, f * BYTES_PER_FRAME);
  +
  +                     frames -= f;
  +
  +                     _buf_inc_writep(outputbuf, f * BYTES_PER_FRAME);
  +                     iptr += f * BYTES_PER_FRAME / sizeof(*iptr);
  +                     LOG_SDEBUG("processed: %d, remaining: %d", f, frames);
  +             } else {
  +                     UNLOCK_O;
  +                     LOG_SDEBUG("Waiting for space!");
  +                     usleep(50000);
  +                     LOCK_O;
  +             }
        }
  
        UNLOCK_O;
  +
  +     LOG_SDEBUG("FINISH: frames to process: %d", frames);
  }
  
  // always called with decode mutex locked
  
  void process_samples(void) {
  -     unsigned idone;
  +     size_t idone;
  
  -     soxr_error_t error =
  -             soxr_process(resampler, process.inbuf, process.in_frames, 
&idone, process.outbuf, process.max_frames, &process.out_frames);
  -     if (error) {
  -             LOG_INFO("soxr_process error: %s", soxr_strerror(error));
  -     } 
  -
  -     if (idone != process.in_frames) {
  -             // should not get here if buffers are big enough...
  -             LOG_ERROR("should not get here - partial sox process: %u of 
%u", idone, process.in_frames);
  +     if (process.sample_factor > 1) {
  +             soxr_error_t error =
  +                     soxr_process(resampler, process.inbuf, 
process.in_frames, &idone, process.outbuf, process.max_frames, 
&process.out_frames);
  +             if (error) {
  +                     LOG_INFO("soxr_process error: %s", 
soxr_strerror(error));
  +             }
  +
  +             if (idone != process.in_frames) {
  +                     // should not get here if buffers are big enough...
  +                     LOG_ERROR("should not get here - partial sox process: 
%u of %u", idone, process.in_frames);
  +             }
        }
  
        _write_samples();
  }
  
  void process_drain(void) {
  -     soxr_error_t error = soxr_process(resampler, NULL, 0, NULL, 
process.outbuf, process.max_frames, &process.out_frames);
  -     if (error) {
  -             LOG_INFO("soxr_process error: %s", soxr_strerror(error));
  -     } 
  
  -     _write_samples();
  +     if (process.sample_factor > 1) {
  +             soxr_error_t error = soxr_process(resampler, NULL, 0, NULL, 
process.outbuf, process.max_frames, &process.out_frames);
  +             if (error) {
  +                     LOG_INFO("soxr_process error: %s", 
soxr_strerror(error));
  +             }
  +
  +             _write_samples();
  +     }
  }
  
  unsigned process_newstream(unsigned raw_sample_rate, unsigned 
max_sample_rate) {
  @@ -130,18 +156,19 @@
                resampler = NULL;
        }
  
  -     soxr_io_spec_t io_spec = soxr_io_spec(SOXR_INT32_I, SOXR_INT32_I);
  -     soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_VHQ | 
SOXR_MINIMUM_PHASE | SOXR_STEEP_FILTER, 0);
  -     soxr_error_t error;
  -
  -     // FIXME - this needs adjustment?
  -     io_spec.scale = 0.9;
  +     if (process.sample_factor > 1) {
  +             soxr_io_spec_t io_spec = soxr_io_spec(SOXR_INT32_I, 
SOXR_INT32_I);
  +             soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_VHQ | 
SOXR_MINIMUM_PHASE | SOXR_STEEP_FILTER, 0);
  +             soxr_error_t error;
        
  -     resampler = soxr_create(raw_sample_rate, outrate, 2, &error, &io_spec, 
&q_spec, NULL);
  -     if (error) {
  -             LOG_INFO("soxr_create error: %s", soxr_strerror(error));
  -     }
  +             // FIXME - this needs adjustment?
  +             io_spec.scale = 0.9;
  
  +             resampler = soxr_create(raw_sample_rate, outrate, 2, &error, 
&io_spec, &q_spec, NULL);
  +             if (error) {
  +                     LOG_INFO("soxr_create error: %s", soxr_strerror(error));
  +             }
  +     }
        return outrate;
  }
  
  --- /home/clivem/development/git/squeezelite/squeezelite.h    2013-06-01 
22:12:46.219869151 +0100
  +++ squeezelite.h     2013-06-02 13:42:56.377267112 +0100
  @@ -358,8 +358,8 @@
  
  struct processstate {
        u8_t *inbuf, *outbuf;
  -     unsigned max_frames;
  -     unsigned in_frames, out_frames;
  +     size_t max_frames;
  +     size_t in_frames, out_frames;
        unsigned sample_factor;
        unsigned sample_rate;
  };
  
--------------------


------------------------------------------------------------------------
JackOfAll's Profile: http://forums.slimdevices.com/member.php?userid=3069
View this thread: http://forums.slimdevices.com/showthread.php?t=98544

_______________________________________________
unix mailing list
[email protected]
http://lists.slimdevices.com/mailman/listinfo/unix

Reply via email to