Changeset 18c6b20


Ignore:
Timestamp:
Jul 16, 2012, 8:19:31 PM (8 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/constantq, feature/pitchshift, feature/pydocstrings, feature/timestretch, master, pitchshift, sampler, timestretch, yinfft+
Children:
d22cc42
Parents:
ab7d100
Message:

src/io/source_sndfile.c: improve resampling, clarify

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/io/source_sndfile.c

    rab7d100 r18c6b20  
    3434#define MAX_CHANNELS 6
    3535#define MAX_SIZE 4096
     36#define MAX_SAMPLES MAX_CHANNELS * MAX_SIZE
    3637
    3738struct _aubio_source_sndfile_t {
     
    3940  uint_t samplerate;
    4041  uint_t channels;
     42
     43  // some data about the file
     44  char_t *path;
     45  SNDFILE *handle;
    4146  int input_samplerate;
    4247  int input_channels;
    4348  int input_format;
    44   char_t *path;
    45   SNDFILE *handle;
     49
     50  // resampling stuff
     51  smpl_t ratio;
     52  uint_t input_hop_size;
     53#ifdef HAVE_SAMPLERATE
     54  aubio_resampler_t *resampler;
     55  fvec_t *input_data;
     56#endif /* HAVE_SAMPLERATE */
     57
     58  // some temporary memory for sndfile to write at
    4659  uint_t scratch_size;
    4760  smpl_t *scratch_data;
    48 
    49   smpl_t ratio;
    50 
    51 #ifdef HAVE_SAMPLERATE
    52   aubio_resampler_t *resampler;
    53   fvec_t *resampled_data;
    54 #endif /* HAVE_SAMPLERATE */
    5561};
    5662
     
    7682    /* show libsndfile err msg */
    7783    AUBIO_ERR("Failed opening %s: %s\n", s->path, sf_strerror (NULL));
    78     return NULL;
     84    goto beach;
    7985  }     
    80 
    81   if (sfinfo.channels > MAX_CHANNELS) {
    82     AUBIO_ERR("Not able to process more than %d channels\n", MAX_CHANNELS);
    83     return NULL;
    84   }
    8586
    8687  /* get input specs */
     
    8990  s->input_format     = sfinfo.format;
    9091
     92  /* compute input block size required before resampling */
    9193  s->ratio = s->samplerate/(float)s->input_samplerate;
     94  s->input_hop_size = (uint_t)FLOOR(s->hop_size / s->ratio + .5);
    9295
    93   if (s->ratio != 1) {
    94 #ifdef HAVE_SAMPLERATE
    95     s->resampler = new_aubio_resampler(s->ratio, 0);
    96     s->resampled_data = new_fvec(s->hop_size / s->ratio);
    97     if (s-> ratio > 1) {
    98       AUBIO_WRN("upsampling from %d to % d\n", s->input_samplerate, s->samplerate);
    99     }
    100 #else
    101     AUBIO_ERR("can not read %s at samplerate %dHz\n", s->path, s->samplerate);
    102     AUBIO_ERR("aubio was compiled without aubio_resampler\n");
    103     return NULL;
    104 #endif /* HAVE_SAMPLERATE */
     96  if (s->input_hop_size * s->input_channels > MAX_SAMPLES) {
     97    AUBIO_ERR("Not able to process more than %d frames of %d channels\n",
     98        MAX_SAMPLES / s->input_channels, s->input_channels);
     99    goto beach;
    105100  }
    106101
    107   s->scratch_size = s->hop_size * s->input_channels / s->ratio;
     102#ifdef HAVE_SAMPLERATE
     103  s->resampler = NULL;
     104  s->input_data = NULL;
     105  if (s->ratio != 1) {
     106    s->input_data = new_fvec(s->input_hop_size);
     107    s->resampler = new_aubio_resampler(s->ratio, 0);
     108    if (s-> ratio > 1) {
     109      AUBIO_WRN("upsampling %s from %d to % d\n", s->path, s->input_samplerate, s->samplerate);
     110    }
     111  }
     112#else
     113  if (s->ratio != 1) {
     114    AUBIO_ERR("aubio was compiled without aubio_resampler\n");
     115    goto beach;
     116  }
     117#endif /* HAVE_SAMPLERATE */
     118
    108119  /* allocate data for de/interleaving reallocated when needed. */
    109   if (s->scratch_size >= MAX_SIZE * MAX_CHANNELS) {
    110     AUBIO_ERR("%d x %d exceeds maximum aubio_source_sndfile buffer size %d\n",
    111         s->hop_size, s->input_channels, MAX_CHANNELS * MAX_CHANNELS);
    112     return NULL;
    113   }
     120  s->scratch_size = s->input_hop_size * s->input_channels;
    114121  s->scratch_data = AUBIO_ARRAY(float,s->scratch_size);
    115122
    116123  return s;
     124
     125beach:
     126  AUBIO_ERR("can not read %s at samplerate %dHz with hop_size of %d\n",
     127      s->path, s->samplerate, s->hop_size);
     128  del_aubio_source_sndfile(s);
     129  return NULL;
    117130}
    118131
    119132void aubio_source_sndfile_do(aubio_source_sndfile_t * s, fvec_t * read_data, uint_t * read){
    120   sf_count_t read_frames;
    121   int i,j, input_channels = s->input_channels;
    122   int aread;
     133  uint_t i,j, input_channels = s->input_channels;
    123134  /* do actual reading */
    124   read_frames = sf_read_float (s->handle, s->scratch_data, s->scratch_size);
     135  sf_count_t read_samples = sf_read_float (s->handle, s->scratch_data, s->scratch_size);
    125136
    126137  smpl_t *data;
    127138
    128139#ifdef HAVE_SAMPLERATE
    129   if (s->resampler) {
    130     data = s->resampled_data->data;
     140  if (s->ratio != 1) {
     141    data = s->input_data->data;
    131142  } else
    132143#endif /* HAVE_SAMPLERATE */
     
    134145    data = read_data->data;
    135146  }
    136   aread = (int)FLOOR(s->ratio * read_frames / (float)input_channels + .5);
    137147
    138148  /* de-interleaving and down-mixing data  */
    139   for (j = 0; j < read_frames; j++) {
     149  for (j = 0; j < read_samples / input_channels; j++) {
    140150    data[j] = 0;
    141151    for (i = 0; i < input_channels; i++) {
     
    147157#ifdef HAVE_SAMPLERATE
    148158  if (s->resampler) {
    149     aubio_resampler_do(s->resampler, s->resampled_data, read_data);
    150     data = s->resampled_data->data;
     159    aubio_resampler_do(s->resampler, s->input_data, read_data);
    151160  }
    152161#endif /* HAVE_SAMPLERATE */
    153162
    154   *read = aread;
     163  *read = (int)FLOOR(s->ratio * read_samples / input_channels + .5);
    155164}
    156165
     
    161170  }
    162171#ifdef HAVE_SAMPLERATE
    163   if (s->resampler) {
     172  if (s->resampler != NULL) {
    164173    del_aubio_resampler(s->resampler);
    165174  }
    166   if (s->resampled_data) {
    167     del_fvec(s->resampled_data);
     175  if (s->input_data) {
     176    del_fvec(s->input_data);
    168177  }
    169178#endif /* HAVE_SAMPLERATE */
Note: See TracChangeset for help on using the changeset viewer.