Changeset e2f1e6d


Ignore:
Timestamp:
Dec 20, 2018, 8:30:50 PM (12 months ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink
Children:
f56f795
Parents:
9630fa8 (diff), a2019c4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'feature/sink_vorbis' into feature/sink_flac

Files:
12 edited

Legend:

Unmodified
Added
Removed
  • .travis.yml

    r9630fa8 re2f1e6d  
    1919      os: linux
    2020      compiler: gcc
    21       env: HAVE_AUBIO_DOUBLE=1 CFLAGS="-O3" WAFOPTS="--enable-fftw3"
     21      env: HAVE_AUBIO_DOUBLE=1 CFLAGS="-O3" WAFOPTS="--enable-fftw3 --disable-avcodec"
    2222    - python: 2.7
    2323      os: linux
  • src/aubio_priv.h

    r9630fa8 re2f1e6d  
    325325#endif
    326326
     327#if !defined(_MSC_VER)
     328#define AUBIO_STRERROR(errno,buf,len) strerror_r(errno, buf, len)
     329#else
     330#define AUBIO_STRERROR(errno,buf,len) strerror_s(buf, len, errno)
     331#endif
     332
    327333/* handy shortcuts */
    328334#define DB2LIN(g) (POW(10.0,(g)*0.05f))
  • src/io/ioutils.c

    r9630fa8 re2f1e6d  
    2020
    2121#include "aubio_priv.h"
     22#include "fmat.h"
    2223
    2324uint_t
     
    5152  }
    5253  return AUBIO_OK;
     54}
     55
     56uint_t
     57aubio_source_validate_input_length(const char_t *kind, const char_t *path,
     58    uint_t hop_size, uint_t read_data_length)
     59{
     60  uint_t length = hop_size;
     61  if (hop_size < read_data_length) {
     62    AUBIO_WRN("%s: partial read from %s, trying to read %d frames, but"
     63        " hop_size is %d\n", kind, path, read_data_length, hop_size);
     64  } else if (hop_size > read_data_length) {
     65    AUBIO_WRN("%s: partial read from %s, trying to read %d frames into"
     66        " a buffer of length %d\n", kind, path, hop_size, read_data_length);
     67    length = read_data_length;
     68  }
     69  return length;
     70}
     71
     72uint_t
     73aubio_source_validate_input_channels(const char_t *kind, const char_t *path,
     74    uint_t source_channels, uint_t read_data_height)
     75{
     76  uint_t channels = source_channels;
     77  if (read_data_height < source_channels) {
     78    AUBIO_WRN("%s: partial read from %s, trying to read %d channels,"
     79        " but found output of height %d\n", kind, path, source_channels,
     80        read_data_height);
     81    channels = read_data_height;
     82  } else if (read_data_height > source_channels) {
     83    // do not show a warning when trying to read into more channels than
     84    // the input source.
     85#if 0
     86    AUBIO_WRN("%s: partial read from %s, trying to read %d channels,"
     87        " but found output of height %d\n", kind, path, source_channels,
     88        read_data_height);
     89#endif
     90    channels = source_channels;
     91  }
     92  return channels;
     93}
     94
     95void
     96aubio_source_pad_output (fvec_t *read_data, uint_t source_read)
     97{
     98  if (source_read < read_data->length) {
     99    AUBIO_MEMSET(read_data->data + source_read, 0,
     100        (read_data->length - source_read) * sizeof(smpl_t));
     101  }
     102}
     103
     104void
     105aubio_source_pad_multi_output (fmat_t *read_data,
     106    uint_t source_channels, uint_t source_read) {
     107  uint_t i;
     108  if (source_read < read_data->length) {
     109    for (i = 0; i < read_data->height; i++) {
     110      AUBIO_MEMSET(read_data->data[i] + source_read, 0,
     111          (read_data->length - source_read) * sizeof(smpl_t));
     112    }
     113  }
     114
     115  // destination matrix has more channels than the file
     116  // copy channels from the source to extra output channels
     117  if (read_data->height > source_channels) {
     118    for (i = source_channels; i < read_data->height; i++) {
     119      AUBIO_MEMCPY(read_data->data[i], read_data->data[i % source_channels],
     120          sizeof(smpl_t) * read_data->length);
     121    }
     122  }
    53123}
    54124
  • src/io/ioutils.h

    r9630fa8 re2f1e6d  
    5454    uint_t channels);
    5555
    56 /** validate length of input
     56/** validate length of source output
     57
     58  \param kind       the object kind to report on
     59  \param path       the path to report on
     60  \param hop_size   number of frames to be read
     61  \param read_data_length actual length of input
     62
     63  \return hop_size or the maximum number of frames that can be written
     64*/
     65uint_t
     66aubio_source_validate_input_length(const char_t *kind, const char_t *path,
     67    uint_t hop_size, uint_t read_data_length);
     68
     69/** validate height of source output
     70
     71  \param kind       the object kind to report on
     72  \param path       the path to report on
     73  \param source_channels maximum number of channels that can be written
     74  \param read_data_height actual height of input
     75
     76  \return write_data_height or the maximum number of channels
     77*/
     78uint_t
     79aubio_source_validate_input_channels(const char_t *kind, const char_t *path,
     80    uint_t source_channels, uint_t read_data_height);
     81
     82/** pad end of source output vector with zeroes
     83
     84  \param read_data   output vector to pad
     85  \param source_read number of frames read
     86
     87*/
     88void
     89aubio_source_pad_output (fvec_t *read_data, uint_t source_read);
     90
     91/** pad end of source output matrix with zeroes
     92
     93  \param read_data   output matrix to pad
     94  \param source_channels number of channels in the source
     95  \param source_read number of frames read
     96
     97*/
     98void
     99aubio_source_pad_multi_output (fmat_t *read_data, uint_t source_channels,
     100        uint_t source_read);
     101
     102/** validate length of sink input
    57103
    58104  \param kind       the object kind to report on
    59105  \param path       the path to report on
    60106  \param max_size   maximum number of frames that can be written
    61   \param write_data_length actual length of input vector/matrix
     107  \param write_data_length actual length of input
    62108  \param write number of samples asked
    63109
     
    68114    uint_t max_size, uint_t write_data_length, uint_t write);
    69115
    70 /** validate height of input
     116/** validate height of sink input
    71117
    72118  \param kind       the object kind to report on
    73119  \param path       the path to report on
    74   \param max_size  maximum number of channels that can be written
     120  \param sink_channels maximum number of channels that can be written
    75121  \param write_data_height actual height of input matrix
    76122
  • src/io/sink_vorbis.c

    r9630fa8 re2f1e6d  
    3737#include <time.h> // time
    3838
    39 #define MAX_SIZE 2048
     39#define MAX_SIZE 4096
    4040
    4141struct _aubio_sink_vorbis_t {
     
    6464void del_aubio_sink_vorbis (aubio_sink_vorbis_t *s);
    6565
     66static uint_t aubio_sink_vorbis_write_page(aubio_sink_vorbis_t *s);
     67
    6668aubio_sink_vorbis_t * new_aubio_sink_vorbis (const char_t *uri,
    6769    uint_t samplerate)
     
    118120  s->fid = fopen((const char *)s->path, "wb");
    119121  if (!s->fid) {
    120     AUBIO_ERR("sink_vorbis: Error opening file %s (%s)\n",
    121         s->path, strerror(errno));
     122    char errorstr[256];
     123    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
     124    AUBIO_ERR("sink_vorbis: Error opening file \'%s\' (%s)\n",
     125        s->path, errorstr);
    122126    return AUBIO_FAIL;
    123127  }
     
    144148  // write header
    145149  {
    146     int ret = 0;
    147     size_t wrote;
    148150    ogg_packet header;
    149151    ogg_packet header_comm;
     
    160162    while (1)
    161163    {
    162       ret = ogg_stream_flush(&s->os, &s->og);
    163       if (ret==0) break;
    164       wrote = fwrite(s->og.header, 1, s->og.header_len, s->fid);
    165       ret = (wrote == (unsigned)s->og.header_len);
    166       wrote = fwrite(s->og.body,   1, s->og.body_len,   s->fid);
    167       ret &= (wrote == (unsigned)s->og.body_len);
    168       if (ret == 0) {
    169         AUBIO_ERR("sink_vorbis: failed writing \'%s\' to disk (%s)\n",
    170             s->path, strerror(errno));
    171         return AUBIO_FAIL;
    172       }
     164      if (!ogg_stream_flush(&s->os, &s->og)) break;
     165      if (aubio_sink_vorbis_write_page(s)) return AUBIO_FAIL;
    173166    }
    174167  }
     
    212205}
    213206
    214 void aubio_sink_vorbis_write(aubio_sink_vorbis_t *s)
    215 {
     207static
     208uint_t aubio_sink_vorbis_write_page(aubio_sink_vorbis_t *s) {
    216209  int result;
    217210  size_t wrote;
     211  wrote = fwrite(s->og.header, 1, s->og.header_len, s->fid);
     212  result = (wrote == (unsigned)s->og.header_len);
     213  wrote = fwrite(s->og.body, 1, s->og.body_len,     s->fid);
     214  result &= (wrote == (unsigned)s->og.body_len);
     215  if (result == 0) {
     216    char errorstr[256];
     217    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
     218    AUBIO_ERR("sink_vorbis: failed writing \'%s\' to disk (%s)\n",
     219        s->path, errorstr);
     220    return AUBIO_FAIL;
     221  }
     222  return AUBIO_OK;
     223}
     224
     225static
     226void aubio_sink_vorbis_write(aubio_sink_vorbis_t *s)
     227{
    218228  // pre-analysis
    219229  while (vorbis_analysis_blockout(&s->vd, &s->vb) == 1) {
     
    227237
    228238      while (1) {
    229         result = ogg_stream_pageout (&s->os, &s->og);
    230         if (result == 0) break;
    231         wrote = fwrite(s->og.header, 1, s->og.header_len, s->fid);
    232         result = (wrote == (unsigned)s->og.header_len);
    233         wrote = fwrite(s->og.body, 1, s->og.body_len,     s->fid);
    234         result &= (wrote == (unsigned)s->og.body_len);
    235         if (result == 0) {
    236           AUBIO_WRN("sink_vorbis: failed writing \'%s\' to disk (%s)\n",
    237               s->path, strerror(errno));
    238         }
     239        if (!ogg_stream_pageout (&s->os, &s->og)) break;
     240        aubio_sink_vorbis_write_page(s);
    239241        if (ogg_page_eos(&s->og)) break;
    240242      }
     
    291293    }
    292294    // tell vorbis how many frames were written
    293     vorbis_analysis_wrote(&s->vd, (long)write);
     295    vorbis_analysis_wrote(&s->vd, (long)length);
    294296  }
    295297
     
    306308
    307309  if (s->fid && fclose(s->fid)) {
    308     AUBIO_ERR("sink_vorbis: Error closing file %s (%s)\n",
    309         s->path, strerror(errno));
     310    char errorstr[256];
     311    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
     312    AUBIO_ERR("sink_vorbis: Error closing file \'%s\' (%s)\n",
     313        s->path, errorstr);
    310314    return AUBIO_FAIL;
    311315  }
  • src/io/sink_wavwrite.c

    r9630fa8 re2f1e6d  
    163163  unsigned char buf[5];
    164164  uint_t byterate, blockalign;
     165  size_t written = 0;
    165166
    166167  /* open output file */
    167168  s->fid = fopen((const char *)s->path, "wb");
    168169  if (!s->fid) {
    169     AUBIO_ERR("sink_wavwrite: could not open %s (%s)\n", s->path, strerror(errno));
     170    char errorstr[256];
     171    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
     172    AUBIO_ERR("sink_wavwrite: could not open %s (%s)\n", s->path, errorstr);
    170173    goto beach;
    171174  }
    172175
    173176  // ChunkID
    174   fwrite("RIFF", 4, 1, s->fid);
     177  written += fwrite("RIFF", 4, 1, s->fid);
    175178
    176179  // ChunkSize (0 for now, actual size will be written in _close)
    177   fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
     180  written += fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
    178181
    179182  // Format
    180   fwrite("WAVE", 4, 1, s->fid);
     183  written += fwrite("WAVE", 4, 1, s->fid);
    181184
    182185  // Subchunk1ID
    183   fwrite("fmt ", 4, 1, s->fid);
     186  written += fwrite("fmt ", 4, 1, s->fid);
    184187
    185188  // Subchunk1Size
    186   fwrite(write_little_endian(16, buf, 4), 4, 1, s->fid);
     189  written += fwrite(write_little_endian(16, buf, 4), 4, 1, s->fid);
    187190
    188191  // AudioFormat
    189   fwrite(write_little_endian(1, buf, 2), 2, 1, s->fid);
     192  written += fwrite(write_little_endian(1, buf, 2), 2, 1, s->fid);
    190193
    191194  // NumChannels
    192   fwrite(write_little_endian(s->channels, buf, 2), 2, 1, s->fid);
     195  written += fwrite(write_little_endian(s->channels, buf, 2), 2, 1, s->fid);
    193196
    194197  // SampleRate
    195   fwrite(write_little_endian(s->samplerate, buf, 4), 4, 1, s->fid);
     198  written += fwrite(write_little_endian(s->samplerate, buf, 4), 4, 1, s->fid);
    196199
    197200  // ByteRate
    198201  byterate = s->samplerate * s->channels * s->bitspersample / 8;
    199   fwrite(write_little_endian(byterate, buf, 4), 4, 1, s->fid);
     202  written += fwrite(write_little_endian(byterate, buf, 4), 4, 1, s->fid);
    200203
    201204  // BlockAlign
    202205  blockalign = s->channels * s->bitspersample / 8;
    203   fwrite(write_little_endian(blockalign, buf, 2), 2, 1, s->fid);
     206  written += fwrite(write_little_endian(blockalign, buf, 2), 2, 1, s->fid);
    204207
    205208  // BitsPerSample
    206   fwrite(write_little_endian(s->bitspersample, buf, 2), 2, 1, s->fid);
     209  written += fwrite(write_little_endian(s->bitspersample, buf, 2), 2, 1, s->fid);
    207210
    208211  // Subchunk2ID
    209   fwrite("data", 4, 1, s->fid);
     212  written += fwrite("data", 4, 1, s->fid);
    210213
    211214  // Subchunk1Size (0 for now, actual size will be written in _close)
    212   fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
     215  written += fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
     216
     217  // fwrite(*, *, 1, s->fid) was called 13 times, check success
     218  if (written != 13) {
     219    char errorstr[256];
     220    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
     221    AUBIO_WRN("sink_wavwrite: writing header to %s failed, expected %d"
     222        " write but got only %d (%s)\n", s->path, 13, written, errorstr);
     223    return AUBIO_FAIL;
     224  }
    213225
    214226  s->scratch_size = s->max_size * s->channels;
     
    227239}
    228240
     241static
     242void aubio_sink_wavwrite_write_frames(aubio_sink_wavwrite_t *s, uint_t write)
     243{
     244  uint_t written_frames = 0;
     245
     246  written_frames = fwrite(s->scratch_data, 2 * s->channels, write, s->fid);
     247
     248  if (written_frames != write) {
     249    char errorstr[256];
     250    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
     251    AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, but only %d"
     252        " could be written (%s)\n", write, s->path, written_frames, errorstr);
     253  }
     254  s->total_frames_written += written_frames;
     255}
    229256
    230257void aubio_sink_wavwrite_do(aubio_sink_wavwrite_t *s, fvec_t * write_data, uint_t write){
    231   uint_t c = 0, i = 0, written_frames = 0;
     258  uint_t c = 0, i = 0;
    232259  uint_t length = aubio_sink_validate_input_length("sink_wavwrite", s->path,
    233260      s->max_size, write_data->length, write);
     
    238265    }
    239266  }
    240   written_frames = fwrite(s->scratch_data, 2, length * s->channels, s->fid);
    241 
    242   if (written_frames != write) {
    243     AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, "
    244         "but only %d could be written\n", write, s->path, written_frames);
    245   }
    246   s->total_frames_written += written_frames;
    247   return;
     267
     268  aubio_sink_wavwrite_write_frames(s, length);
    248269}
    249270
    250271void aubio_sink_wavwrite_do_multi(aubio_sink_wavwrite_t *s, fmat_t * write_data, uint_t write){
    251   uint_t c = 0, i = 0, written_frames = 0;
     272  uint_t c = 0, i = 0;
    252273
    253274  uint_t channels = aubio_sink_validate_input_channels("sink_wavwrite", s->path,
     
    261282    }
    262283  }
    263   written_frames = fwrite(s->scratch_data, 2, length * s->channels, s->fid);
    264 
    265   if (written_frames != write * s->channels) {
    266     AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, "
    267         "but only %d could be written\n", write, s->path, written_frames / s->channels);
    268   }
    269   s->total_frames_written += written_frames;
    270   return;
     284
     285  aubio_sink_wavwrite_write_frames(s, length);
    271286}
    272287
     
    274289  uint_t data_size = s->total_frames_written * s->bitspersample * s->channels / 8;
    275290  unsigned char buf[5];
     291  size_t written = 0, err = 0;
    276292  if (!s->fid) return AUBIO_FAIL;
    277293  // ChunkSize
    278   fseek(s->fid, 4, SEEK_SET);
    279   fwrite(write_little_endian(data_size + 36, buf, 4), 4, 1, s->fid);
     294  err += fseek(s->fid, 4, SEEK_SET);
     295  written += fwrite(write_little_endian(data_size + 36, buf, 4), 4, 1, s->fid);
    280296  // Subchunk2Size
    281   fseek(s->fid, 40, SEEK_SET);
    282   fwrite(write_little_endian(data_size, buf, 4), 4, 1, s->fid);
     297  err += fseek(s->fid, 40, SEEK_SET);
     298  written += fwrite(write_little_endian(data_size, buf, 4), 4, 1, s->fid);
     299  if (written != 2 || err != 0) {
     300    char errorstr[256];
     301    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
     302    AUBIO_WRN("sink_wavwrite: updating header of %s failed, expected %d"
     303        " write but got only %d (%s)\n", s->path, 2, written, errorstr);
     304  }
    283305  // close file
    284306  if (fclose(s->fid)) {
    285     AUBIO_ERR("sink_wavwrite: Error closing file %s (%s)\n", s->path, strerror(errno));
     307    char errorstr[256];
     308    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
     309    AUBIO_ERR("sink_wavwrite: Error closing file %s (%s)\n", s->path, errorstr);
    286310  }
    287311  s->fid = NULL;
  • src/io/source_apple_audio.c

    r9630fa8 re2f1e6d  
    2525#include "fvec.h"
    2626#include "fmat.h"
     27#include "ioutils.h"
    2728#include "io/source_apple_audio.h"
    2829
     
    210211  uint_t c, v;
    211212  UInt32 loadedPackets = aubio_source_apple_audio_read_frame(s);
     213  uint_t length = aubio_source_validate_input_length("source_apple_audio",
     214      s->path, s->block_size, read_to->length);
    212215  smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
    213216
    214   for (v = 0; v < loadedPackets; v++) {
     217  length = MIN(loadedPackets, length);
     218
     219  for (v = 0; v < length; v++) {
    215220    read_to->data[v] = 0.;
    216221    for (c = 0; c < s->channels; c++) {
     
    220225  }
    221226  // short read, fill with zeros
    222   if (loadedPackets < s->block_size) {
    223     for (v = loadedPackets; v < s->block_size; v++) {
    224       read_to->data[v] = 0.;
    225     }
    226   }
    227 
    228   *read = (uint_t)loadedPackets;
    229   return;
     227  aubio_source_pad_output(read_to, length);
     228
     229  *read = (uint_t)length;
    230230}
    231231
    232232void aubio_source_apple_audio_do_multi(aubio_source_apple_audio_t *s, fmat_t * read_to, uint_t * read) {
    233233  uint_t c, v;
     234  uint_t length = aubio_source_validate_input_length("source_apple_audio",
     235      s->path, s->block_size, read_to->length);
     236  uint_t channels = aubio_source_validate_input_channels("source_apple_audio",
     237      s->path, s->channels, read_to->height);
    234238  UInt32 loadedPackets = aubio_source_apple_audio_read_frame(s);
    235239  smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
    236240
    237   for (v = 0; v < loadedPackets; v++) {
    238     for (c = 0; c < read_to->height; c++) {
     241  length = MIN(loadedPackets, length);
     242
     243  for (v = 0; v < length; v++) {
     244    for (c = 0; c < channels; c++) {
    239245      read_to->data[c][v] = data[ v * s->channels + c];
    240246    }
    241247  }
    242   // if read_data has more channels than the file
    243   if (read_to->height > s->channels) {
    244     // copy last channel to all additional channels
    245     for (v = 0; v < loadedPackets; v++) {
    246       for (c = s->channels; c < read_to->height; c++) {
    247         read_to->data[c][v] = data[ v * s->channels + (s->channels - 1)];
    248       }
    249     }
    250   }
    251   // short read, fill with zeros
    252   if (loadedPackets < s->block_size) {
    253     for (v = loadedPackets; v < s->block_size; v++) {
    254       for (c = 0; c < read_to->height; c++) {
    255         read_to->data[c][v] = 0.;
    256       }
    257     }
    258   }
    259 
    260   *read = (uint_t)loadedPackets;
    261   return;
     248
     249  aubio_source_pad_multi_output(read_to, s->channels, (uint_t)length);
     250
     251  *read = (uint_t)length;
    262252}
    263253
  • src/io/source_avcodec.c

    r9630fa8 re2f1e6d  
    6161#include "fvec.h"
    6262#include "fmat.h"
     63#include "ioutils.h"
    6364#include "source_avcodec.h"
    6465
     
    489490  uint_t end = 0;
    490491  uint_t total_wrote = 0;
    491   while (total_wrote < s->hop_size) {
    492     end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
     492  uint_t length = aubio_source_validate_input_length("source_avcodec", s->path,
     493      s->hop_size, read_data->length);
     494  while (total_wrote < length) {
     495    end = MIN(s->read_samples - s->read_index, length - total_wrote);
    493496    for (i = 0; i < end; i++) {
    494497      read_data->data[i + total_wrote] = 0.;
     
    500503    }
    501504    total_wrote += end;
    502     if (total_wrote < s->hop_size) {
     505    if (total_wrote < length) {
    503506      uint_t avcodec_read = 0;
    504507      aubio_source_avcodec_readframe(s, &avcodec_read);
     
    512515    }
    513516  }
    514   if (total_wrote < s->hop_size) {
    515     for (i = total_wrote; i < s->hop_size; i++) {
    516       read_data->data[i] = 0.;
    517     }
    518   }
     517
     518  aubio_source_pad_output(read_data, total_wrote);
     519
    519520  *read = total_wrote;
    520521}
     
    525526  uint_t end = 0;
    526527  uint_t total_wrote = 0;
    527   while (total_wrote < s->hop_size) {
    528     end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
    529     for (j = 0; j < read_data->height; j++) {
     528  uint_t length = aubio_source_validate_input_length("source_wavread", s->path,
     529      s->hop_size, read_data->length);
     530  uint_t channels = aubio_source_validate_input_channels("source_wavread",
     531      s->path, s->input_channels, read_data->height);
     532  while (total_wrote < length) {
     533    end = MIN(s->read_samples - s->read_index, length - total_wrote);
     534    for (j = 0; j < channels; j++) {
    530535      for (i = 0; i < end; i++) {
    531536        read_data->data[j][i + total_wrote] =
     
    534539    }
    535540    total_wrote += end;
    536     if (total_wrote < s->hop_size) {
     541    if (total_wrote < length) {
    537542      uint_t avcodec_read = 0;
    538543      aubio_source_avcodec_readframe(s, &avcodec_read);
     
    546551    }
    547552  }
    548   if (total_wrote < s->hop_size) {
    549     for (j = 0; j < read_data->height; j++) {
    550       for (i = total_wrote; i < s->hop_size; i++) {
    551         read_data->data[j][i] = 0.;
    552       }
    553     }
    554   }
     553
     554  aubio_source_pad_multi_output(read_data, s->input_channels, total_wrote);
     555
    555556  *read = total_wrote;
    556557}
  • src/io/source_sndfile.c

    r9630fa8 re2f1e6d  
    2727#include "fvec.h"
    2828#include "fmat.h"
     29#include "ioutils.h"
    2930#include "source_sndfile.h"
    3031
     
    170171  uint_t i,j, input_channels = s->input_channels;
    171172  /* read from file into scratch_data */
    172   sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data, s->scratch_size);
     173  uint_t length = aubio_source_validate_input_length("source_sndfile", s->path,
     174      s->hop_size, read_data->length);
     175  sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data,
     176      s->input_channels * length);
     177
     178  length = MIN(read_samples / s->input_channels, length);
    173179
    174180  /* where to store de-interleaved data */
     
    184190
    185191  /* de-interleaving and down-mixing data  */
    186   for (j = 0; j < read_samples / input_channels; j++) {
     192  for (j = 0; j < length; j++) {
    187193    ptr_data[j] = 0;
    188194    for (i = 0; i < input_channels; i++) {
     
    198204#endif /* HAVE_SAMPLERATE */
    199205
    200   *read = (int)FLOOR(s->ratio * read_samples / input_channels + .5);
    201 
    202   if (*read < s->hop_size) {
    203     for (j = *read; j < s->hop_size; j++) {
    204       read_data->data[j] = 0;
    205     }
    206   }
     206  *read = (int)FLOOR(s->ratio * length + .5);
     207
     208  aubio_source_pad_output (read_data, *read);
    207209
    208210}
     
    211213  uint_t i,j, input_channels = s->input_channels;
    212214  /* do actual reading */
    213   sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data, s->scratch_size);
     215  uint_t length = aubio_source_validate_input_length("source_sndfile", s->path,
     216      s->hop_size, read_data->length);
     217  uint_t channels = aubio_source_validate_input_channels("source_sndfile",
     218      s->path, s->input_channels, read_data->height);
     219  sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data,
     220      length * s->input_channels);
     221
     222  length = MIN(read_samples / s->input_channels, length);
    214223
    215224  /* where to store de-interleaved data */
     
    224233  }
    225234
    226   if (read_data->height < input_channels) {
    227     // destination matrix has less channels than the file; copy only first
    228     // channels of the file, de-interleaving data
    229     for (j = 0; j < read_samples / input_channels; j++) {
    230       for (i = 0; i < read_data->height; i++) {
    231         ptr_data[i][j] = s->scratch_data[j * input_channels + i];
    232       }
    233     }
    234   } else {
    235     // destination matrix has as many or more channels than the file; copy each
    236     // channel from the file to the destination matrix, de-interleaving data
    237     for (j = 0; j < read_samples / input_channels; j++) {
    238       for (i = 0; i < input_channels; i++) {
    239         ptr_data[i][j] = s->scratch_data[j * input_channels + i];
    240       }
    241     }
    242   }
    243 
    244   if (read_data->height > input_channels) {
    245     // destination matrix has more channels than the file; copy last channel
    246     // of the file to each additional channels, de-interleaving data
    247     for (j = 0; j < read_samples / input_channels; j++) {
    248       for (i = input_channels; i < read_data->height; i++) {
    249         ptr_data[i][j] = s->scratch_data[j * input_channels + (input_channels - 1)];
    250       }
     235  for (j = 0; j < length; j++) {
     236    for (i = 0; i < channels; i++) {
     237      ptr_data[i][j] = s->scratch_data[j * input_channels + i];
    251238    }
    252239  }
     
    265252#endif /* HAVE_SAMPLERATE */
    266253
    267   *read = (int)FLOOR(s->ratio * read_samples / input_channels + .5);
    268 
    269   if (*read < s->hop_size) {
    270     for (i = 0; i < read_data->height; i++) {
    271       for (j = *read; j < s->hop_size; j++) {
    272         read_data->data[i][j] = 0.;
    273       }
    274     }
    275   }
    276 
     254  *read = (int)FLOOR(s->ratio * length + .5);
     255
     256  aubio_source_pad_multi_output(read_data, input_channels, *read);
    277257}
    278258
  • src/io/source_wavread.c

    r9630fa8 re2f1e6d  
    2525#include "fvec.h"
    2626#include "fmat.h"
     27#include "ioutils.h"
    2728#include "source_wavread.h"
    2829
     
    348349  uint_t end = 0;
    349350  uint_t total_wrote = 0;
     351  uint_t length = aubio_source_validate_input_length("source_wavread", s->path,
     352      s->hop_size, read_data->length);
    350353  if (s->fid == NULL) {
    351354    AUBIO_ERR("source_wavread: could not read from %s (file not opened)\n",
     
    353356    return;
    354357  }
    355   while (total_wrote < s->hop_size) {
    356     end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
     358  while (total_wrote < length) {
     359    end = MIN(s->read_samples - s->read_index, length - total_wrote);
    357360    for (i = 0; i < end; i++) {
    358361      read_data->data[i + total_wrote] = 0;
     
    363366    }
    364367    total_wrote += end;
    365     if (total_wrote < s->hop_size) {
     368    if (total_wrote < length) {
    366369      uint_t wavread_read = 0;
    367370      aubio_source_wavread_readframe(s, &wavread_read);
     
    375378    }
    376379  }
    377   if (total_wrote < s->hop_size) {
    378     for (i = end; i < s->hop_size; i++) {
    379       read_data->data[i] = 0.;
    380     }
    381   }
     380
     381  aubio_source_pad_output (read_data, total_wrote);
     382
    382383  *read = total_wrote;
    383384}
     
    387388  uint_t end = 0;
    388389  uint_t total_wrote = 0;
     390  uint_t length = aubio_source_validate_input_length("source_wavread", s->path,
     391      s->hop_size, read_data->length);
     392  uint_t channels = aubio_source_validate_input_channels("source_wavread",
     393      s->path, s->input_channels, read_data->height);
    389394  if (s->fid == NULL) {
    390395    AUBIO_ERR("source_wavread: could not read from %s (file not opened)\n",
     
    392397    return;
    393398  }
    394   while (total_wrote < s->hop_size) {
    395     end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
    396     for (j = 0; j < read_data->height; j++) {
     399  while (total_wrote < length) {
     400    end = MIN(s->read_samples - s->read_index, length - total_wrote);
     401    for (j = 0; j < channels; j++) {
    397402      for (i = 0; i < end; i++) {
    398403        read_data->data[j][i + total_wrote] = s->output->data[j][i];
     
    400405    }
    401406    total_wrote += end;
    402     if (total_wrote < s->hop_size) {
     407    if (total_wrote < length) {
    403408      uint_t wavread_read = 0;
    404409      aubio_source_wavread_readframe(s, &wavread_read);
     
    412417    }
    413418  }
    414   if (total_wrote < s->hop_size) {
    415     for (j = 0; j < read_data->height; j++) {
    416       for (i = end; i < s->hop_size; i++) {
    417         read_data->data[j][i] = 0.;
    418       }
    419     }
    420   }
     419
     420  aubio_source_pad_multi_output(read_data, s->input_channels, total_wrote);
     421
    421422  *read = total_wrote;
    422423}
  • tests/src/io/base-source_custom.h

    r9630fa8 re2f1e6d  
    9494  if (read != hop_size) return 1;
    9595
     96  // read again in undersized vector
     97  del_fvec(vec);
     98  vec = new_fvec(hop_size - 1);
     99  aubio_source_custom_do(s, vec, &read);
     100  if (read != hop_size - 1) return 1;
     101
     102  // read again in oversized vector
     103  del_fvec(vec);
     104  vec = new_fvec(hop_size + 1);
     105  aubio_source_custom_do(s, vec, &read);
     106  if (read != hop_size) return 1;
     107
    96108  // seek to 0
    97109  if(aubio_source_custom_seek(s, 0)) return 1;
    98110
    99111  // read again as multiple channels
     112  aubio_source_custom_do_multi(s, mat, &read);
     113  if (read != hop_size) return 1;
     114
     115  // read again as multiple channels in an undersized matrix
     116  del_fmat(mat);
     117  mat = new_fmat(channels - 1, hop_size);
     118  aubio_source_custom_do_multi(s, mat, &read);
     119  if (read != hop_size) return 1;
     120
     121  // read again as multiple channels in an undersized matrix
     122  del_fmat(mat);
     123  mat = new_fmat(channels, hop_size - 1);
     124  aubio_source_custom_do_multi(s, mat, &read);
     125  if (read != hop_size - 1) return 1;
     126
     127  // read again as multiple channels in an oversized matrix
     128  del_fmat(mat);
     129  mat = new_fmat(channels + 1, hop_size);
     130  aubio_source_custom_do_multi(s, mat, &read);
     131  if (read != hop_size) return 1;
     132
     133  // read again as multiple channels in an oversized matrix
     134  del_fmat(mat);
     135  mat = new_fmat(channels, hop_size + 1);
    100136  aubio_source_custom_do_multi(s, mat, &read);
    101137  if (read != hop_size) return 1;
  • tests/src/io/test-source.c

    r9630fa8 re2f1e6d  
    9090  if (read != hop_size) return 1;
    9191
     92  // read again in undersized vector
     93  del_fvec(vec);
     94  vec = new_fvec(hop_size - 1);
     95  aubio_source_do(s, vec, &read);
     96  if (read != hop_size - 1) return 1;
     97
     98  // read again in oversized vector
     99  del_fvec(vec);
     100  vec = new_fvec(hop_size + 1);
     101  aubio_source_do(s, vec, &read);
     102  if (read != hop_size) return 1;
     103
    92104  // seek to 0
    93105  if(aubio_source_seek(s, 0)) return 1;
    94106
    95107  // read again as multiple channels
     108  aubio_source_do_multi(s, mat, &read);
     109  if (read != hop_size) return 1;
     110
     111  // read again as multiple channels in an undersized matrix
     112  del_fmat(mat);
     113  mat = new_fmat(channels - 1, hop_size);
     114  aubio_source_do_multi(s, mat, &read);
     115  if (read != hop_size) return 1;
     116
     117  // read again as multiple channels in an undersized matrix
     118  del_fmat(mat);
     119  mat = new_fmat(channels, hop_size - 1);
     120  aubio_source_do_multi(s, mat, &read);
     121  if (read != hop_size - 1) return 1;
     122
     123  // read again as multiple channels in an oversized matrix
     124  del_fmat(mat);
     125  mat = new_fmat(channels + 1, hop_size);
     126  aubio_source_do_multi(s, mat, &read);
     127  if (read != hop_size) return 1;
     128
     129  // read again as multiple channels in an oversized matrix
     130  del_fmat(mat);
     131  mat = new_fmat(channels, hop_size + 1);
    96132  aubio_source_do_multi(s, mat, &read);
    97133  if (read != hop_size) return 1;
Note: See TracChangeset for help on using the changeset viewer.