Changeset 41b985f for python


Ignore:
Timestamp:
Mar 12, 2017, 11:26:24 AM (8 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
sampler
Children:
bde49c4a
Parents:
71f2e5f (diff), 67b6618 (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 'origin/master' into sampler

Conflicts:

.travis.yml
Makefile
examples/aubionotes.c
examples/parse_args.h
python/demos/demo_timestretch_online.py
python/lib/moresetuptools.py
python/tests/test_source.py
setup.py
src/io/source.c

Location:
python
Files:
6 added
23 edited

Legend:

Unmodified
Added
Removed
  • python/README.md

    r71f2e5f r41b985f  
    3636-------------------------
    3737
     38Python tests are in `python/tests` and use the [nose2 python package][nose2].
     39
    3840To run the all the python tests, use the script:
    3941
     
    4345
    4446    $ ./python/tests/test_note2midi.py -v
     47
     48[nose2]: https://github.com/nose-devs/nose2
    4549
    4650Install in a virtualenv
  • python/demos/demo_timestretch_online.py

    r71f2e5f r41b985f  
    1212import numpy as np
    1313
    14 win_s = 1024
     14win_s = 512
    1515hop_s = win_s // 8 # 87.5 % overlap
    1616
     
    9393    old_grain.phas = np.copy(cur_grain.phas)
    9494
     95    # until end of file
     96    if read < hop_s: break
     97    # increment block counter
    9598    block_read += 1
    96     if read < hop_s: break
    9799
    98100for t in range(warmup + 2): # purge the last frames from the phase vocoder
  • python/ext/aubio-types.h

    r71f2e5f r41b985f  
    2828#include "aubio.h"
    2929#else
    30 #include "aubio/aubio.h"
     30#include <aubio/aubio.h>
    3131#endif
    3232
     
    4545#define AUBIO_NPY_SMPL_STR "float32"
    4646#define AUBIO_NPY_SMPL_CHR "f"
     47#endif
     48
     49#ifndef PATH_MAX
     50#ifdef MAX_PATH
     51#define PATH_MAX MAX_PATH
     52#else
     53#define PATH_MAX 1024
     54#endif
    4755#endif
    4856
  • python/ext/aubiomodule.c

    r71f2e5f r41b985f  
    22#include "aubio-types.h"
    33#include "py-musicutils.h"
     4
     5// this dummy macro is used to convince windows that a string passed as -D flag
     6// is just that, a string, and not a double.
     7#define REDEFINESTRING(x) #x
     8#define DEFINEDSTRING(x) REDEFINESTRING(x)
    49
    510static char aubio_module_doc[] = "Python module for the aubio library";
     
    324329
    325330  PyModule_AddStringConstant(m, "float_type", AUBIO_NPY_SMPL_STR);
     331  PyModule_AddStringConstant(m, "__version__", DEFINEDSTRING(AUBIO_VERSION));
    326332
    327333  // add generated objects
  • python/ext/py-cvec.c

    r71f2e5f r41b985f  
    148148  if (length != vec->length) {
    149149    PyErr_Format (PyExc_ValueError,
    150         "input array has length %ld, but cvec has length %d", length,
     150        "input array has length %" NPY_INTP_FMT ", but cvec has length %d", length,
    151151        vec->length);
    152152    return 1;
     
    169169  if (length != vec->length) {
    170170    PyErr_Format (PyExc_ValueError,
    171         "input array has length %ld, but cvec has length %d", length,
     171        "input array has length %" NPY_INTP_FMT ", but cvec has length %d", length,
    172172        vec->length);
    173173    return 1;
  • python/ext/py-sink.c

    r71f2e5f r41b985f  
    8181  }
    8282
    83   self->uri = "none";
     83  self->uri = NULL;
    8484  if (uri != NULL) {
    85     self->uri = uri;
     85    self->uri = (char_t *)malloc(sizeof(char_t) * (strnlen(uri, PATH_MAX) + 1));
     86    strncpy(self->uri, uri, strnlen(uri, PATH_MAX) + 1);
    8687  }
    8788
    8889  self->samplerate = Py_aubio_default_samplerate;
    89   if ((sint_t)samplerate > 0) {
     90  if (samplerate != 0) {
    9091    self->samplerate = samplerate;
    91   } else if ((sint_t)samplerate < 0) {
    92     PyErr_SetString (PyExc_ValueError,
    93         "can not use negative value for samplerate");
    94     return NULL;
    9592  }
    9693
    9794  self->channels = 1;
    98   if ((sint_t)channels > 0) {
     95  if (channels != 0) {
    9996    self->channels = channels;
    100   } else if ((sint_t)channels < 0) {
    101     PyErr_SetString (PyExc_ValueError,
    102         "can not use negative or null value for channels");
    103     return NULL;
    10497  }
    10598
     
    110103Py_sink_init (Py_sink * self, PyObject * args, PyObject * kwds)
    111104{
    112   if (self->channels == 1) {
    113     self->o = new_aubio_sink ( self->uri, self->samplerate );
    114   } else {
    115     self->o = new_aubio_sink ( self->uri, 0 );
    116     aubio_sink_preset_channels ( self->o, self->channels );
    117     aubio_sink_preset_samplerate ( self->o, self->samplerate );
    118   }
     105  self->o = new_aubio_sink ( self->uri, 0 );
    119106  if (self->o == NULL) {
    120     PyErr_SetString (PyExc_RuntimeError, "error creating sink with this uri");
     107    // error string was set in new_aubio_sink
    121108    return -1;
    122109  }
     110  if (aubio_sink_preset_channels(self->o, self->channels) != 0) {
     111    // error string was set in aubio_sink_preset_channels
     112    return -1;
     113  }
     114  if (aubio_sink_preset_samplerate(self->o, self->samplerate) != 0) {
     115    // error string was set in aubio_sink_preset_samplerate
     116    return -1;
     117  }
     118
    123119  self->samplerate = aubio_sink_get_samplerate ( self->o );
    124120  self->channels = aubio_sink_get_channels ( self->o );
     
    132128  del_aubio_sink(self->o);
    133129  free(self->mwrite_data.data);
     130  if (self->uri) {
     131    free(self->uri);
     132  }
    134133  Py_TYPE(self)->tp_free((PyObject *) self);
    135134}
     
    205204}
    206205
     206static char Pyaubio_sink_enter_doc[] = "";
     207static PyObject* Pyaubio_sink_enter(Py_sink *self, PyObject *unused) {
     208  Py_INCREF(self);
     209  return (PyObject*)self;
     210}
     211
     212static char Pyaubio_sink_exit_doc[] = "";
     213static PyObject* Pyaubio_sink_exit(Py_sink *self, PyObject *unused) {
     214  return Pyaubio_sink_close(self, unused);
     215}
     216
    207217static PyMethodDef Py_sink_methods[] = {
    208218  {"do", (PyCFunction) Py_sink_do, METH_VARARGS, Py_sink_do_doc},
    209219  {"do_multi", (PyCFunction) Py_sink_do_multi, METH_VARARGS, Py_sink_do_multi_doc},
    210220  {"close", (PyCFunction) Pyaubio_sink_close, METH_NOARGS, Py_sink_close_doc},
     221  {"__enter__", (PyCFunction)Pyaubio_sink_enter, METH_NOARGS,
     222    Pyaubio_sink_enter_doc},
     223  {"__exit__",  (PyCFunction)Pyaubio_sink_exit, METH_VARARGS,
     224    Pyaubio_sink_exit_doc},
    211225  {NULL} /* sentinel */
    212226};
  • python/ext/py-source.c

    r71f2e5f r41b985f  
    101101  }
    102102
    103   self->uri = "none";
     103  self->uri = NULL;
    104104  if (uri != NULL) {
    105     self->uri = uri;
     105    self->uri = (char_t *)malloc(sizeof(char_t) * (strnlen(uri, PATH_MAX) + 1));
     106    strncpy(self->uri, uri, strnlen(uri, PATH_MAX) + 1);
    106107  }
    107108
     
    163164    del_aubio_source(self->o);
    164165    free(self->c_mread_to.data);
     166  }
     167  if (self->uri) {
     168    free(self->uri);
    165169  }
    166170  Py_XDECREF(self->read_to);
     
    243247Pyaubio_source_close (Py_source *self, PyObject *unused)
    244248{
    245   aubio_source_close (self->o);
     249  if (aubio_source_close(self->o) != 0) return NULL;
    246250  Py_RETURN_NONE;
    247251}
     
    271275  }
    272276  Py_RETURN_NONE;
     277}
     278
     279static char Pyaubio_source_enter_doc[] = "";
     280static PyObject* Pyaubio_source_enter(Py_source *self, PyObject *unused) {
     281  Py_INCREF(self);
     282  return (PyObject*)self;
     283}
     284
     285static char Pyaubio_source_exit_doc[] = "";
     286static PyObject* Pyaubio_source_exit(Py_source *self, PyObject *unused) {
     287  return Pyaubio_source_close(self, unused);
     288}
     289
     290static PyObject* Pyaubio_source_iter(PyObject *self) {
     291  Py_INCREF(self);
     292  return (PyObject*)self;
     293}
     294
     295static PyObject* Pyaubio_source_iter_next(Py_source *self) {
     296  PyObject *done, *size;
     297  if (self->channels == 1) {
     298    done = Py_source_do(self, NULL);
     299  } else {
     300    done = Py_source_do_multi(self, NULL);
     301  }
     302  if (!PyTuple_Check(done)) {
     303    PyErr_Format(PyExc_ValueError,
     304        "error when reading source: not opened?");
     305    return NULL;
     306  }
     307  size = PyTuple_GetItem(done, 1);
     308  if (size != NULL && PyLong_Check(size)) {
     309    if (PyLong_AsLong(size) == (long)self->hop_size) {
     310      PyObject *vec = PyTuple_GetItem(done, 0);
     311      return vec;
     312    } else if (PyLong_AsLong(size) > 0) {
     313      // short read, return a shorter array
     314      PyArrayObject *shortread = (PyArrayObject*)PyTuple_GetItem(done, 0);
     315      PyArray_Dims newdims;
     316      PyObject *reshaped;
     317      newdims.len = PyArray_NDIM(shortread);
     318      newdims.ptr = PyArray_DIMS(shortread);
     319      // mono or multiple channels?
     320      if (newdims.len == 1) {
     321        newdims.ptr[0] = PyLong_AsLong(size);
     322      } else {
     323        newdims.ptr[1] = PyLong_AsLong(size);
     324      }
     325      reshaped = PyArray_Newshape(shortread, &newdims, NPY_CORDER);
     326      Py_DECREF(shortread);
     327      return reshaped;
     328    } else {
     329      PyErr_SetNone(PyExc_StopIteration);
     330      return NULL;
     331    }
     332  } else {
     333    PyErr_SetNone(PyExc_StopIteration);
     334    return NULL;
     335  }
    273336}
    274337
     
    286349  {"seek", (PyCFunction) Pyaubio_source_seek,
    287350    METH_VARARGS, Py_source_seek_doc},
     351  {"__enter__", (PyCFunction)Pyaubio_source_enter, METH_NOARGS,
     352    Pyaubio_source_enter_doc},
     353  {"__exit__",  (PyCFunction)Pyaubio_source_exit, METH_VARARGS,
     354    Pyaubio_source_exit_doc},
    288355  {NULL} /* sentinel */
    289356};
     
    315382  0,
    316383  0,
    317   0,
    318   0,
     384  Pyaubio_source_iter,
     385  (unaryfunc)Pyaubio_source_iter_next,
    319386  Py_source_methods,
    320387  Py_source_members,
  • python/lib/aubio/__init__.py

    r71f2e5f r41b985f  
    22
    33import numpy
     4from ._aubio import __version__ as version
     5from ._aubio import float_type
    46from ._aubio import *
    5 from ._aubio import float_type
    67from .midiconv import *
    78from .slicing import *
  • python/lib/aubio/midiconv.py

    r71f2e5f r41b985f  
    1616    " convert note name to midi note number, e.g. [C-1, G9] -> [0, 127] "
    1717    _valid_notenames = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}
    18     _valid_modifiers = {None: 0, u'♮': 0, '#': +1, u'♯': +1, u'\udd2a': +2,
    19                         'b': -1, u'♭': -1, u'\ufffd': -2}
     18    _valid_modifiers = {
     19            u'𝄫': -2,                        # double flat
     20            u'♭': -1, 'b': -1, '\u266d': -1, # simple flat
     21            u'♮': 0, '\u266e': 0, None: 0,   # natural
     22            '#': +1, u'♯': +1, '\u266f': +1, # sharp
     23            u'𝄪': +2,                        # double sharp
     24            }
    2025    _valid_octaves = range(-1, 10)
    2126    if not isinstance(note, str_instances):
  • python/lib/gen_external.py

    r71f2e5f r41b985f  
    1515  'filter',
    1616  'filterbank',
    17   #'resampler',
    1817  # AUBIO_UNSTABLE
    1918  'hist',
     
    7978    return cpp_cmd
    8079
    81 def get_cpp_objects(header=header):
     80def get_cpp_objects(header=header, usedouble=False):
    8281    cpp_cmd = get_preprocessor()
    8382
    8483    macros = [('AUBIO_UNSTABLE', 1)]
     84    if usedouble:
     85        macros += [('HAVE_AUBIO_DOUBLE', 1)]
    8586
    8687    if not os.path.isfile(header):
     
    180181    elif not overwrite: return sorted(glob.glob(os.path.join(output_path, '*.c')))
    181182
    182     cpp_output, cpp_objects = get_cpp_objects(header)
     183    cpp_output, cpp_objects = get_cpp_objects(header, usedouble=usedouble)
    183184
    184185    lib = analyze_cpp_output(cpp_objects, cpp_output)
     
    251252        # no need to add header to list of sources
    252253
    253     return sources_list
     254    return sorted(sources_list)
    254255
    255256if __name__ == '__main__':
  • python/lib/moresetuptools.py

    r71f2e5f r41b985f  
    44import distutils, distutils.command.clean, distutils.dir_util
    55from .gen_external import generate_external, header, output_path
     6
     7def get_aubio_version():
     8    # read from VERSION
     9    this_file_dir = os.path.dirname(os.path.abspath(__file__))
     10    version_file = os.path.join(this_file_dir, '..', '..', 'VERSION')
     11
     12    if not os.path.isfile(version_file):
     13        raise SystemError("VERSION file not found.")
     14
     15    for l in open(version_file).readlines():
     16        #exec (l.strip())
     17        if l.startswith('AUBIO_MAJOR_VERSION'):
     18            AUBIO_MAJOR_VERSION = int(l.split('=')[1])
     19        if l.startswith('AUBIO_MINOR_VERSION'):
     20            AUBIO_MINOR_VERSION = int(l.split('=')[1])
     21        if l.startswith('AUBIO_PATCH_VERSION'):
     22            AUBIO_PATCH_VERSION = int(l.split('=')[1])
     23        if l.startswith('AUBIO_VERSION_STATUS'):
     24            AUBIO_VERSION_STATUS = l.split('=')[1].strip()[1:-1]
     25
     26    if AUBIO_MAJOR_VERSION is None or AUBIO_MINOR_VERSION is None \
     27            or AUBIO_PATCH_VERSION is None:
     28        raise SystemError("Failed parsing VERSION file.")
     29
     30    verstr = '.'.join(map(str, [AUBIO_MAJOR_VERSION,
     31                                     AUBIO_MINOR_VERSION,
     32                                     AUBIO_PATCH_VERSION]))
     33
     34    if AUBIO_VERSION_STATUS is not None:
     35        verstr += AUBIO_VERSION_STATUS
     36    return verstr
     37
     38def get_aubio_pyversion():
     39    # convert to version for python according to pep 440
     40    # see https://www.python.org/dev/peps/pep-0440/
     41    verstr = get_aubio_version()
     42    if '~alpha' in verstr:
     43        verstr = verstr.split('~')[0] + 'a1'
     44    # TODO: add rc, .dev, and .post suffixes, add numbering
     45    return verstr
    646
    747# inspired from https://gist.github.com/abergmeier/9488990
     
    2262
    2363    for package in packages:
     64        print("checking for {:s}".format(package))
    2465        cmd = ['pkg-config', '--libs', '--cflags', package]
    2566        try:
     
    5394    ext.libraries += ['aubio']
    5495
    55 def add_local_aubio_sources(ext):
     96def add_local_aubio_sources(ext, usedouble = False):
    5697    """ build aubio inside python module instead of linking against libaubio """
    57     print("Warning: libaubio was not built with waf, adding src/")
    58     # create an empty header, macros will be passed on the command line
    59     fake_config_header = os.path.join('python', 'ext', 'config.h')
    60     distutils.file_util.write_file(fake_config_header, "")
     98    print("Info: libaubio was not installed or built locally with waf, adding src/")
    6199    aubio_sources = sorted(glob.glob(os.path.join('src', '**.c')))
    62100    aubio_sources += sorted(glob.glob(os.path.join('src', '*', '**.c')))
    63101    ext.sources += aubio_sources
     102
     103def add_local_macros(ext, usedouble = False):
    64104    # define macros (waf puts them in build/src/config.h)
    65105    for define_macro in ['HAVE_STDLIB_H', 'HAVE_STDIO_H',
     
    70110        ext.define_macros += [(define_macro, 1)]
    71111
     112def add_external_deps(ext, usedouble = False):
    72113    # loof for additional packages
    73114    print("Info: looking for *optional* additional packages")
    74115    packages = ['libavcodec', 'libavformat', 'libavutil', 'libavresample',
    75116                'jack',
    76                 'sndfile', 'samplerate',
     117                'sndfile',
     118                'samplerate',
    77119                'rubberband',
    78120                #'fftw3f',
    79121               ]
     122    # samplerate only works with float
     123    if usedouble is False:
     124        packages += ['samplerate']
     125    else:
     126        print("Info: not adding libsamplerate in double precision mode")
    80127    add_packages(packages, ext=ext)
    81128    if 'avcodec' in ext.libraries \
     
    116163def add_system_aubio(ext):
    117164    # use pkg-config to find aubio's location
    118     add_packages(['aubio'], ext)
     165    aubio_version = get_aubio_version()
     166    add_packages(['aubio = ' + aubio_version], ext)
    119167    if 'aubio' not in ext.libraries:
    120         print("Error: libaubio not found")
     168        print("Info: aubio " + aubio_version + " was not found by pkg-config")
     169    else:
     170        print("Info: using system aubio " + aubio_version + " found in " + ' '.join(ext.library_dirs))
    121171
    122172class CleanGenerated(distutils.command.clean.clean):
    123173    def run(self):
    124         distutils.dir_util.remove_tree(output_path)
    125         distutils.command.clean.clean.run(self)
     174        if os.path.isdir(output_path):
     175            distutils.dir_util.remove_tree(output_path)
    126176
    127177from distutils.command.build_ext import build_ext as _build_ext
     
    145195
    146196    def build_extension(self, extension):
    147         if self.enable_double:
     197        if self.enable_double or 'HAVE_AUBIO_DOUBLE' in os.environ:
    148198            extension.define_macros += [('HAVE_AUBIO_DOUBLE', 1)]
    149         if os.path.isfile('src/aubio.h'):
    150             # if aubio headers are found in this directory
    151             add_local_aubio_header(extension)
    152             # was waf used to build the shared lib?
    153             if os.path.isdir(os.path.join('build','src')):
    154                 # link against build/src/libaubio, built with waf
     199            enable_double = True
     200        else:
     201            enable_double = False
     202        # seack for aubio headers and lib in PKG_CONFIG_PATH
     203        add_system_aubio(extension)
     204        # the lib was not installed on this system
     205        if 'aubio' not in extension.libraries:
     206            # use local src/aubio.h
     207            if os.path.isfile(os.path.join('src', 'aubio.h')):
     208                add_local_aubio_header(extension)
     209            add_local_macros(extension)
     210            # look for a local waf build
     211            if os.path.isfile(os.path.join('build','src', 'fvec.c.1.o')):
    155212                add_local_aubio_lib(extension)
    156213            else:
     214                # check for external dependencies
     215                add_external_deps(extension, usedouble=enable_double)
    157216                # add libaubio sources and look for optional deps with pkg-config
    158                 add_local_aubio_sources(extension, usedouble=self.enable_double)
    159         else:
    160             # look for aubio headers and lib using pkg-config
    161             add_system_aubio(extension)
     217                add_local_aubio_sources(extension, usedouble=enable_double)
    162218        # generate files python/gen/*.c, python/gen/aubio-generated.h
    163219        extension.sources += generate_external(header, output_path, overwrite = False,
    164                 usedouble=self.enable_double)
     220                usedouble=enable_double)
    165221        return _build_ext.build_extension(self, extension)
  • python/scripts/aubiocut

    r71f2e5f r41b985f  
    66
    77import sys
    8 #from aubio.task import *
    98
    109usage = "usage: %s [options] -i soundfile" % sys.argv[0]
     
    118117            action = "store", dest = "cut_until_nsamples", default = None,
    119118            help="how many extra samples should be added at the end of each slice")
     119    parser.add_option("--cut-every-nslices", type = int,
     120            metavar = "<samples>",
     121            action = "store", dest = "cut_every_nslices", default = None,
     122            help="how many slices should be groupped together at each cut")
    120123    parser.add_option("--cut-until-nslices", type = int,
    121124            metavar = "<slices>",
     
    188191        from aubio.slicing import slice_source_at_stamps
    189192        timestamps_end = None
     193        if options.cut_every_nslices:
     194            timestamps = timestamps[::options.cut_every_nslices]
     195            nstamps = len(timestamps)
    190196        if options.cut_until_nslices and options.cut_until_nsamples:
    191197            print ("warning: using cut_until_nslices, but cut_until_nsamples is set")
  • python/tests/eval_pitch

    r71f2e5f r41b985f  
    2525import os.path
    2626import numpy
    27 from utils import array_from_text_file, array_from_yaml_file
     27from .utils import array_from_text_file, array_from_yaml_file
    2828from aubio import source, pitch, freqtomidi
    2929
  • python/tests/test_aubio.py

    r71f2e5f r41b985f  
    1010        import aubio
    1111
     12    def test_version(self):
     13        """ test aubio.version """
     14        import aubio
     15        self.assertEqual('0', aubio.version[0])
     16
    1217if __name__ == '__main__':
    1318    main()
  • python/tests/test_fft.py

    r71f2e5f r41b985f  
    3434        fftgrain = f (timegrain)
    3535        assert_equal ( fftgrain.norm, 0 )
    36         assert_equal ( fftgrain.phas, 0 )
     36        try:
     37            assert_equal ( fftgrain.phas, 0 )
     38        except AssertionError:
     39            assert_equal (fftgrain.phas[fftgrain.phas > 0], +pi)
     40            assert_equal (fftgrain.phas[fftgrain.phas < 0], -pi)
     41            assert_equal (np.abs(fftgrain.phas[np.abs(fftgrain.phas) != pi]), 0)
     42            self.skipTest('fft(fvec(%d)).phas != +0, ' % win_s \
     43                    + 'This is expected when using fftw3 on powerpc.')
    3744
    3845    def test_impulse(self):
  • python/tests/test_filter.py

    r71f2e5f r41b985f  
    44from numpy.testing import TestCase, assert_equal, assert_almost_equal
    55from aubio import fvec, digital_filter
    6 from utils import array_from_text_file
     6from .utils import array_from_text_file
    77
    88class aubio_filter_test_case(TestCase):
  • python/tests/test_filterbank.py

    r71f2e5f r41b985f  
    66import numpy as np
    77from aubio import cvec, filterbank, float_type
    8 from utils import array_from_text_file
     8from .utils import array_from_text_file
    99
    1010class aubio_filterbank_test_case(TestCase):
  • python/tests/test_midi2note.py

    r71f2e5f r41b985f  
    33
    44from aubio import midi2note
     5from nose2.tools import params
    56import unittest
    67
     
    1718class midi2note_good_values(unittest.TestCase):
    1819
    19     def test_midi2note_known_values(self):
     20    @params(*list_of_known_midis)
     21    def test_midi2note_known_values(self, midi, note):
    2022        " known values are correctly converted "
    21         for midi, note in list_of_known_midis:
    22             self.assertEqual ( midi2note(midi), note )
     23        self.assertEqual ( midi2note(midi), note )
    2324
    2425class midi2note_wrong_values(unittest.TestCase):
     
    4142
    4243if __name__ == '__main__':
    43     unittest.main()
     44    import nose2
     45    nose2.main()
  • python/tests/test_note2midi.py

    r71f2e5f r41b985f  
    55
    66from aubio import note2midi, freq2note
     7from nose2.tools import params
    78import unittest
    89
     
    1415        ( 'B3', 59 ),
    1516        ( 'B#3', 60 ),
     17        ( 'C♯4', 61 ),
    1618        ( 'A4', 69 ),
    1719        ( 'A#4', 70 ),
     20        ( 'A♯4', 70 ),
     21        ( 'A\u266f4', 70 ),
    1822        ( 'Bb4', 70 ),
    1923        ( 'B♭4', 70 ),
     24        ( 'B\u266d4', 70 ),
    2025        ( 'G8', 115 ),
    2126        ( 'G♯8', 116 ),
    2227        ( 'G9', 127 ),
    23         ( 'G\udd2a2', 45 ),
    24         ( 'B\ufffd2', 45 ),
    2528        ( 'A♮2', 45 ),
     29        )
     30
     31list_of_known_notes_with_unicode_issues = (
     32        ('C𝄪4', 62 ),
     33        ('E𝄫4', 62 ),
     34        )
     35
     36list_of_unknown_notes = (
     37        ( 'G\udd2a2' ),
     38        ( 'B\ufffd2' ),
     39        ( 'B\u266e\u266e2' ),
     40        ( 'B\u266f\u266d3' ),
     41        ( 'B33' ),
     42        ( 'C.3' ),
     43        ( 'A' ),
     44        ( '2' ),
    2645        )
    2746
    2847class note2midi_good_values(unittest.TestCase):
    2948
    30     def test_note2midi_known_values(self):
     49    @params(*list_of_known_notes)
     50    def test_note2midi_known_values(self, note, midi):
    3151        " known values are correctly converted "
    32         for note, midi in list_of_known_notes:
     52        self.assertEqual ( note2midi(note), midi )
     53
     54    @params(*list_of_known_notes_with_unicode_issues)
     55    def test_note2midi_known_values_with_unicode_issues(self, note, midi):
     56        " known values are correctly converted, unless decoding is expected to fail"
     57        try:
    3358            self.assertEqual ( note2midi(note), midi )
     59        except UnicodeEncodeError as e:
     60            import sys
     61            strfmt = "len(u'\\U0001D12A') != 1, excpected decoding failure | {:s} | {:s} {:s}"
     62            strres = strfmt.format(e, sys.platform, sys.version)
     63            # happens with: darwin 2.7.10, windows 2.7.12
     64            if len('\U0001D12A') != 1 and sys.version[0] == '2':
     65                self.skipTest(strres + " | upgrade to Python 3 to fix")
     66            else:
     67                raise
    3468
    3569class note2midi_wrong_values(unittest.TestCase):
     
    67101        self.assertRaises(TypeError, note2midi, 123)
    68102
     103    def test_note2midi_wrong_data_too_long(self):
     104        " fails when passed a note with a note name longer than expected"
     105        self.assertRaises(ValueError, note2midi, 'CB+-3')
     106
     107    @params(*list_of_unknown_notes)
     108    def test_note2midi_unknown_values(self, note):
     109        " unknown values throw out an error "
     110        self.assertRaises(ValueError, note2midi, note)
    69111
    70112class freq2note_simple_test(unittest.TestCase):
     
    75117
    76118if __name__ == '__main__':
    77     unittest.main()
     119    import nose2
     120    nose2.main()
  • python/tests/test_phasevoc.py

    r71f2e5f r41b985f  
    4747            assert_equal ( t, 0.)
    4848            assert_equal ( s.norm, 0.)
    49             assert_equal ( s.phas, 0.)
     49            try:
     50                assert_equal ( s.phas, 0 )
     51            except AssertionError:
     52                assert_equal (s.phas[s.phas > 0], +np.pi)
     53                assert_equal (s.phas[s.phas < 0], -np.pi)
     54                assert_equal (np.abs(s.phas[np.abs(s.phas) != np.pi]), 0)
     55                self.skipTest('pvoc(fvec(%d)).phas != +0, ' % win_s \
     56                        + 'This is expected when using fftw3 on powerpc.')
    5057            assert_equal ( r, 0.)
    5158
  • python/tests/test_sink.py

    r71f2e5f r41b985f  
    55from numpy.testing import TestCase
    66from aubio import fvec, source, sink
    7 from utils import list_all_sounds, get_tmp_sink_path, del_tmp_sink_path
     7from .utils import list_all_sounds, get_tmp_sink_path, del_tmp_sink_path
     8
     9import warnings
     10warnings.filterwarnings('ignore', category=UserWarning, append=True)
    811
    912list_of_sounds = list_all_sounds('sounds')
     
    2629        if not len(list_of_sounds):
    2730            self.skipTest('add some sound files in \'python/tests/sounds\'')
     31
     32    def test_wrong_filename(self):
     33        with self.assertRaises(RuntimeError):
     34            sink('')
     35
     36    def test_wrong_samplerate(self):
     37        with self.assertRaises(RuntimeError):
     38            sink(get_tmp_sink_path(), -1)
     39
     40    def test_wrong_samplerate_too_large(self):
     41        with self.assertRaises(RuntimeError):
     42            sink(get_tmp_sink_path(), 1536001, 2)
     43
     44    def test_wrong_channels(self):
     45        with self.assertRaises(RuntimeError):
     46            sink(get_tmp_sink_path(), 44100, -1)
     47
     48    def test_wrong_channels_too_large(self):
     49        with self.assertRaises(RuntimeError):
     50            sink(get_tmp_sink_path(), 44100, 202020)
    2851
    2952    def test_many_sinks(self):
     
    94117        del_tmp_sink_path(sink_path)
    95118
     119    def test_read_with(self):
     120        sink_path =get_tmp_sink_path()
     121        vec = fvec(128)
     122        with sink(sink_path, samplerate) as g:
     123            for i in range(10):
     124                g(vec, 128)
     125
    96126if __name__ == '__main__':
    97127    main()
  • python/tests/test_slicing.py

    r71f2e5f r41b985f  
    44from numpy.testing import TestCase, assert_equal
    55from aubio import slice_source_at_stamps
    6 from utils import count_files_in_directory, get_default_test_sound
    7 from utils import count_samples_in_directory, count_samples_in_file
     6from .utils import count_files_in_directory, get_default_test_sound
     7from .utils import count_samples_in_directory, count_samples_in_file
    88
    99import tempfile
  • python/tests/test_source.py

    r71f2e5f r41b985f  
    55from numpy.testing import TestCase, assert_equal
    66from aubio import source
    7 from utils import list_all_sounds
     7from .utils import list_all_sounds
    88import numpy as np
    99
     
    5757            if read < f.hop_size:
    5858                assert_equal(samples[read:], 0)
    59                 if 'brownnoise' in f.uri:
    60                     self.assertEquals(np.count_nonzero(samples[:read]), read)
    6159                break
    6260        #result_str = "read {:.2f}s ({:d} frames in {:d} blocks at {:d}Hz) from {:s}"
     
    7270            self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
    7371        assert f.samplerate != 0
    74         self.read_from_source(f)
     72        read_frames = self.read_from_source(f)
     73        if 'f_' in soundfile and samplerate == 0:
     74            import re
     75            f = re.compile('.*_\([0:9]*f\)_.*')
     76            match_f = re.findall('([0-9]*)f_', soundfile)
     77            if len(match_f) == 1:
     78                expected_frames = int(match_f[0])
     79                self.assertEqual(expected_frames, read_frames)
    7580
    7681    @params(*list_of_sounds)
     
    159164            if read < f.hop_size:
    160165                assert_equal(samples[:,read:], 0)
    161                 if 'brownnoise' in f.uri:
    162                     self.assertEquals(np.count_nonzero(samples[:,:read]), read)
    163166                break
    164167        #result_str = "read {:.2f}s ({:d} frames in {:d} channels and {:d} blocks at {:d}Hz) from {:s}"
     
    167170        return total_frames
    168171
     172class aubio_source_with(aubio_source_test_case_base):
     173
     174    #@params(*list_of_sounds)
     175    @params(*list_of_sounds)
     176    def test_read_from_mono(self, filename):
     177        total_frames = 0
     178        hop_size = 2048
     179        with source(filename, 0, hop_size) as input_source:
     180            assert_equal(input_source.hop_size, hop_size)
     181            #assert_equal(input_source.samplerate, samplerate)
     182            total_frames = 0
     183            for frames in input_source:
     184                total_frames += frames.shape[-1]
     185            # check we read as many samples as we expected
     186            assert_equal(total_frames, input_source.duration)
     187
    169188if __name__ == '__main__':
    170189    main()
Note: See TracChangeset for help on using the changeset viewer.