Changeset 439ba7b


Ignore:
Timestamp:
Apr 1, 2019, 1:30:06 AM (6 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/cnn, feature/crepe, feature/pitchshift, feature/timestretch, fix/ffmpeg5, master
Children:
7a02ce9
Parents:
5f57ea9 (diff), f55630c (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 'master' into feature/pitchshift

Files:
1 added
1 deleted
38 edited

Legend:

Unmodified
Added
Removed
  • .travis.yml

    r5f57ea9 r439ba7b  
    33matrix:
    44  include:
    5     - python: 3.5
    6       os: linux
    7       compiler: gcc
    8     - python: 3.4
    9       os: linux
    10       compiler: gcc
    11     - python: 2.7
     5    - python: 3.6
    126      os: linux
    137      compiler: gcc
     
    159      os: linux
    1610      compiler: gcc
    17       env: CFLAGS="-Os" WAFOPTS="--disable-samplerate --disable-sndfile"
    18     - python: 3.4
     11      env: WAFOPTS="--build-type=debug"
     12    - python: 2.7
     13      os: linux
     14      compiler: gcc
     15    - python: "pypy3.5"
     16      os: linux
     17      compiler: gcc
     18      env: CFLAGS="-Os" WAFOPTS="--disable-avcodec"
     19    - python: 3.6
     20      os: linux
     21      compiler: gcc
     22      env: CFLAGS="-Os" WAFOPTS="--disable-samplerate"
     23    - python: 3.5
    1924      os: linux
    2025      compiler: gcc
  • ChangeLog

    r5f57ea9 r439ba7b  
     12018-12-19 Paul Brossier <piem@aubio.org>
     2
     3        [ Overview ]
     4
     5        * VERSION: bump to 0.4.9
     6        * library: improve stability, fixing potential crashes and memory leaks on
     7        invalid arguments; improve library messages and reporting of system errors
     8        * tests/: major clean-up, check return codes, increase code coverage
     9        * python/tests/: switch to pytest (closes gh-163), check emitted warnings
     10        * python/: add pages to manual with brief descriptions of classes
     11
     12        [ Fixes ]
     13
     14        * security: improve arguments validation in new_aubio_filterbank (prevent
     15        possible null-pointer dereference on invalid n_filters, CVE-2018-19801),
     16        new_aubio-tempo (prevent possible buffer overflow, CVE-2018-19800), and
     17        new_aubio_onset (prevent null-pointer dereference, CVE-2018-19802). Thanks
     18        to Guoxiang Niu (@niugx), from the EaglEye Team for reporting these issues.
     19        * tempo: fix delay_ms methods
     20        * filterbank: fix aubio_filterbank_get_power (thanks to @romanbsd who
     21        also noticed this issue)
     22        * dct: creation fail on negative sizes or invalid accelerate radix,
     23        fix typo in error and warning messages, prevent possible memory leak
     24        * pitch: prevent null pointer dereference in yinfast, comment out unused
     25        functions in mcomb and yin, prevent possible leak in specacf
     26        * mfcc: always use dct module, strengthen input validation, change
     27        get_{scale,power} to return smpl_t
     28        * specdesc: improve error message
     29        * notes: prevent null pointer dereference
     30        * hist: add validation for size argument, prevent possible leak
     31        * awhitening: use shortest length available (closes gh-216)
     32        * io: add macros to display system errors, add helpers to validate input
     33        arguments of source and sink methods, always clean-up after failure
     34        * source: validate input sizes to prevent invalid reads
     35        * apple_audio: use native format conversions in source and sink, prevent
     36        possible apple_audio crash on empty string, get_duration returns 0 on failure
     37        * ffmpeg/avcodec: prevent deprecation warnings, read after close, and skipped
     38        samples warnings, improve warning messages, only show a warning when
     39        swr_convert failed, prevent possible memory leak when closing swr context
     40        * wavwrite: copy to all channels if needed, check fseek and fwrite return
     41        values, call fflush in open to return failure on full disk-system
     42        * source_sndfile: fix reading sizes when resampling, set error message when
     43        reading after close
     44        * aubio_priv.h: include blas first (see gh-225), add STRERROR macros
     45
     46        [ Python ]
     47
     48        * documentation: add pages to manual, add minimal docstrings for fft,
     49        digital_filter, and generated objects, improve specdesc documentation
     50        * filterbank: add get_norm/power documentation
     51        * source: take a copy of the last frame before resizing it, raise an
     52        exception when read failed, fix compilation warning
     53        * fixes: remove unneeded check convert with PyFloat_FromDouble or
     54        PyFloat_FromDouble, check if sink, digital_filter, were created before
     55        deleting
     56
     57        [ Tests ]
     58
     59        * python/tests/: switch to pytest (slightly slower than nose2 but better at
     60        capturing warnings and parametrization), improve coding style and coverage.
     61        Tests should now be run with `pytest`.
     62        * tests/: Each test program in C must now return 0, otherwise the test will
     63        fail. Examples have been modified to run themselves on a test audio file,
     64        but can still be run with arguments. Tests for `source` and `sink` have been
     65        factorised, and some code cleaning. A python script is used to create a
     66        test sound file. Tested on linux, macos, and windows, improvements to
     67        test-mfcc (closes gh-219).
     68
     69        [ Build system ]
     70
     71        * waf: upgrade to 2.0.14, check the return code of each test program,
     72        update rules to build manual and api documentation into build/, check
     73        for errno.h
     74        * osx: use -Os in scripts/build_apple_frameworks
     75        * Makefile: improve coverage reports
     76        * appveyor, travis, circleci: switch to pytest, set one travis config to use
     77        sndfile only
     78        * travis: add py3.6, drop py3.4, use py3.5 to test debug mode
     79        * azure: add basic configuration
     80
    1812018-11-21 Paul Brossier <piem@aubio.org>
    282
  • README.md

    r5f57ea9 r439ba7b  
    44[![Travis build status](https://travis-ci.org/aubio/aubio.svg?branch=master)](https://travis-ci.org/aubio/aubio "Travis build status")
    55[![Appveyor build status](https://img.shields.io/appveyor/ci/piem/aubio/master.svg)](https://ci.appveyor.com/project/piem/aubio "Appveyor build status")
    6 [![Landscape code health](https://landscape.io/github/aubio/aubio/master/landscape.svg?style=flat)](https://landscape.io/github/aubio/aubio/master "Landscape code health")
    76[![Commits since last release](https://img.shields.io/github/commits-since/aubio/aubio/latest.svg)](https://github.com/aubio/aubio "Commits since last release")
    87
  • VERSION

    r5f57ea9 r439ba7b  
    11AUBIO_MAJOR_VERSION=0
    2 AUBIO_MINOR_VERSION=4
    3 AUBIO_PATCH_VERSION=9
     2AUBIO_MINOR_VERSION=5
     3AUBIO_PATCH_VERSION=0
    44AUBIO_VERSION_STATUS='~alpha'
    55LIBAUBIO_LT_CUR=5
  • azure-pipelines.yml

    r5f57ea9 r439ba7b  
    44- job: linux
    55  pool:
    6     vmImage: 'Ubuntu 16.04'
     6    vmImage: 'ubuntu-16.04'
    77  steps:
    88  - script: |
     
    1414- job: windows
    1515  pool:
    16     vmIMage: 'VS2017-Win2016'
     16    vmImage: 'vs2017-win2016'
    1717  steps:
    1818  - script: |
     
    2525- job: macos
    2626  pool:
    27     vmIMage: macOS-10.13
     27    vmImage: 'macos-10.13'
    2828  steps:
    2929  - script: |
  • doc/statuslinks.rst

    r5f57ea9 r439ba7b  
    1010   :alt: Appveyor build status
    1111
    12 .. image:: https://landscape.io/github/aubio/aubio/master/landscape.svg?style=flat
    13    :target: https://landscape.io/github/aubio/aubio/master
    14    :alt: Landscape code health
    15 
    1612.. image:: https://readthedocs.org/projects/aubio/badge/?version=latest
    1713   :target: https://aubio.readthedocs.io/en/latest/?badge=latest
  • examples/utils.c

    r5f57ea9 r439ba7b  
    185185
    186186    del_aubio_source (this_source);
    187     del_aubio_sink   (this_sink);
     187    if (this_sink)
     188      del_aubio_sink   (this_sink);
    188189
    189190  }
  • python/demos/demo_wav2midi.py

    r5f57ea9 r439ba7b  
    6464        if new_note[2] > 0:
    6565            track.append(Message('note_off', note=int(new_note[2]),
    66                 velocity=127, time=0)
     66                velocity=127, time=delta)
    6767                )
    6868        track.append(Message('note_on',
  • python/ext/py-filter.c

    r5f57ea9 r439ba7b  
    110110{
    111111  Py_XDECREF(self->out);
    112   del_aubio_filter (self->o);
     112  if (self->o)
     113    del_aubio_filter (self->o);
    113114  Py_TYPE(self)->tp_free ((PyObject *) self);
    114115}
  • python/ext/py-sink.c

    r5f57ea9 r439ba7b  
    151151Py_sink_del (Py_sink *self, PyObject *unused)
    152152{
    153   del_aubio_sink(self->o);
    154   free(self->mwrite_data.data);
     153  if (self->o) {
     154    del_aubio_sink(self->o);
     155    free(self->mwrite_data.data);
     156  }
    155157  if (self->uri) {
    156158    free(self->uri);
  • python/ext/py-source.c

    r5f57ea9 r439ba7b  
    437437  aubio_source_do (self->o, &(self->c_read_to), &read);
    438438
     439  if (PyErr_Occurred() != NULL) {
     440    return NULL;
     441  }
     442
    439443  outputs = PyTuple_New(2);
    440444  PyTuple_SetItem( outputs, 0, self->read_to );
     
    457461  /* compute _do function */
    458462  aubio_source_do_multi (self->o, &(self->c_mread_to), &read);
     463
     464  if (PyErr_Occurred() != NULL) {
     465    return NULL;
     466  }
    459467
    460468  outputs = PyTuple_New(2);
     
    574582    } else if (PyLong_AsLong(size) > 0) {
    575583      // short read, return a shorter array
    576       PyArrayObject *shortread = (PyArrayObject*)PyTuple_GetItem(done, 0);
     584      PyObject *vec = PyTuple_GetItem(done, 0);
     585      // take a copy to prevent resizing internal arrays
     586      PyArrayObject *shortread = (PyArrayObject*)PyArray_FROM_OTF(vec,
     587          NPY_NOTYPE, NPY_ARRAY_ENSURECOPY);
    577588      PyArray_Dims newdims;
    578589      PyObject *reshaped;
     
    587598      reshaped = PyArray_Newshape(shortread, &newdims, NPY_CORDER);
    588599      Py_DECREF(shortread);
     600      Py_DECREF(vec);
    589601      return reshaped;
    590602    } else {
  • python/lib/moresetuptools.py

    r5f57ea9 r439ba7b  
    6969    for define_macro in ['HAVE_STDLIB_H', 'HAVE_STDIO_H',
    7070                         'HAVE_MATH_H', 'HAVE_STRING_H',
    71                          'HAVE_C99_VARARGS_MACROS',
     71                         'HAVE_ERRNO_H', 'HAVE_C99_VARARGS_MACROS',
    7272                         'HAVE_LIMITS_H', 'HAVE_STDARG_H',
    7373                         'HAVE_MEMCPY_HACKS']:
  • python/tests/test_sink.py

    r5f57ea9 r439ba7b  
    44from aubio import fvec, source, sink
    55from utils import list_all_sounds, get_tmp_sink_path, del_tmp_sink_path
    6 from _tools import parametrize, skipTest, assert_raises
     6from utils import parse_file_samplerate
     7from _tools import parametrize, skipTest, assert_raises, assert_warns
    78
    89list_of_sounds = list_all_sounds('sounds')
     
    6162    @parametrize('hop_size, samplerate, path', all_params)
    6263    def test_read_and_write(self, hop_size, samplerate, path):
     64        orig_samplerate = parse_file_samplerate(soundfile)
    6365        try:
    64             f = source(path, samplerate, hop_size)
     66            if orig_samplerate is not None and orig_samplerate < samplerate:
     67                # upsampling should emit a warning
     68                with assert_warns(UserWarning):
     69                    f = source(soundfile, samplerate, hop_size)
     70            else:
     71                f = source(soundfile, samplerate, hop_size)
    6572        except RuntimeError as e:
    6673            err_msg = '{:s} (hop_s = {:d}, samplerate = {:d})'
     
    7986    @parametrize('hop_size, samplerate, path', all_params)
    8087    def test_read_and_write_multi(self, hop_size, samplerate, path):
     88        orig_samplerate = parse_file_samplerate(soundfile)
    8189        try:
    82             f = source(path, samplerate, hop_size)
     90            if orig_samplerate is not None and orig_samplerate < samplerate:
     91                # upsampling should emit a warning
     92                with assert_warns(UserWarning):
     93                    f = source(soundfile, samplerate, hop_size)
     94            else:
     95                f = source(soundfile, samplerate, hop_size)
    8396        except RuntimeError as e:
    8497            err_msg = '{:s} (hop_s = {:d}, samplerate = {:d})'
  • python/tests/test_source.py

    r5f57ea9 r439ba7b  
    44from numpy.testing import TestCase, assert_equal
    55from aubio import source
    6 from utils import list_all_sounds
     6from utils import list_all_sounds, parse_file_samplerate
    77import unittest
    8 from _tools import parametrize, assert_raises, assert_equal, skipTest
     8from _tools import assert_raises, assert_equal, assert_warns
     9from _tools import parametrize, skipTest
    910
    1011list_of_sounds = list_all_sounds('sounds')
     
    2425_debug = False
    2526
    26 class Test_aubio_source_test_case(object):
    27 
    28     @parametrize('filename', list_of_sounds)
    29     def test_close_file(self, filename):
     27
     28class Test_aubio_source_test_case(TestCase):
     29
     30    def setUp(self):
     31        if not default_test_sound:
     32            skipTest(no_sounds_msg)
     33
     34    def test_close_file(self):
    3035        samplerate = 0 # use native samplerate
    3136        hop_size = 256
    32         f = source(filename, samplerate, hop_size)
    33         f.close()
    34 
    35     @parametrize('filename', list_of_sounds)
    36     def test_close_file_twice(self, filename):
     37        f = source(default_test_sound, samplerate, hop_size)
     38        f.close()
     39
     40    def test_close_file_twice(self):
    3741        samplerate = 0 # use native samplerate
    3842        hop_size = 256
    39         f = source(filename, samplerate, hop_size)
    40         f.close()
    41         f.close()
     43        f = source(default_test_sound, samplerate, hop_size)
     44        f.close()
     45        f.close()
     46
     47    def test_read_after_close(self):
     48        samplerate = 0 # use native samplerate
     49        hop_size = 256
     50        f = source(default_test_sound, samplerate, hop_size)
     51        read, frames = f()
     52        f.close()
     53        with assert_raises(RuntimeError):
     54            read, frames = f()
     55        with assert_raises(RuntimeError):
     56            read, frames = f.do_multi()
     57
    4258
    4359class Test_aubio_source_read(object):
     
    6177    @parametrize('hop_size, samplerate, soundfile', all_params)
    6278    def test_samplerate_hopsize(self, hop_size, samplerate, soundfile):
     79        orig_samplerate = parse_file_samplerate(soundfile)
    6380        try:
    64             f = source(soundfile, samplerate, hop_size)
     81            if orig_samplerate is not None and orig_samplerate < samplerate:
     82                # upsampling should emit a warning
     83                with assert_warns(UserWarning):
     84                    f = source(soundfile, samplerate, hop_size)
     85            else:
     86                f = source(soundfile, samplerate, hop_size)
    6587        except RuntimeError as e:
    6688            err_msg = 'failed opening with hop_s={:d}, samplerate={:d} ({:s})'
  • python/tests/utils.py

    r5f57ea9 r439ba7b  
    22
    33import os
     4import re
    45import glob
    56import numpy as np
     
    7879                    total_files += 1
    7980    return total_files
     81
     82def parse_file_samplerate(soundfile):
     83    samplerate = None
     84    # parse samplerate
     85    re_sr = re.compile(r'/([0-9]{4,})Hz_.*')
     86    match_samplerate = re_sr.findall(soundfile)
     87    if match_samplerate:
     88        samplerate = int(match_samplerate[0])
     89    else:
     90        import warnings
     91        warnings.warn(UserWarning("could not parse samplerate for {:s}"
     92            .format(soundfile)))
     93    return samplerate
  • scripts/build_apple_frameworks

    r5f57ea9 r439ba7b  
    1414#VERSION+=+$(git log --pretty=format:"%h" -1)
    1515
    16 CFLAGS="-Werror -Ofast"
     16CFLAGS="-Werror -Os"
    1717WAFCONF="--disable-sndfile --disable-avcodec --disable-samplerate --enable-fat" # --disable-memcpy --disable-accelerate"
    1818
  • scripts/get_waf.sh

    r5f57ea9 r439ba7b  
    44#set -x
    55
    6 WAFVERSION=2.0.13
     6WAFVERSION=2.0.14
    77WAFTARBALL=waf-$WAFVERSION.tar.bz2
    88WAFURL=https://waf.io/$WAFTARBALL
  • src/aubio_priv.h

    r5f57ea9 r439ba7b  
    6363#endif
    6464
     65#ifdef HAVE_ERRNO_H
     66#include <errno.h>
     67#endif
     68
    6569#ifdef HAVE_LIMITS_H
    6670#include <limits.h> // for CHAR_BIT, in C99 standard
     
    7175#endif
    7276
    73 #if defined(HAVE_ACCELERATE)
    74 #define HAVE_ATLAS 1
    75 #define HAVE_BLAS 1
    76 #include <Accelerate/Accelerate.h>
    77 #elif defined(HAVE_ATLAS_CBLAS_H)
    78 #elif defined(HAVE_BLAS)
     77#if defined(HAVE_BLAS) // --enable-blas=true
     78// check which cblas header we found
    7979#if defined(HAVE_ATLAS_CBLAS_H)
    8080#define HAVE_ATLAS 1
     
    8484#elif defined(HAVE_CBLAS_H)
    8585#include <cblas.h>
    86 #endif
    87 #endif
    88 
    89 #ifdef HAVE_ACCELERATE
     86#elif !defined(HAVE_ACCELERATE)
     87#error "HAVE_BLAS was defined, but no blas header was found"
     88#endif /* end of cblas includes */
     89#endif
     90
     91#if defined(HAVE_ACCELERATE)
     92// include accelerate framework after blas
     93#define HAVE_ATLAS 1
     94#define HAVE_BLAS 1
    9095#include <Accelerate/Accelerate.h>
     96
    9197#ifndef HAVE_AUBIO_DOUBLE
    9298#define aubio_vDSP_mmov       vDSP_mmov
     
    325331#endif
    326332
     333#if !defined(_MSC_VER)
     334#define AUBIO_STRERROR(errno,buf,len) strerror_r(errno, buf, len)
     335#else
     336#define AUBIO_STRERROR(errno,buf,len) strerror_s(buf, len, errno)
     337#endif
     338
     339#ifdef HAVE_C99_VARARGS_MACROS
     340#define AUBIO_STRERR(...)            \
     341    char errorstr[256]; \
     342    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr)); \
     343    AUBIO_ERR(__VA_ARGS__)
     344#else
     345#define AUBIO_STRERR(format, args...)   \
     346    char errorstr[256]; \
     347    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr)); \
     348    AUBIO_ERR(format, ##args)
     349#endif
     350
    327351/* handy shortcuts */
    328352#define DB2LIN(g) (POW(10.0,(g)*0.05f))
  • src/io/ioutils.c

    r5f57ea9 r439ba7b  
    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

    r5f57ea9 r439ba7b  
    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.c

    r5f57ea9 r439ba7b  
    136136
    137137void del_aubio_sink(aubio_sink_t * s) {
    138   AUBIO_ASSERT(s);
    139   if (s->s_del && s->sink)
     138  //AUBIO_ASSERT(s);
     139  if (s && s->s_del && s->sink)
    140140    s->s_del((void *)s->sink);
    141141  AUBIO_FREE(s);
  • src/io/sink_wavwrite.c

    r5f57ea9 r439ba7b  
    2828#include "io/sink_wavwrite.h"
    2929#include "io/ioutils.h"
    30 
    31 #include <errno.h>
    3230
    3331#define MAX_SIZE 4096
     
    163161  unsigned char buf[5];
    164162  uint_t byterate, blockalign;
     163  size_t written = 0;
    165164
    166165  /* open output file */
    167166  s->fid = fopen((const char *)s->path, "wb");
    168167  if (!s->fid) {
    169     AUBIO_ERR("sink_wavwrite: could not open %s (%s)\n", s->path, strerror(errno));
     168    AUBIO_STRERR("sink_wavwrite: could not open %s (%s)\n", s->path, errorstr);
    170169    goto beach;
    171170  }
    172171
    173172  // ChunkID
    174   fwrite("RIFF", 4, 1, s->fid);
     173  written += fwrite("RIFF", 4, 1, s->fid);
    175174
    176175  // ChunkSize (0 for now, actual size will be written in _close)
    177   fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
     176  written += fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
    178177
    179178  // Format
    180   fwrite("WAVE", 4, 1, s->fid);
     179  written += fwrite("WAVE", 4, 1, s->fid);
    181180
    182181  // Subchunk1ID
    183   fwrite("fmt ", 4, 1, s->fid);
     182  written += fwrite("fmt ", 4, 1, s->fid);
    184183
    185184  // Subchunk1Size
    186   fwrite(write_little_endian(16, buf, 4), 4, 1, s->fid);
     185  written += fwrite(write_little_endian(16, buf, 4), 4, 1, s->fid);
    187186
    188187  // AudioFormat
    189   fwrite(write_little_endian(1, buf, 2), 2, 1, s->fid);
     188  written += fwrite(write_little_endian(1, buf, 2), 2, 1, s->fid);
    190189
    191190  // NumChannels
    192   fwrite(write_little_endian(s->channels, buf, 2), 2, 1, s->fid);
     191  written += fwrite(write_little_endian(s->channels, buf, 2), 2, 1, s->fid);
    193192
    194193  // SampleRate
    195   fwrite(write_little_endian(s->samplerate, buf, 4), 4, 1, s->fid);
     194  written += fwrite(write_little_endian(s->samplerate, buf, 4), 4, 1, s->fid);
    196195
    197196  // ByteRate
    198197  byterate = s->samplerate * s->channels * s->bitspersample / 8;
    199   fwrite(write_little_endian(byterate, buf, 4), 4, 1, s->fid);
     198  written += fwrite(write_little_endian(byterate, buf, 4), 4, 1, s->fid);
    200199
    201200  // BlockAlign
    202201  blockalign = s->channels * s->bitspersample / 8;
    203   fwrite(write_little_endian(blockalign, buf, 2), 2, 1, s->fid);
     202  written += fwrite(write_little_endian(blockalign, buf, 2), 2, 1, s->fid);
    204203
    205204  // BitsPerSample
    206   fwrite(write_little_endian(s->bitspersample, buf, 2), 2, 1, s->fid);
     205  written += fwrite(write_little_endian(s->bitspersample, buf, 2), 2, 1, s->fid);
    207206
    208207  // Subchunk2ID
    209   fwrite("data", 4, 1, s->fid);
     208  written += fwrite("data", 4, 1, s->fid);
    210209
    211210  // Subchunk1Size (0 for now, actual size will be written in _close)
    212   fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
     211  written += fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
     212
     213  // fwrite(*, *, 1, s->fid) was called 13 times, check success
     214  if (written != 13 || fflush(s->fid)) {
     215    AUBIO_STRERR("sink_wavwrite: writing header to %s failed"
     216        " (wrote %d/%d, %s)\n", s->path, written, 13, errorstr);
     217    fclose(s->fid);
     218    s->fid = NULL;
     219    return AUBIO_FAIL;
     220  }
    213221
    214222  s->scratch_size = s->max_size * s->channels;
     
    227235}
    228236
     237static
     238void aubio_sink_wavwrite_write_frames(aubio_sink_wavwrite_t *s, uint_t write)
     239{
     240  uint_t written_frames = 0;
     241
     242  written_frames = fwrite(s->scratch_data, 2 * s->channels, write, s->fid);
     243
     244  if (written_frames != write) {
     245    AUBIO_STRERR("sink_wavwrite: trying to write %d frames to %s, but only %d"
     246        " could be written (%s)\n", write, s->path, written_frames, errorstr);
     247  }
     248  s->total_frames_written += written_frames;
     249}
    229250
    230251void 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;
     252  uint_t c = 0, i = 0;
    232253  uint_t length = aubio_sink_validate_input_length("sink_wavwrite", s->path,
    233254      s->max_size, write_data->length, write);
     
    238259    }
    239260  }
    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;
     261
     262  aubio_sink_wavwrite_write_frames(s, length);
    248263}
    249264
    250265void 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;
     266  uint_t c = 0, i = 0;
    252267
    253268  uint_t channels = aubio_sink_validate_input_channels("sink_wavwrite", s->path,
     
    261276    }
    262277  }
    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;
     278
     279  aubio_sink_wavwrite_write_frames(s, length);
    271280}
    272281
     
    274283  uint_t data_size = s->total_frames_written * s->bitspersample * s->channels / 8;
    275284  unsigned char buf[5];
     285  size_t written = 0, err = 0;
    276286  if (!s->fid) return AUBIO_FAIL;
    277287  // ChunkSize
    278   fseek(s->fid, 4, SEEK_SET);
    279   fwrite(write_little_endian(data_size + 36, buf, 4), 4, 1, s->fid);
     288  err += fseek(s->fid, 4, SEEK_SET);
     289  written += fwrite(write_little_endian(data_size + 36, buf, 4), 4, 1, s->fid);
    280290  // Subchunk2Size
    281   fseek(s->fid, 40, SEEK_SET);
    282   fwrite(write_little_endian(data_size, buf, 4), 4, 1, s->fid);
     291  err += fseek(s->fid, 40, SEEK_SET);
     292  written += fwrite(write_little_endian(data_size, buf, 4), 4, 1, s->fid);
     293  if (written != 2 || err != 0) {
     294    AUBIO_STRERR("sink_wavwrite: updating header of %s failed, expected %d"
     295        " write but got only %d (%s)\n", s->path, 2, written, errorstr);
     296  }
    283297  // close file
    284298  if (fclose(s->fid)) {
    285     AUBIO_ERR("sink_wavwrite: Error closing file %s (%s)\n", s->path, strerror(errno));
     299    AUBIO_STRERR("sink_wavwrite: Error closing file %s (%s)\n", s->path, errorstr);
    286300  }
    287301  s->fid = NULL;
  • src/io/source.c

    r5f57ea9 r439ba7b  
    139139
    140140void del_aubio_source(aubio_source_t * s) {
    141   AUBIO_ASSERT(s);
    142   if (s->s_del && s->source)
     141  //AUBIO_ASSERT(s);
     142  if (s && s->s_del && s->source)
    143143    s->s_del((void *)s->source);
    144144  AUBIO_FREE(s);
  • src/io/source_apple_audio.c

    r5f57ea9 r439ba7b  
    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
     
    355345        "error in ExtAudioFileGetProperty (%s)\n", s->path,
    356346        getPrintableOSStatusError(errorstr, err));
    357     return err;
     347    return 0;
    358348  }
    359349  return (uint_t)fileLengthFrames;
  • src/io/source_avcodec.c

    r5f57ea9 r439ba7b  
    3131#endif
    3232#include <libavutil/opt.h>
    33 #include <stdlib.h>
    3433
    3534// determine whether we use libavformat from ffmpeg or from libav
     
    6160#include "fvec.h"
    6261#include "fmat.h"
     62#include "ioutils.h"
    6363#include "source_avcodec.h"
    6464
     
    120120    uint_t samplerate, uint_t hop_size) {
    121121  aubio_source_avcodec_t * s = AUBIO_NEW(aubio_source_avcodec_t);
    122   AVFormatContext *avFormatCtx = s->avFormatCtx;
    123   AVCodecContext *avCodecCtx = s->avCodecCtx;
    124   AVFrame *avFrame = s->avFrame;
     122  AVFormatContext *avFormatCtx = NULL;
     123  AVCodecContext *avCodecCtx = NULL;
     124  AVFrame *avFrame = NULL;
    125125  sint_t selected_stream = -1;
    126126#if FF_API_LAVF_AVCTX
     
    464464      (const uint8_t **)avFrame->data, in_samples);
    465465#endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
    466   if (out_samples <= 0) {
    467     AUBIO_WRN("source_avcodec: no sample found while converting frame (%s)\n",
    468         s->path);
     466  if (out_samples < 0) {
     467    AUBIO_WRN("source_avcodec: error while resampling %s (%d)\n",
     468        s->path, out_samples);
    469469    goto beach;
    470470  }
     
    473473
    474474beach:
    475   s->avFormatCtx = avFormatCtx;
    476   s->avCodecCtx = avCodecCtx;
    477   s->avFrame = avFrame;
    478 #if defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)
    479   s->avr = avr;
    480 #endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
    481   s->output = output;
    482 
    483475  av_packet_unref(&avPacket);
    484476}
     
    489481  uint_t end = 0;
    490482  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);
     483  uint_t length = aubio_source_validate_input_length("source_avcodec", s->path,
     484      s->hop_size, read_data->length);
     485  if (!s->avr || !s->avFormatCtx || !s->avCodecCtx) {
     486    AUBIO_ERR("source_avcodec: could not read from %s (file was closed)\n",
     487        s->path);
     488    *read= 0;
     489    return;
     490  }
     491  while (total_wrote < length) {
     492    end = MIN(s->read_samples - s->read_index, length - total_wrote);
    493493    for (i = 0; i < end; i++) {
    494494      read_data->data[i + total_wrote] = 0.;
     
    500500    }
    501501    total_wrote += end;
    502     if (total_wrote < s->hop_size) {
     502    if (total_wrote < length) {
    503503      uint_t avcodec_read = 0;
    504504      aubio_source_avcodec_readframe(s, &avcodec_read);
     
    512512    }
    513513  }
    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   }
     514
     515  aubio_source_pad_output(read_data, total_wrote);
     516
    519517  *read = total_wrote;
    520518}
     
    525523  uint_t end = 0;
    526524  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++) {
     525  uint_t length = aubio_source_validate_input_length("source_avcodec", s->path,
     526      s->hop_size, read_data->length);
     527  uint_t channels = aubio_source_validate_input_channels("source_avcodec",
     528      s->path, s->input_channels, read_data->height);
     529  if (!s->avr || !s->avFormatCtx || !s->avCodecCtx) {
     530    AUBIO_ERR("source_avcodec: could not read from %s (file was closed)\n",
     531        s->path);
     532    *read= 0;
     533    return;
     534  }
     535  while (total_wrote < length) {
     536    end = MIN(s->read_samples - s->read_index, length - total_wrote);
     537    for (j = 0; j < channels; j++) {
    530538      for (i = 0; i < end; i++) {
    531539        read_data->data[j][i + total_wrote] =
     
    534542    }
    535543    total_wrote += end;
    536     if (total_wrote < s->hop_size) {
     544    if (total_wrote < length) {
    537545      uint_t avcodec_read = 0;
    538546      aubio_source_avcodec_readframe(s, &avcodec_read);
     
    546554    }
    547555  }
    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   }
     556
     557  aubio_source_pad_multi_output(read_data, s->input_channels, total_wrote);
     558
    555559  *read = total_wrote;
    556560}
     
    616620#ifdef HAVE_AVRESAMPLE
    617621    avresample_close( s->avr );
     622    av_free ( s->avr );
    618623#elif defined(HAVE_SWRESAMPLE)
    619624    swr_close ( s->avr );
    620 #endif
    621     av_free ( s->avr );
     625    swr_free ( &s->avr );
     626#endif
    622627  }
    623628  s->avr = NULL;
  • src/io/source_sndfile.c

    r5f57ea9 r439ba7b  
    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->scratch_size);
     177  uint_t read_length = read_samples / s->input_channels;
    173178
    174179  /* where to store de-interleaved data */
    175180  smpl_t *ptr_data;
     181
     182  if (!s->handle) {
     183    AUBIO_ERR("source_sndfile: could not read from %s (file was closed)\n",
     184        s->path);
     185    *read = 0;
     186    return;
     187  }
     188
    176189#ifdef HAVE_SAMPLERATE
    177190  if (s->ratio != 1) {
     
    180193#endif /* HAVE_SAMPLERATE */
    181194  {
     195    read_length = MIN(length, read_length);
    182196    ptr_data = read_data->data;
    183197  }
    184198
    185199  /* de-interleaving and down-mixing data  */
    186   for (j = 0; j < read_samples / input_channels; j++) {
     200  for (j = 0; j < read_length; j++) {
    187201    ptr_data[j] = 0;
    188202    for (i = 0; i < input_channels; i++) {
     
    198212#endif /* HAVE_SAMPLERATE */
    199213
    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   }
     214  *read = MIN(length, (uint_t)FLOOR(s->ratio * read_length + .5));
     215
     216  aubio_source_pad_output (read_data, *read);
    207217
    208218}
     
    211221  uint_t i,j, input_channels = s->input_channels;
    212222  /* do actual reading */
    213   sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data, s->scratch_size);
     223  uint_t length = aubio_source_validate_input_length("source_sndfile", s->path,
     224      s->hop_size, read_data->length);
     225  uint_t channels = aubio_source_validate_input_channels("source_sndfile",
     226      s->path, s->input_channels, read_data->height);
     227  sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data,
     228      s->scratch_size);
     229  uint_t read_length = read_samples / s->input_channels;
    214230
    215231  /* where to store de-interleaved data */
    216232  smpl_t **ptr_data;
     233
     234  if (!s->handle) {
     235    AUBIO_ERR("source_sndfile: could not read from %s (file was closed)\n",
     236        s->path);
     237    *read = 0;
     238    return;
     239  }
     240
    217241#ifdef HAVE_SAMPLERATE
    218242  if (s->ratio != 1) {
     
    221245#endif /* HAVE_SAMPLERATE */
    222246  {
     247    read_length = MIN(read_length, length);
    223248    ptr_data = read_data->data;
    224249  }
    225250
    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       }
     251  for (j = 0; j < read_length; j++) {
     252    for (i = 0; i < channels; i++) {
     253      ptr_data[i][j] = s->scratch_data[j * input_channels + i];
    251254    }
    252255  }
     
    265268#endif /* HAVE_SAMPLERATE */
    266269
    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 
     270  *read = MIN(length, (uint_t)FLOOR(s->ratio * read_length + .5));
     271
     272  aubio_source_pad_multi_output(read_data, input_channels, *read);
    277273}
    278274
  • src/io/source_wavread.c

    r5f57ea9 r439ba7b  
    2525#include "fvec.h"
    2626#include "fmat.h"
     27#include "ioutils.h"
    2728#include "source_wavread.h"
    2829
    29 #include <errno.h>
    30 
    3130#define AUBIO_WAVREAD_BUFSIZE 1024
    3231
    33 #define SHORT_TO_FLOAT(x) (smpl_t)(x * 3.0517578125e-05)
     32//#define SHORT_TO_FLOAT(x) (smpl_t)(x * 3.0517578125e-05)
    3433
    3534struct _aubio_source_wavread_t {
     
    10099  s->fid = fopen((const char *)path, "rb");
    101100  if (!s->fid) {
    102     AUBIO_ERR("source_wavread: Failed opening %s (System error: %s)\n", s->path, strerror(errno));
     101    AUBIO_STRERR("source_wavread: Failed opening %s (%s)\n", s->path, errorstr);
    103102    goto beach;
    104103  }
     
    133132    bytes_junk += read_little_endian(buf, 4);
    134133    if (fseek(s->fid, bytes_read + bytes_junk, SEEK_SET) != 0) {
    135       AUBIO_ERR("source_wavread: Failed opening %s (could not seek past JUNK Chunk: %s)\n",
    136           s->path, strerror(errno));
     134      AUBIO_STRERR("source_wavread: Failed opening %s (could not seek past JUNK Chunk: %s)\n",
     135          s->path, errorstr);
    137136      goto beach;
    138137    }
     
    261260    bytes_junk += read_little_endian(buf, 4);
    262261    if (fseek(s->fid, bytes_read + bytes_junk, SEEK_SET) != 0) {
    263       AUBIO_ERR("source_wavread: could not seek past unknown chunk in %s (%s)\n",
    264           s->path, strerror(errno));
     262      AUBIO_STRERR("source_wavread: could not seek past unknown chunk in %s (%s)\n",
     263          s->path, errorstr);
    265264      goto beach;
    266265    }
     
    348347  uint_t end = 0;
    349348  uint_t total_wrote = 0;
     349  uint_t length = aubio_source_validate_input_length("source_wavread", s->path,
     350      s->hop_size, read_data->length);
    350351  if (s->fid == NULL) {
    351352    AUBIO_ERR("source_wavread: could not read from %s (file not opened)\n",
     
    353354    return;
    354355  }
    355   while (total_wrote < s->hop_size) {
    356     end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
     356  while (total_wrote < length) {
     357    end = MIN(s->read_samples - s->read_index, length - total_wrote);
    357358    for (i = 0; i < end; i++) {
    358359      read_data->data[i + total_wrote] = 0;
     
    363364    }
    364365    total_wrote += end;
    365     if (total_wrote < s->hop_size) {
     366    if (total_wrote < length) {
    366367      uint_t wavread_read = 0;
    367368      aubio_source_wavread_readframe(s, &wavread_read);
     
    375376    }
    376377  }
    377   if (total_wrote < s->hop_size) {
    378     for (i = end; i < s->hop_size; i++) {
    379       read_data->data[i] = 0.;
    380     }
    381   }
     378
     379  aubio_source_pad_output (read_data, total_wrote);
     380
    382381  *read = total_wrote;
    383382}
     
    387386  uint_t end = 0;
    388387  uint_t total_wrote = 0;
     388  uint_t length = aubio_source_validate_input_length("source_wavread", s->path,
     389      s->hop_size, read_data->length);
     390  uint_t channels = aubio_source_validate_input_channels("source_wavread",
     391      s->path, s->input_channels, read_data->height);
    389392  if (s->fid == NULL) {
    390393    AUBIO_ERR("source_wavread: could not read from %s (file not opened)\n",
     
    392395    return;
    393396  }
    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++) {
     397  while (total_wrote < length) {
     398    end = MIN(s->read_samples - s->read_index, length - total_wrote);
     399    for (j = 0; j < channels; j++) {
    397400      for (i = 0; i < end; i++) {
    398401        read_data->data[j][i + total_wrote] = s->output->data[j][i];
     
    400403    }
    401404    total_wrote += end;
    402     if (total_wrote < s->hop_size) {
     405    if (total_wrote < length) {
    403406      uint_t wavread_read = 0;
    404407      aubio_source_wavread_readframe(s, &wavread_read);
     
    412415    }
    413416  }
    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   }
     417
     418  aubio_source_pad_multi_output(read_data, s->input_channels, total_wrote);
     419
    421420  *read = total_wrote;
    422421}
     
    442441  ret = fseek(s->fid, s->seek_start + pos * s->blockalign, SEEK_SET);
    443442  if (ret != 0) {
    444     AUBIO_ERR("source_wavread: could not seek %s at %d (%s)\n", s->path, pos, strerror(errno));
     443    AUBIO_STRERR("source_wavread: could not seek %s at %d (%s)\n", s->path, pos, errorstr);
    445444    return AUBIO_FAIL;
    446445  }
     
    463462  }
    464463  if (fclose(s->fid)) {
    465     AUBIO_ERR("source_wavread: could not close %s (%s)\n", s->path, strerror(errno));
     464    AUBIO_STRERR("source_wavread: could not close %s (%s)\n", s->path, errorstr);
    466465    return AUBIO_FAIL;
    467466  }
  • tests/src/io/base-sink_custom.h

    r5f57ea9 r439ba7b  
    152152  close_temp_sink(sink_path, fd);
    153153
     154  // shouldn't crash on null (bypassed, only check del_aubio_sink)
     155  // del_aubio_sink_custom(NULL);
     156
    154157  return run_on_default_source_and_sink(base_main);
    155158}
  • tests/src/io/base-source_custom.h

    r5f57ea9 r439ba7b  
    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;
     
    106142  aubio_source_custom_close(s);
    107143
     144  // reading after close fails
     145  del_fvec(vec);
     146  vec = new_fvec(hop_size);
     147  aubio_source_custom_do(s, vec, &read);
     148  del_fmat(mat);
     149  mat = new_fmat(channels, hop_size);
     150  aubio_source_custom_do_multi(s, mat, &read);
     151
    108152  del_aubio_source_custom(s);
    109153  del_fmat(mat);
    110154  del_fvec(vec);
     155
     156  // shouldn't crash on null (bypassed, only check del_aubio_source)
     157  // del_aubio_source_custom(NULL);
    111158
    112159  return run_on_default_source(base_main);
  • tests/src/io/test-sink.c

    r5f57ea9 r439ba7b  
    148148  close_temp_sink(sink_path, fd);
    149149
     150  // shouldn't crash on null
     151  del_aubio_sink(NULL);
     152
    150153  return run_on_default_source_and_sink(main);
    151154}
  • tests/src/io/test-source.c

    r5f57ea9 r439ba7b  
    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;
     
    102138  aubio_source_close(s);
    103139
     140  // reading after close fails
     141  del_fvec(vec);
     142  vec = new_fvec(hop_size);
     143  aubio_source_do(s, vec, &read);
     144  del_fmat(mat);
     145  mat = new_fmat(channels, hop_size);
     146  aubio_source_do_multi(s, mat, &read);
     147
    104148  del_aubio_source(s);
    105149  del_fmat(mat);
    106150  del_fvec(vec);
    107151
     152  // shouldn't crash on null
     153  del_aubio_source(NULL);
     154
    108155  return run_on_default_source(main);
    109156}
  • tests/src/spectral/test-mfcc.c

    r5f57ea9 r439ba7b  
    3434  aubio_mfcc_t *mfcc = 0;
    3535
    36   fvec_t *in = new_fvec (win_s); // input buffer
    37   cvec_t *fftgrain = new_cvec (win_s); // input buffer
    38   fvec_t *out = new_fvec (n_coeffs); // output coefficients
     36  fvec_t *in = new_fvec (hop_s);       // phase vocoder input
     37  cvec_t *fftgrain = new_cvec (win_s); // pvoc output / mfcc input
     38  fvec_t *out = new_fvec (n_coeffs);   // mfcc output
    3939
    4040  if (!in || !fftgrain || !out) { err = 1; goto failure; }
  • tests/src/test-cvec.c

    r5f57ea9 r439ba7b  
    44int main (void)
    55{
    6   uint_t i, window_size = 16; // window size
    7   cvec_t * complex_vector = new_cvec (window_size); // input buffer
    8   uint_t rand_times = 4;
     6  uint_t i, window_size = 16;
     7  cvec_t * complex_vector = new_cvec(window_size);
     8  cvec_t * other_cvector = new_cvec(window_size);
    99
    10   utils_init_random();
     10  assert(cvec_norm_get_data(complex_vector) == complex_vector->norm);
     11  assert(cvec_phas_get_data(complex_vector) == complex_vector->phas);
     12  assert(complex_vector->length == window_size / 2 + 1);
    1113
    12   while (rand_times -- ) {
    13     // fill with random phas and norm
    14     for ( i = 0; i < complex_vector->length; i++ ) {
    15       complex_vector->norm[i] = ( 2. / RAND_MAX * random() - 1. );
    16       complex_vector->phas[i] = ( 2. / RAND_MAX * random() - 1. ) * M_PI;
    17     }
    18     // print the vector
    19     cvec_print(complex_vector);
     14  // all elements are initialized to 0
     15  for ( i = 0; i < complex_vector->length; i++ ) {
     16    assert( complex_vector->norm[i] == 0. );
     17    assert( complex_vector->phas[i] == 0. );
    2018  }
    2119
    22   // set all vector elements to `0`
     20  cvec_norm_set_sample(complex_vector, 2., 1);
     21  assert(cvec_norm_get_sample(complex_vector, 1));
     22
     23  cvec_phas_set_sample(complex_vector, 2., 1);
     24  assert(cvec_phas_get_sample(complex_vector, 1));
     25
     26  cvec_print(complex_vector);
     27
     28  // set all norm and phas elements to 0
     29  cvec_zeros(complex_vector);
     30  for ( i = 0; i < complex_vector->length; i++ ) {
     31    assert( complex_vector->norm[i] == 0. );
     32    assert( complex_vector->phas[i] == 0. );
     33  }
     34
     35  // set all norm elements to 1
     36  cvec_norm_ones(complex_vector);
     37  for ( i = 0; i < complex_vector->length; i++ ) {
     38    assert( complex_vector->norm[i] == 1. );
     39  }
     40
     41  // set all norm elements to 0
    2342  cvec_norm_zeros(complex_vector);
    2443  for ( i = 0; i < complex_vector->length; i++ ) {
    2544    assert( complex_vector->norm[i] == 0. );
    26     // assert( complex_vector->phas[i] == 0 );
    2745  }
    28   cvec_print(complex_vector);
    2946
    30   // set all vector elements to `1`
    31   cvec_norm_ones(complex_vector);
     47  // set all phas elements to 1
     48  cvec_phas_ones(complex_vector);
    3249  for ( i = 0; i < complex_vector->length; i++ ) {
    33     assert( complex_vector->norm[i] == 1. );
    34     // assert( complex_vector->phas[i] == 0 );
     50    assert( complex_vector->phas[i] == 1. );
    3551  }
    36   cvec_print(complex_vector);
    3752
    38   cvec_zeros(complex_vector);
     53  // set all phas elements to 0
    3954  cvec_phas_zeros(complex_vector);
    40   cvec_norm_zeros(complex_vector);
    41   cvec_norm_ones(complex_vector);
    42   cvec_phas_ones(complex_vector);
     55  for ( i = 0; i < complex_vector->length; i++ ) {
     56    assert( complex_vector->phas[i] == 0. );
     57  }
     58
     59  cvec_copy(complex_vector, other_cvector);
     60  // copy to self
    4361  cvec_copy(complex_vector, complex_vector);
     62  // copy to a different size fails
     63  del_cvec(other_cvector);
     64  other_cvector = new_cvec(window_size + 2);
     65  cvec_copy(complex_vector, other_cvector);
    4466
    45   // destroy it
    46   del_cvec(complex_vector);
     67  if (complex_vector)
     68    del_cvec(complex_vector);
     69  if (other_cvector)
     70    del_cvec(other_cvector);
     71
     72  // wrong parameters
     73  assert(new_cvec(-1) == NULL);
     74  assert(new_cvec(0) == NULL);
     75
    4776  return 0;
    4877}
  • tests/src/test-fmat.c

    r5f57ea9 r439ba7b  
    55// and j the column.
    66
     7void assert_fmat_all_equal(fmat_t *mat, smpl_t scalar)
     8{
     9  uint_t i, j;
     10  for ( i = 0; i < mat->height; i++ ) {
     11    for ( j = 0; j < mat->length; j++ ) {
     12      assert(mat->data[i][j] == scalar);
     13    }
     14  }
     15}
     16
    717int main (void)
    818{
    9   uint_t height = 3, length = 9, i, j;
     19  uint_t i, j;
     20  uint_t height = 3, length = 9;
     21
    1022  // create fmat_t object
    11   fmat_t * mat = new_fmat (height, length);
    12   for ( i = 0; i < mat->height; i++ ) {
    13     for ( j = 0; j < mat->length; j++ ) {
     23  fmat_t * mat = new_fmat(height, length);
     24  fmat_t * other_mat = new_fmat(height, length);
     25
     26  assert(mat);
     27  assert(other_mat);
     28
     29  assert(mat->length == length);
     30  assert(mat->height == height);
     31
     32  for (i = 0; i < mat->height; i++) {
     33    for (j = 0; j < mat->length; j++) {
    1434      // all elements are already initialized to 0.
    1535      assert(mat->data[i][j] == 0);
    1636      // setting element of row i, column j
    17       mat->data[i][j] = i * 1. + j *.1;
     37      mat->data[i][j] = i * 10. + j;
    1838    }
    1939  }
     40
     41  // print out matrix
     42  fmat_print(mat);
     43
     44  // helpers
     45  fmat_rev(mat);
     46  fmat_print(mat);
     47  for (i = 0; i < mat->height; i++) {
     48    for (j = 0; j < mat->length; j++) {
     49      assert(mat->data[i][j] == i * 10. + mat->length - 1. - j);
     50    }
     51  }
     52
     53  fmat_set_sample(mat, 3, 1, 1);
     54  assert(fmat_get_sample(mat, 1, 1) == 3.);
     55
     56  fmat_ones(mat);
     57  assert_fmat_all_equal(mat, 1.);
     58
     59  fmat_set(other_mat, .5);
     60  assert_fmat_all_equal(other_mat, .5);
     61
     62  fmat_weight(mat, other_mat);
     63  assert_fmat_all_equal(mat, .5);
     64
    2065  fvec_t channel_onstack;
    2166  fvec_t *channel = &channel_onstack;
    2267  fmat_get_channel(mat, 1, channel);
    23   fvec_print (channel);
    24   // print out matrix
    25   fmat_print(mat);
    26   // destroy it
    27   del_fmat(mat);
     68  assert(channel->data == mat->data[1]);
     69
     70  // copy of the same size
     71  fmat_copy(mat, other_mat);
     72  del_fmat(other_mat);
     73
     74  // copy to undersized
     75  other_mat = new_fmat(height - 1, length);
     76  fmat_copy(mat, other_mat);
     77  del_fmat(other_mat);
     78
     79  // copy from undersized
     80  other_mat = new_fmat(height, length + 1);
     81  fmat_copy(mat, other_mat);
     82
     83  // wrong parameters
     84  assert(new_fmat(-1, length) == NULL);
     85  assert(new_fmat(height, -1) == NULL);
     86
     87  // methods for wrappers with opaque structure
     88  assert (fmat_get_channel_data(mat, 0) == mat->data[0]);
     89  assert (fmat_get_data(mat) == mat->data);
     90
     91  if (mat)
     92    del_fmat(mat);
     93  if (other_mat)
     94    del_fmat(other_mat);
    2895  return 0;
    2996}
    30 
  • tests/src/test-fvec.c

    r5f57ea9 r439ba7b  
    22#include "utils_tests.h"
    33
     4void assert_fvec_all_equal(fvec_t *vec, smpl_t scalar)
     5{
     6  uint_t i;
     7  for (i = 0; i < vec->length; i++) {
     8    assert(vec->data[i] == scalar);
     9  }
     10}
     11
    412int main (void)
    513{
    6   uint_t vec_size = 10, i;
    7   fvec_t * vec = new_fvec (vec_size);
     14  uint_t length = 10;
     15  uint_t i;
     16
     17  fvec_t * vec = new_fvec (length);
     18  fvec_t * other_vec = new_fvec (length);
     19
     20  assert (vec);
     21  assert (other_vec);
    822
    923  // vec->length matches requested size
    10   assert(vec->length == vec_size);
     24  assert(vec->length == length);
    1125
    1226  // all elements are initialized to `0.`
     
    1529  }
    1630
     31  // all elements can be set to `1.`
     32  fvec_ones(vec);
     33  assert_fvec_all_equal(vec, 1.);
     34
    1735  // all elements can be set to `0.`
    1836  fvec_zeros(vec);
    19   for ( i = 0; i < vec->length; i++ ) {
    20     assert(vec->data[i] == 0.);
    21   }
    22   fvec_print(vec);
    23 
    24   // all elements can be set to `1.`
    25   fvec_ones(vec);
    26   for ( i = 0; i < vec->length; i++ ) {
    27     assert(vec->data[i] == 1.);
    28   }
    29   fvec_print(vec);
     37  assert_fvec_all_equal(vec, 0.);
    3038
    3139  // each element can be accessed directly
     
    3644  fvec_print(vec);
    3745
     46  fvec_set_sample(vec, 3, 2);
     47  assert(fvec_get_sample(vec, 2) == 3);
     48
     49  assert(fvec_get_data(vec) == vec->data);
     50
     51  // wrong parameters
     52  assert(new_fvec(-1) == NULL);
     53
     54  // copy to an identical size works
     55  fvec_copy(vec, other_vec);
     56  del_fvec(other_vec);
     57
     58  // copy to a different size fail
     59  other_vec = new_fvec(length + 1);
     60  fvec_copy(vec, other_vec);
     61  del_fvec(other_vec);
     62
     63  // copy to a different size fail
     64  other_vec = new_fvec(length - 1);
     65  fvec_copy(vec, other_vec);
     66
    3867  // now destroys the vector
    39   del_fvec(vec);
    40 
     68  if (vec)
     69    del_fvec(vec);
     70  if (other_vec)
     71    del_fvec(other_vec);
    4172  return 0;
    4273}
    43 
  • tests/src/test-lvec.c

    r5f57ea9 r439ba7b  
    22#include "utils_tests.h"
    33
     4void assert_lvec_all_equal(lvec_t *vec, lsmp_t scalar)
     5{
     6  uint_t i;
     7  for (i = 0; i < vec->length; i++) {
     8    assert(vec->data[i] == scalar);
     9  }
     10}
     11
    412int main (void)
    513{
    6   uint_t win_s = 32; // window size
    7   lvec_t * sp = new_lvec (win_s); // input buffer
    8   lvec_set_sample (sp, 2./3., 0);
    9   PRINT_MSG(AUBIO_LSMP_FMT "\n", lvec_get_sample (sp, 0));
    10   lvec_print (sp);
    11   lvec_ones (sp);
    12   lvec_print (sp);
    13   lvec_set_all (sp, 3./5.);
    14   lvec_print (sp);
    15   del_lvec(sp);
     14  uint_t length = 32; // window size
     15
     16  lvec_t * vec = new_lvec (length); // input buffer
     17
     18  assert(vec);
     19
     20  assert(vec->length == length);
     21
     22  lvec_set_sample (vec, 3., 0);
     23  assert(lvec_get_sample(vec, 0) == 3.);
     24
     25  assert(lvec_get_data(vec) == vec->data);
     26
     27  lvec_print (vec);
     28  // note AUBIO_LSMP_FMT can be used to print lsmp_t
     29  PRINT_MSG(AUBIO_LSMP_FMT "\n", lvec_get_sample (vec, 0));
     30
     31  lvec_set_all (vec, 2.);
     32  assert_lvec_all_equal(vec, 2.);
     33
     34  lvec_ones (vec);
     35  assert_lvec_all_equal(vec, 1.);
     36
     37  lvec_zeros (vec);
     38  assert_lvec_all_equal(vec, 0.);
     39
     40  del_lvec(vec);
     41
     42  // wrong parameters
     43  assert(new_lvec(0) == NULL);
     44  assert(new_lvec(-1) == NULL);
     45
    1646  return 0;
    1747}
    18 
  • tests/src/test-mathutils-window.c

    r5f57ea9 r439ba7b  
    88  uint_t lengths[4] = { 8, 10, 15, 16 };
    99  char *method = "default";
    10   char *window_types[10] = { "default",
    11     "rectangle", "hamming", "hanning", "hanningz",
     10  char *window_types[11] = { "default",
     11    "ones", "rectangle", "hamming", "hanning", "hanningz",
    1212    "blackman", "blackman_harris", "gaussian", "welch", "parzen"};
    1313
     
    2727    }
    2828  }
     29
     30  assert (new_aubio_window("parzen", -1) == NULL);
     31  assert (new_aubio_window(NULL, length) == NULL);
     32  assert (new_aubio_window("\0", length) == NULL);
    2933  return 0;
    3034}
  • wscript

    r5f57ea9 r439ba7b  
    143143    ctx.check(header_name='math.h')
    144144    ctx.check(header_name='string.h')
     145    ctx.check(header_name='errno.h')
    145146    ctx.check(header_name='limits.h')
    146147    ctx.check(header_name='stdarg.h')
     
    639640    ctx.excl += ' **/.cache'
    640641    ctx.excl += ' **/**.zip **/**.tar.bz2'
    641     ctx.excl += ' **.tar.bz2'
     642    ctx.excl += ' **.tar.bz2**'
    642643    ctx.excl += ' **/doc/full/* **/doc/web/*'
    643644    ctx.excl += ' **/doc/full.cfg'
     
    651652    ctx.excl += ' **/.DS_Store'
    652653    ctx.excl += ' **/.travis.yml'
    653     ctx.excl += ' **/.landscape.yml'
    654654    ctx.excl += ' **/.appveyor.yml'
    655655    ctx.excl += ' **/.circleci/*'
Note: See TracChangeset for help on using the changeset viewer.