Changeset 088760e


Ignore:
Timestamp:
Oct 31, 2018, 10:26:52 PM (6 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/constantq
Children:
c03d191
Parents:
45c2c5c (diff), 7a54b37 (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/constantq

Files:
7 added
1 deleted
57 edited

Legend:

Unmodified
Added
Removed
  • .appveyor.yml

    r45c2c5c r088760e  
    44environment:
    55
     6  global:
     7      CUSTOM64PATH: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin
     8
    69  matrix:
    710
    811    # pre-installed python version, see:
    912    # http://www.appveyor.com/docs/installed-software#python
    10     - PYTHONDIR: "C:\\Python27"
    11       PYTHON_VERSION: "2.7.x"
    12       PYTHON_ARCH: "32"
     13    - PYTHONDIR: C:\Python27
     14      PYTHON_VERSION: 2.7.x
     15      PYTHON_ARCH: 32
    1316
    14     - PYTHONDIR: "C:\\Python27-x64"
    15       PYTHON_VERSION: "2.7.x"
    16       PYTHON_ARCH: "64"
     17    - PYTHONDIR: C:\Python27-x64
     18      PYTHON_VERSION: 2.7.x
     19      PYTHON_ARCH: 64
    1720
    18     - PYTHONDIR: "C:\\Python34"
    19       PYTHON_VERSION: "3.4.x"
    20       PYTHON_ARCH: "32"
     21    - PYTHONDIR: C:\Python35
     22      PYTHON_VERSION: 3.5.x
     23      PYTHON_ARCH: 32
    2124
    22     - PYTHONDIR: "C:\\Python34-x64"
    23       PYTHON_VERSION: "3.4.x"
    24       PYTHON_ARCH: "64"
     25    - PYTHONDIR: C:\Python35-x64
     26      PYTHON_VERSION: 3.5.x
     27      PYTHON_ARCH: 64
    2528
    26     - PYTHONDIR: "C:\\Python35"
    27       PYTHON_VERSION: "3.5.x"
    28       PYTHON_ARCH: "32"
     29    - PYTHONDIR: C:\Python36
     30      PYTHON_VERSION: 3.6.x
     31      PYTHON_ARCH: 32
    2932
    30     - PYTHONDIR: "C:\\Python35-x64"
    31       PYTHON_VERSION: "3.5.x"
    32       PYTHON_ARCH: "64"
    33       # add path required to run preprocessor step
    34       PATH_EXTRAS: "c:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin"
     33    - PYTHONDIR: C:\Python36-x64
     34      PYTHON_VERSION: 3.6.x
     35      PYTHON_ARCH: 64
     36
     37    - PYTHONDIR: C:\Python37
     38      PYTHON_VERSION: 3.7.x
     39      PYTHON_ARCH: 32
     40
     41    - PYTHONDIR: C:\Python37-x64
     42      PYTHON_VERSION: 3.7.x
     43      PYTHON_ARCH: 64
    3544
    3645install:
     
    3948  - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
    4049
     50  - "SET PATH=%PYTHONDIR%;%PYTHONDIR%\\Scripts;%PATH%"
     51
     52  - if [%PYTHON_ARCH%]==[64] SET PATH=%CUSTOM64PATH%;%PATH%
     53
    4154  # Check that we have the expected version and architecture for Python
    42   - "%PYTHONDIR%\\python.exe --version"
    43   - "%PYTHONDIR%\\python.exe -c \"import struct; print(struct.calcsize('P') * 8)\""
     55  - "python --version"
     56  - "python -c \"import struct; print(struct.calcsize('P') * 8)\""
    4457
    45   - "%PYTHONDIR%\\python.exe -m pip install --disable-pip-version-check --user --upgrade pip"
    46   - "%PYTHONDIR%\\python.exe -m pip install --upgrade setuptools"
     58  - "python -m pip install --disable-pip-version-check --user --upgrade pip"
     59  - "python -m pip install --upgrade setuptools"
    4760
    4861  # We need wheel installed to build wheels
    49   - "%PYTHONDIR%\\python.exe -m pip install wheel"
     62  - "python -m pip install wheel"
    5063
    51   - "SET PATH=%PATH_EXTRAS%;%PYTHONDIR%;%PYTHONDIR%\\Scripts;%PATH%"
     64  - "pip install -r requirements.txt"
    5265
    5366before_build:
     
    5568
    5669build_script:
     70  # also build libaubio with waf
     71  - python waf configure build install --verbose --msvc_version="msvc 14.0"
     72  # clean before building python package
     73  - python waf distclean
    5774  # build python module without using libaubio
    58   - "%PYTHONDIR%\\python.exe -m pip install -r requirements.txt"
    59   - "python setup.py build"
    60   - "%PYTHONDIR%\\python.exe -m pip install ."
     75  - pip wheel -v -v -v --wheel-dir=dist .
     76  # build, upload and install wheel (inspired by numpy's appveyor)
     77  - ps: |
     78      pip wheel -v -v -v --wheel-dir=dist .
     79      ls dist -r | Foreach-Object {
     80          Push-AppveyorArtifact $_.FullName
     81          pip install $_.FullName
     82      }
     83
     84test_script:
    6185  - "python python\\demos\\demo_create_test_sounds.py"
    6286  - "nose2 --verbose"
    63   # clean up
    64   - "python waf distclean"
    65   # build libaubio
    66   - python waf configure build --verbose --msvc_version="msvc 14.0"
  • .gitignore

    r45c2c5c r088760e  
    4444aubio-*.zip
    4545dist/*.tar.gz
     46dist/*.whl
    4647
    4748# test sounds
  • ChangeLog

    r45c2c5c r088760e  
     12018-09-22 Paul Brossier <piem@aubio.org>
     2
     3        [ Overview ]
     4
     5        * VERSION: bump to 0.4.7
     6        * src/spectral/dct.h: add dct type II object with optimised versions
     7        * src/io/, src/notes/, src/pitch: prevent crashes on corrupted files
     8        * examples/: fix jack midi output, improve messages when jack disabled
     9        * python/: add dct support, minor bug fixes tests and demos
     10        * wscript: improve support for BLAS/ATLAS
     11
     12        [ Library fixes ]
     13
     14        * src/pitch/pitchyinfft.c: fix out of bound read when samplerate > 50kHz
     15        thanks to @fCorleone (closes #189, CVE-2018-14523, debian #904906)
     16        * src/notes/notes.c: bail out if pitch creation failed (see #188)
     17        * src/io/source_wavread.c:
     18         - also exit if samplerate is negative (closes #188, CVE-2018-14522,
     19         debian #904907)
     20         - add some input validation (closes #148 and #158, CVE-2017-17054,
     21         debian #883355)
     22        * src/io/source_avcodec.c:
     23         - give up if resampling context failed opening (see #137, closes #187,
     24         CVE-2018-14521, debian #904908)
     25         - give up reading file if number of channel changes during stream (closes
     26         #137, CVE-2017-17554, debian #884237)
     27         - make sure libavutil > 52 before checking avFrame->channels (see #137)
     28         - fix build with ffmpeg 4.0, thanks to @jcowgill (closes #168, #173)
     29         - avoid deprecated call for ffmpeg >= 4.0
     30        * src/onset/onset.c: add dummy default parameters for wphase (closes #150)
     31
     32        [ Tools ]
     33
     34        * examples/parse_args.h: hide jack options if not available, improve error
     35        message (closes #182)
     36        * examples/utils.h: process_block returns void
     37        * examples/utils.c: fix examples failing to send more than one JACK midi
     38        event per frame, thanks to @cyclopsian (closes #201)
     39
     40        [ New features ]
     41
     42        * src/spectral/dct.h: add dct type II object with implementation factory
     43        * src/spectral/dct_plain.c: add plain dct implementation
     44        * src/spectral/dct_ooura.c: add ooura implementation
     45        * src/spectral/dct_fftw.c: add fftw implementation
     46        * src/spectral/dct_ipp.c: add ipp version
     47        * src/spectral/dct_accelerate.c: add vdsp/accelerate dct
     48        * tests/src/spectral/test-dct.c: check reconstruction works
     49        * src/spectral/mfcc.c: use new dct to compute mfcc
     50
     51        [ Library internals ]
     52
     53        * src/aubio_priv.h: avoid hard-coded undefs, split BLAS and ATLAS support,
     54        add vdsp scalar add and multiply
     55
     56        [ Build system ]
     57
     58        * wscript:
     59         - add options to disable examples and tests
     60         - detect includes for openblas/libblas/atlas
     61        * scripts/get_waf.sh: bump to 2.0.11, verify signature if gpg available
     62        * python/lib/gen_external.py: pass '-x c' to emcc only
     63
     64        [ Python ]
     65
     66        * python/lib/gen_code.py: add support for rdo methods
     67        * python/tests/test_dct.py: add tests for new dct
     68        * python/demos/demo_pitch_sinusoid.py: use // to yield an integer, fixing
     69        demo on py3, thanks to @ancorcruz (closes #176)
     70        * python/ext/py-musicutils.*: add shift(fvec) and ishift(fvec)
     71        * python/tests/test_fvec_shift.py: add tests for shift() and ishift()
     72        * python/lib/aubio/cmd.py: fix typo in comment
     73
     74        [ Documentation ]
     75
     76        * README.md, doc/statuslinks.rst: use latest for commits-since
     77        * examples/parse_args.h: add yinfast to pitch algorithms
     78        * doc/requirements.rst: add some blas documentation
     79        * doc/requirements.rst: split media/optimisation libraries
     80        * doc/develop.rst: fixed spelling error, thanks to Jon Williams (closes #161)
     81        * doc/aubio{pitch,notes}.txt: add yinfast to list of pitch methods
     82
     83        [ Continuous integration ]
     84
     85        * .travis.yml: remove xcode8.2 builds, group osx, add alias pip=pip2
     86        * .appveyor.yml: upgrade pip first, always use python -m pip
     87
    1882017-10-02 Paul Brossier <piem@aubio.org>
    289
  • VERSION

    r45c2c5c r088760e  
    11AUBIO_MAJOR_VERSION=0
    22AUBIO_MINOR_VERSION=4
    3 AUBIO_PATCH_VERSION=7
     3AUBIO_PATCH_VERSION=8
    44AUBIO_VERSION_STATUS='~alpha'
    55LIBAUBIO_LT_CUR=5
  • doc/about.rst

    r45c2c5c r088760e  
    6060-------
    6161
    62 aubio is a `free <http://www.debian.org/intro/free>`_ and `open source
     62aubio is a `free <https://www.debian.org/intro/free>`_ and `open source
    6363<http://www.opensource.org/docs/definition.php>`_ software; **you** can
    6464redistribute it and/or modify it under the terms of the `GNU
  • doc/aubio.txt

    r45c2c5c r088760e  
    9999NOTES
    100100
    101   The "note" command accepts all common options and no additional options.
     101  The following additional options can be used with the "notes" subcommand.
     102
     103  -s <value>, --silence <value>  silence threshold, in dB (default: -70)
     104
     105  -d <value>, --release-drop <value>  release drop level, in dB. If the level
     106  drops more than this amount since the last note started, the note will be
     107  turned off (default: 10).
    102108
    103109MFCC
  • doc/aubiomfcc.txt

    r45c2c5c r088760e  
    5252  url:
    5353
    54   http://cobweb.ecn.purdue.edu/~malcolm/interval/1998-010/ (see file mfcc.m)
     54  https://engineering.purdue.edu/~malcolm/interval/1998-010/ (see file mfcc.m)
    5555
    5656SEE ALSO
  • doc/aubionotes.txt

    r45c2c5c r088760e  
    77  aubionotes [[-i] source]
    88             [-r rate] [-B win] [-H hop]
    9              [-O method] [-t thres]
     9             [-O method] [-t thres] [-d drop]
    1010             [-p method] [-u unit] [-l thres]
    1111             [-T time-format]
     
    6969  loudest ones. A value of -90.0 would select all onsets. Defaults to -90.0.
    7070
     71  -d, --release-drop  Set the release drop threshold, in dB. If the level drops
     72  more than this amount since the last note started, the note will be turned
     73  off. Defaults to 10.
     74
    7175  -T, --timeformat format  Set time format (samples, ms, seconds). Defaults to
    7276  seconds.
     
    8892PITCH METHODS
    8993
    90   Available methods: default, schmitt, fcomb, mcomb, specacf, yin, yinfft.
     94  Available methods: default, schmitt, fcomb, mcomb, specacf, yin, yinfft,
     95  yinfast.
    9196
    9297  See aubiopitch(1) for details about these methods.
  • doc/aubiopitch.txt

    r45c2c5c r088760e  
    121121  University of London, London, UK, 2006.
    122122
     123  yinfast  YIN algorithm (accelerated)
     124
     125  An optimised implementation of the YIN algorithm, yielding results identical
     126  to the original YIN algorithm, while reducing its computational cost from
     127  O(n^2) to O(n log(n)).
     128
    123129SEE ALSO
    124130
  • doc/conf.py

    r45c2c5c r088760e  
    3030# Add any Sphinx extension module names here, as strings. They can be extensions
    3131# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
    32 extensions = ['sphinx.ext.viewcode', 'sphinx.ext.autodoc']
     32extensions = ['sphinx.ext.viewcode', 'sphinx.ext.autodoc',
     33        'sphinx.ext.napoleon', 'sphinx.ext.intersphinx']
     34
     35autodoc_member_order = 'groupwise'
     36
     37intersphinx_mapping = {
     38        'numpy': ('https://docs.scipy.org/doc/numpy/', None),
     39        }
    3340
    3441# Add any paths that contain templates here, relative to this directory.
     
    4653# General information about the project.
    4754project = u'aubio'
    48 copyright = u'2016, Paul Brossier'
     55copyright = u'2018, Paul Brossier'
    4956
    5057# The version info for the project you're documenting, acts as replacement for
  • doc/debian_packages.rst

    r45c2c5c r088760e  
    1010``git-buildpackage`` to build from the git repository. For instance:
    1111
    12 .. code-block:: bash
     12.. code-block:: console
    1313
    1414    $ git clone git://anonscm.debian.org/collab-maint/aubio.git
  • doc/index.rst

    r45c2c5c r088760e  
    7171   installing
    7272   python_module
     73   python
    7374   cli
    7475   develop
  • doc/installing.rst

    r45c2c5c r088760e  
    3232    sudo ./waf install
    3333
    34 - :ref:`install python-aubio from source <python>`::
     34- :ref:`install python-aubio from source <python-install>`::
    3535
    3636    # from git
     
    4646    pip install -v .
    4747
    48 - :ref:`install python-aubio from a pre-compiled binary <python>`::
     48- :ref:`install python-aubio from a pre-compiled binary <python-install>`::
    4949
    5050      # conda [osx, linux, win]
  • doc/python_module.rst

    r45c2c5c r088760e  
    1 .. _python:
     1.. _python-install:
    22
    3 Python module
    4 =============
     3Installing aubio for Python
     4===========================
    55
    66The aubio extension for Python is available for Python 2.7 and Python 3.
     
    1111aubio can now be installed using ``pip``:
    1212
    13 .. code-block:: bash
     13.. code-block:: console
    1414
    1515    $ pip install aubio
     
    2020From ``aubio`` source directory, run the following:
    2121
    22 .. code-block:: bash
     22.. code-block:: console
    2323
    2424    $ ./setup.py clean
     
    2626    $ sudo ./setup.py install
    2727
    28 Using aubio in python
    29 ---------------------
    3028
    31 Once you have python-aubio installed, you should be able to run ``python -c
    32 "import aubio; print(aubio.version)"``.
     29.. _py-doubleprecision:
    3330
    34 A simple example
    35 ................
     31Double precision
     32----------------
    3633
    37 Here is a :download:`simple script <../python/demos/demo_source_simple.py>`
    38 that reads all the samples from a media file:
     34This module can be compiled in double-precision mode, in which case the
     35default type for floating-point samples will be 64-bit. The default is
     36single precision mode (32-bit, recommended).
    3937
    40 .. literalinclude:: ../python/demos/demo_source_simple.py
    41    :language: python
     38To build the aubio module with double precision, use the option
     39`--enable-double` of the `build_ext` subcommand:
    4240
    43 Filtering an input sound file
    44 .............................
     41.. code:: bash
    4542
    46 Here is a more complete example, :download:`demo_filter.py
    47 <../python/demos/demo_filter.py>`. This files executes the following:
     43    $ ./setup.py clean
     44    $ ./setup.py build_ext --enable-double
     45    $ pip install -v .
    4846
    49 * read an input media file (``aubio.source``)
     47**Note**: If linking against `libaubio`, make sure the library was also
     48compiled in :ref:`doubleprecision` mode.
    5049
    51 * filter it using an `A-weighting <https://en.wikipedia.org/wiki/A-weighting>`_
    52   filter (``aubio.digital_filter``)
    5350
    54 * write result to a new file (``aubio.sink``)
     51Checking your installation
     52--------------------------
    5553
    56 .. literalinclude:: ../python/demos/demo_filter.py
    57    :language: python
     54Once the python module is installed, its version can be checked with:
    5855
    59 More demos
    60 ..........
     56.. code-block:: console
    6157
    62 Check out the `python demos folder`_ for more examples.
     58    $ python -c "import aubio; print(aubio.version, aubio.float_type)"
     59
     60The command line `aubio` is also installed:
     61
     62.. code-block:: console
     63
     64    $ aubio -h
     65
    6366
    6467Python tests
     
    6871``python/tests/run_all_tests``.
    6972
    70 .. _python demos folder: https://github.com/aubio/aubio/blob/master/python/demos
    7173.. _demo_filter.py: https://github.com/aubio/aubio/blob/master/python/demos/demo_filter.py
    7274.. _python tests: https://github.com/aubio/aubio/blob/master/python/tests
    73 
  • doc/requirements.rst

    r45c2c5c r088760e  
    3131    If ``pkg-config`` is not found in ``PATH``, the configure step will
    3232    succeed, but none of the external libraries will be used.
     33
     34Media libraries
     35---------------
    3336
    3437libav
     
    7982configure with ``--disable-samplerate``
    8083
     84Optimisation libraries
     85----------------------
     86
    8187libfftw3
    8288........
     
    9298then fail if the required library is not found. To disable this option,
    9399configure with ``--disable-fftw3``
     100
     101blas
     102....
     103
     104On macOs/iOS, `blas
     105<https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms>`_ are made
     106available through the Accelerate framework.
     107
     108On Linux, they can be enabled with ``--enable-blas``.  On Debian (etch),
     109`atlas`_, `openblas`_, and `libblas`_ have been successfully tested.
     110
     111When enabled, ``waf`` will check for the current blas configuration by running
     112``pkg-config --libs blas``. Depending of the library path returned by
     113``pkg-config``, different headers will be searched for.
     114
     115.. note::
     116
     117    On Debian systems, `multiple versions of BLAS and LAPACK
     118    <https://wiki.debian.org/DebianScience/LinearAlgebraLibraries>`_ can be
     119    installed. To configure which libblas is being used:
     120
     121    .. code-block:: console
     122
     123      $ sudo update-alternatives --config libblas.so
     124
     125..
     126  Expected pkg-config output for each alternative:
     127    /usr/lib/atlas-base/atlas/libblas.so
     128    -L/usr/lib/atlas-base/atlas -lblas
     129    /usr/lib/openblas-base/libblas.so
     130    -L/usr/lib/openblas-base -lblas
     131    /usr/lib/libblas/libblas.so
     132    -lblas
     133
     134atlas
     135.....
     136
     137`ATLAS BLAS APIs <http://math-atlas.sourceforge.net/>`_ will be used the path
     138returned by ``pkg-config --libs blas`` contains ``atlas``.
     139
     140..
     141  ``<atlas/cblas.h>`` will be included.
     142
     143Example:
     144
     145.. code-block:: console
     146
     147  $ pkg-config --libs blas
     148  -L/usr/lib/atlas-base/atlas -lblas
     149  $ ./waf configure --enable-atlas
     150  [...]
     151  Checking for 'blas'                      : yes
     152  Checking for header atlas/cblas.h        : yes
     153
     154openblas
     155........
     156
     157`OpenBlas libraries <https://www.openblas.net/>`_ will be used when the output
     158of ``pkg-config --libs blas`` contains 'openblas',
     159
     160..
     161  ``<openblas/cblas.h>`` will be included.
     162
     163Example:
     164
     165.. code-block:: console
     166
     167  $ pkg-config --libs blas
     168  -L/usr/lib/openblas-base -lblas
     169  $ ./waf configure --enable-atlas
     170  [...]
     171  Checking for 'blas'                      : yes
     172  Checking for header openblas/cblas.h     : yes
     173
     174libblas
     175.......
     176
     177`Netlib's libblas (LAPACK) <https://www.netlib.org/lapack/>`_ will be used if
     178no specific library path is specified by ``pkg-config``
     179
     180..
     181  ``<cblas.h>`` will be included.
     182
     183Example:
     184
     185.. code-block:: console
     186
     187  $ pkg-config --libs blas
     188  -lblas
     189  $ ./waf configure --enable-atlas
     190  [...]
     191  Checking for 'blas'                      : yes
     192  Checking for header cblas.h              : yes
     193
    94194
    95195Platform notes
     
    198298                uninstall clean distclean dist distcheck
    199299
     300.. _doubleprecision:
     301
    200302Double precision
    201303................
     
    203305To compile aubio in double precision mode, configure with ``--enable-double``.
    204306
    205 To compile aubio in single precision mode, use ``--disable-double`` (default).
     307To compile aubio in single precision mode, use ``--disable-double`` (default,
     308recommended).
    206309
    207310Disabling the tests
  • examples/aubionotes.c

    r45c2c5c r088760e  
    2222#define PROG_HAS_PITCH 1
    2323#define PROG_HAS_ONSET 1
     24#define PROG_HAS_NOTES 1
    2425#define PROG_HAS_SILENCE 1
    2526#define PROG_HAS_JACK 1
     
    8384    }
    8485  }
     86  if (release_drop != 10.) {
     87    if (aubio_notes_set_release_drop (notes, release_drop) != 0) {
     88      errmsg ("failed setting notes release drop to %.2f\n",
     89          release_drop);
     90    }
     91  }
    8592
    8693  examples_common_process((aubio_process_func_t)process_block, process_print);
  • examples/parse_args.h

    r45c2c5c r088760e  
    4848// more general stuff
    4949extern smpl_t silence_threshold;
     50extern smpl_t release_drop;
    5051extern uint_t mix_input;
    5152// midi tap
     
    6566extern int blocks;
    6667
    67 extern fvec_t *ibuf;
    68 extern fvec_t *obuf;
     68extern fvec_t *input_buffer;
     69extern fvec_t *output_buffer;
    6970
    7071const char *prog_name;
     
    9899#ifdef PROG_HAS_PITCH
    99100      "       -p      --pitch            select pitch detection algorithm\n"
    100       "                 <default|yinfft|yin|mcomb|fcomb|schmitt>; default=yinfft\n"
     101      "                 <default|yinfft|yinfast|yin|mcomb|fcomb|schmitt>; default=yinfft\n"
    101102      "       -u      --pitch-unit       select pitch output unit\n"
    102103      "                 <default|freq|hertz|Hz|midi|cent|bin>; default=freq\n"
     
    108109      "                 a value in dB, for instance -70, or -100; default=-90\n"
    109110#endif /* PROG_HAS_SILENCE */
     111#ifdef PROG_HAS_NOTES
     112      "       -d      --release-drop     select release drop threshold\n"
     113      "                 a positive value in dB; default=10\n"
     114#endif
    110115      "       -T      --time-format      select time values output format\n"
    111116      "                 (samples, ms, seconds) default=seconds\n"
     
    158163    "s:"
    159164#endif /* PROG_HAS_SILENCE */
     165#ifdef PROG_HAS_NOTES
     166    "d:"
     167#endif /* PROG_HAS_SILENCE */
    160168#ifdef PROG_HAS_OUTPUT
    161169    "mf"
     
    193201    {"silence",               1, NULL, 's'},
    194202#endif /* PROG_HAS_SILENCE */
     203#ifdef PROG_HAS_NOTES
     204    {"release-drop",          1, NULL, 'd'},
     205#endif /* PROG_HAS_NOTES */
    195206    {"time-format",           1, NULL, 'T'},
    196207#ifdef PROG_HAS_OUTPUT
     
    201212  };
    202213#endif /* HAVE_GETOPT_H */
    203   prog_name = argv[0];
     214  // better safe than sorry
    204215  if (argc < 1) {
    205216    usage (stderr, 1);
    206     return -1;
    207   }
     217  }
     218  prog_name = argv[0];
    208219#ifdef HAVE_GETOPT_H
    209220  do {
     
    274285      case 's':                /* silence threshold */
    275286        silence_threshold = (smpl_t) atof (optarg);
     287        break;
     288      case 'd':                /* release-drop threshold */
     289        release_drop = (smpl_t) atof (optarg);
    276290        break;
    277291      case 'm':                /* mix_input flag */
  • examples/utils.c

    r45c2c5c r088760e  
    5555// more general stuff
    5656smpl_t silence_threshold = -90.;
     57smpl_t release_drop = 10.;
    5758uint_t mix_input = 0;
    5859
     
    6364aubio_source_t *this_source = NULL;
    6465aubio_sink_t *this_sink = NULL;
    65 fvec_t *ibuf;
    66 fvec_t *obuf;
     66fvec_t *input_buffer;
     67fvec_t *output_buffer;
    6768
    6869smpl_t miditap_note = 69.;
     
    7677
    7778#if HAVE_JACK
     79#define MAX_MIDI_EVENTS 128
     80#define MAX_MIDI_EVENT_SIZE 3
    7881aubio_jack_t *jack_setup;
    7982jack_midi_event_t ev;
     83jack_midi_data_t midi_data[MAX_MIDI_EVENTS * MAX_MIDI_EVENT_SIZE];
     84size_t midi_event_count = 0;
    8085#endif /* HAVE_JACK */
    8186
     
    122127#endif /* HAVE_JACK */
    123128  }
    124   ibuf = new_fvec (hop_size);
    125   obuf = new_fvec (hop_size);
     129  input_buffer = new_fvec (hop_size);
     130  output_buffer = new_fvec (hop_size);
    126131
    127132}
     
    129134void examples_common_del (void)
    130135{
    131 #ifdef HAVE_JACK
    132   if (ev.buffer) free(ev.buffer);
    133 #endif
    134   del_fvec (ibuf);
    135   del_fvec (obuf);
     136  del_fvec (input_buffer);
     137  del_fvec (output_buffer);
    136138  aubio_cleanup ();
    137139  fflush(stderr);
     
    147149
    148150#ifdef HAVE_JACK
    149     ev.size = 3;
    150     ev.buffer = malloc (3 * sizeof (jack_midi_data_t));
     151    ev.size = MAX_MIDI_EVENT_SIZE;
    151152    ev.time = 0; // send it now
    152153    debug ("Jack activation ...\n");
     
    166167
    167168    do {
    168       aubio_source_do (this_source, ibuf, &read);
    169       process_func (ibuf, obuf);
     169      aubio_source_do (this_source, input_buffer, &read);
     170      process_func (input_buffer, output_buffer);
    170171      // print to console if verbose or no output given
    171172      if (verbose || sink_uri == NULL) {
     
    173174      }
    174175      if (this_sink) {
    175         aubio_sink_do (this_sink, obuf, hop_size);
     176        aubio_sink_do (this_sink, output_buffer, hop_size);
    176177      }
    177178      blocks++;
     
    194195#ifdef HAVE_JACK
    195196  if (usejack) {
     197    ev.buffer = midi_data + midi_event_count++ * MAX_MIDI_EVENT_SIZE;
     198    if (midi_event_count >= MAX_MIDI_EVENTS) {
     199      midi_event_count = 0;
     200    }
    196201    ev.buffer[2] = velo;
    197202    ev.buffer[1] = pitch;
  • python/demos/demo_bpm_extract.py

    r45c2c5c r088760e  
    2323            pass
    2424        else:
    25             print("unknown mode {:s}".format(params.mode))
     25            raise ValueError("unknown mode {:s}".format(params.mode))
    2626    # manual settings
    2727    if 'samplerate' in params:
     
    7070    parser.add_argument('-m', '--mode',
    7171            help="mode [default|fast|super-fast]",
    72             dest="mode")
     72            dest="mode", default='default')
    7373    parser.add_argument('sources',
    74             nargs='*',
     74            nargs='+',
    7575            help="input_files")
    7676    args = parser.parse_args()
  • python/demos/demo_filter.py

    r45c2c5c r088760e  
    11#! /usr/bin/env python
    22
     3import sys
     4import os.path
     5import aubio
    36
    4 def apply_filter(path):
    5     from aubio import source, sink, digital_filter
    6     from os.path import basename, splitext
    7 
     7def apply_filter(path, target):
    88    # open input file, get its samplerate
    9     s = source(path)
     9    s = aubio.source(path)
    1010    samplerate = s.samplerate
    1111
    1212    # create an A-weighting filter
    13     f = digital_filter(7)
     13    f = aubio.digital_filter(7)
    1414    f.set_a_weighting(samplerate)
    15     # alternatively, apply another filter
    1615
    1716    # create output file
    18     o = sink("filtered_" + splitext(basename(path))[0] + ".wav", samplerate)
     17    o = aubio.sink(target, samplerate)
    1918
    2019    total_frames = 0
    2120    while True:
     21        # read from source
    2222        samples, read = s()
     23        # filter samples
    2324        filtered_samples = f(samples)
     25        # write to sink
    2426        o(filtered_samples, read)
     27        # count frames read
    2528        total_frames += read
     29        # end of file reached
    2630        if read < s.hop_size: break
    2731
     32    # print some info
    2833    duration = total_frames / float(samplerate)
    29     print ("read {:s}".format(s.uri))
    30     print ("applied A-weighting filtered ({:d} Hz)".format(samplerate))
    31     print ("wrote {:s} ({:.2f} s)".format(o.uri, duration))
     34    input_str = "input: {:s} ({:.2f} s, {:d} Hz)"
     35    output_str = "output: {:s}, A-weighting filtered ({:d} frames total)"
     36    print (input_str.format(s.uri, duration, samplerate))
     37    print (output_str.format(o.uri, total_frames))
    3238
    3339if __name__ == '__main__':
    34     import sys
    35     for f in sys.argv[1:]:
    36         apply_filter(f)
     40    usage = "{:s} <input_file> [output_file]".format(sys.argv[0])
     41    if not 1 < len(sys.argv) < 4:
     42        print (usage)
     43        sys.exit(1)
     44    if len(sys.argv) < 3:
     45        input_path = sys.argv[1]
     46        basename = os.path.splitext(os.path.basename(input_path))[0] + ".wav"
     47        output_path = "filtered_" + basename
     48    else:
     49        input_path, output_path = sys.argv[1:]
     50    # run function
     51    apply_filter(input_path, output_path)
  • python/demos/demo_source_simple.py

    r45c2c5c r088760e  
    11#! /usr/bin/env python
    2 import sys, aubio
     2import sys
     3import aubio
    34
    4 samplerate = 0  # use original source samplerate
     5samplerate = 0 # use original source samplerate
    56hop_size = 256 # number of frames to read in one block
    6 s = aubio.source(sys.argv[1], samplerate, hop_size)
     7src = aubio.source(sys.argv[1], samplerate, hop_size)
    78total_frames = 0
    89
    9 while True: # reading loop
    10     samples, read = s()
    11     total_frames += read
     10while True:
     11    samples, read = src()     # read hop_size new samples from source
     12    total_frames += read      # increment total number of frames
    1213    if read < hop_size: break # end of file reached
    1314
    1415fmt_string = "read {:d} frames at {:d}Hz from {:s}"
    15 print (fmt_string.format(total_frames, s.samplerate, sys.argv[1]))
    16 
     16print (fmt_string.format(total_frames, src.samplerate, src.uri))
  • python/ext/aubiomodule.c

    r45c2c5c r088760e  
    1111
    1212static char Py_alpha_norm_doc[] = ""
    13 "alpha_norm(fvec, integer) -> float\n"
    14 "\n"
    15 "Compute alpha normalisation factor on vector, given alpha\n"
     13"alpha_norm(vec, alpha)\n"
     14"\n"
     15"Compute `alpha` normalisation factor of vector `vec`.\n"
     16"\n"
     17"Parameters\n"
     18"----------\n"
     19"vec : fvec\n"
     20"   input vector\n"
     21"alpha : float\n"
     22"   norm factor\n"
     23"\n"
     24"Returns\n"
     25"-------\n"
     26"float\n"
     27"   p-norm of the input vector, where `p=alpha`\n"
    1628"\n"
    1729"Example\n"
    1830"-------\n"
    1931"\n"
    20 ">>> b = alpha_norm(a, 9)";
     32">>> a = aubio.fvec(np.arange(10)); alpha = 2\n"
     33">>> aubio.alpha_norm(a, alpha), (sum(a**alpha)/len(a))**(1./alpha)\n"
     34"(5.338539123535156, 5.338539126015656)\n"
     35"\n"
     36"Note\n"
     37"----\n"
     38"Computed as:\n"
     39"\n"
     40".. math::\n"
     41"  l_{\\alpha} = \n"
     42"       \\|\\frac{\\sum_{n=0}^{N-1}{{x_n}^{\\alpha}}}{N}\\|^{1/\\alpha}\n"
     43"";
    2144
    2245static char Py_bintomidi_doc[] = ""
    23 "bintomidi(float, samplerate = integer, fftsize = integer) -> float\n"
    24 "\n"
    25 "Convert bin (float) to midi (float), given the sampling rate and the FFT size\n"
     46"bintomidi(fftbin, samplerate, fftsize)\n"
     47"\n"
     48"Convert FFT bin to frequency in midi note, given the sampling rate\n"
     49"and the size of the FFT.\n"
     50"\n"
     51"Parameters\n"
     52"----------\n"
     53"fftbin : float\n"
     54"   input frequency bin\n"
     55"samplerate : float\n"
     56"   sampling rate of the signal\n"
     57"fftsize : float\n"
     58"   size of the FFT\n"
     59"\n"
     60"Returns\n"
     61"-------\n"
     62"float\n"
     63"   Frequency converted to midi note.\n"
    2664"\n"
    2765"Example\n"
    2866"-------\n"
    2967"\n"
    30 ">>> midi = bintomidi(float, samplerate = 44100, fftsize = 1024)";
     68">>> aubio.bintomidi(10, 44100, 1024)\n"
     69"68.62871551513672\n"
     70"";
    3171
    3272static char Py_miditobin_doc[] = ""
    33 "miditobin(float, samplerate = integer, fftsize = integer) -> float\n"
    34 "\n"
    35 "Convert midi (float) to bin (float), given the sampling rate and the FFT size\n"
     73"miditobin(midi, samplerate, fftsize)\n"
     74"\n"
     75"Convert frequency in midi note to FFT bin, given the sampling rate\n"
     76"and the size of the FFT.\n"
     77"\n"
     78"Parameters\n"
     79"----------\n"
     80"midi : float\n"
     81"   input frequency, in midi note\n"
     82"samplerate : float\n"
     83"   sampling rate of the signal\n"
     84"fftsize : float\n"
     85"   size of the FFT\n"
     86"\n"
     87"Returns\n"
     88"-------\n"
     89"float\n"
     90"   Frequency converted to FFT bin.\n"
     91"\n"
     92"Examples\n"
     93"--------\n"
     94"\n"
     95">>> aubio.miditobin(69, 44100, 1024)\n"
     96"10.216779708862305\n"
     97">>> aubio.miditobin(75.08, 32000, 512)\n"
     98"10.002175331115723\n"
     99"";
     100
     101static char Py_bintofreq_doc[] = ""
     102"bintofreq(fftbin, samplerate, fftsize)\n"
     103"\n"
     104"Convert FFT bin to frequency in Hz, given the sampling rate\n"
     105"and the size of the FFT.\n"
     106"\n"
     107"Parameters\n"
     108"----------\n"
     109"fftbin : float\n"
     110"   input frequency bin\n"
     111"samplerate : float\n"
     112"   sampling rate of the signal\n"
     113"fftsize : float\n"
     114"   size of the FFT\n"
     115"\n"
     116"Returns\n"
     117"-------\n"
     118"float\n"
     119"   Frequency converted to Hz.\n"
    36120"\n"
    37121"Example\n"
    38122"-------\n"
    39123"\n"
    40 ">>> bin = miditobin(midi, samplerate = 44100, fftsize = 1024)";
    41 
    42 static char Py_bintofreq_doc[] = ""
    43 "bintofreq(float, samplerate = integer, fftsize = integer) -> float\n"
    44 "\n"
    45 "Convert bin number (float) in frequency (Hz), given the sampling rate and the FFT size\n"
     124">>> aubio.bintofreq(10, 44100, 1024)\n"
     125"430.6640625\n"
     126"";
     127
     128static char Py_freqtobin_doc[] = ""
     129"freqtobin(freq, samplerate, fftsize)\n"
     130"\n"
     131"Convert frequency in Hz to FFT bin, given the sampling rate\n"
     132"and the size of the FFT.\n"
     133"\n"
     134"Parameters\n"
     135"----------\n"
     136"midi : float\n"
     137"   input frequency, in midi note\n"
     138"samplerate : float\n"
     139"   sampling rate of the signal\n"
     140"fftsize : float\n"
     141"   size of the FFT\n"
     142"\n"
     143"Returns\n"
     144"-------\n"
     145"float\n"
     146"   Frequency converted to FFT bin.\n"
     147"\n"
     148"Examples\n"
     149"--------\n"
     150"\n"
     151">>> aubio.freqtobin(440, 44100, 1024)\n"
     152"10.216779708862305\n"
     153"";
     154
     155static char Py_zero_crossing_rate_doc[] = ""
     156"zero_crossing_rate(vec)\n"
     157"\n"
     158"Compute zero-crossing rate of `vec`.\n"
     159"\n"
     160"Parameters\n"
     161"----------\n"
     162"vec : fvec\n"
     163"   input vector\n"
     164"\n"
     165"Returns\n"
     166"-------\n"
     167"float\n"
     168"   Zero-crossing rate.\n"
    46169"\n"
    47170"Example\n"
    48171"-------\n"
    49172"\n"
    50 ">>> freq = bintofreq(bin, samplerate = 44100, fftsize = 1024)";
    51 
    52 static char Py_freqtobin_doc[] = ""
    53 "freqtobin(float, samplerate = integer, fftsize = integer) -> float\n"
    54 "\n"
    55 "Convert frequency (Hz) in bin number (float), given the sampling rate and the FFT size\n"
     173">>> a = np.linspace(-1., 1., 1000, dtype=aubio.float_type)\n"
     174">>> aubio.zero_crossing_rate(a), 1/1000\n"
     175"(0.0010000000474974513, 0.001)\n"
     176"";
     177
     178static char Py_min_removal_doc[] = ""
     179"min_removal(vec)\n"
     180"\n"
     181"Remove the minimum value of a vector to each of its element.\n"
     182"\n"
     183"Modifies the input vector in-place and returns a reference to it.\n"
     184"\n"
     185"Parameters\n"
     186"----------\n"
     187"vec : fvec\n"
     188"   input vector\n"
     189"\n"
     190"Returns\n"
     191"-------\n"
     192"fvec\n"
     193"   modified input vector\n"
    56194"\n"
    57195"Example\n"
    58196"-------\n"
    59197"\n"
    60 ">>> bin = freqtobin(freq, samplerate = 44100, fftsize = 1024)";
    61 
    62 static char Py_zero_crossing_rate_doc[] = ""
    63 "zero_crossing_rate(fvec) -> float\n"
    64 "\n"
    65 "Compute Zero crossing rate of a vector\n"
    66 "\n"
    67 "Example\n"
    68 "-------\n"
    69 "\n"
    70 ">>> z = zero_crossing_rate(a)";
    71 
    72 static char Py_min_removal_doc[] = ""
    73 "min_removal(fvec) -> float\n"
    74 "\n"
    75 "Remove the minimum value of a vector, in-place modification\n"
    76 "\n"
    77 "Example\n"
    78 "-------\n"
    79 "\n"
    80 ">>> min_removal(a)";
     198">>> aubio.min_removal(aubio.fvec(np.arange(1,4)))\n"
     199"array([0., 1., 2.], dtype=" AUBIO_NPY_SMPL_STR ")\n"
     200"";
    81201
    82202extern void add_ufuncs ( PyObject *m );
     
    118238  smpl_t output;
    119239
    120   if (!PyArg_ParseTuple (args, "|" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR , &input, &samplerate, &fftsize)) {
     240  if (!PyArg_ParseTuple (args,
     241        "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
     242        &input, &samplerate, &fftsize)) {
    121243    return NULL;
    122244  }
     
    133255  smpl_t output;
    134256
    135   if (!PyArg_ParseTuple (args, "|" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR , &input, &samplerate, &fftsize)) {
     257  if (!PyArg_ParseTuple (args,
     258        "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
     259        &input, &samplerate, &fftsize)) {
    136260    return NULL;
    137261  }
     
    148272  smpl_t output;
    149273
    150   if (!PyArg_ParseTuple (args, "|" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR, &input, &samplerate, &fftsize)) {
     274  if (!PyArg_ParseTuple (args,
     275        "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
     276        &input, &samplerate, &fftsize)) {
    151277    return NULL;
    152278  }
     
    163289  smpl_t output;
    164290
    165   if (!PyArg_ParseTuple (args, "|" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR, &input, &samplerate, &fftsize)) {
     291  if (!PyArg_ParseTuple (args,
     292        "" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
     293        &input, &samplerate, &fftsize)) {
    166294    return NULL;
    167295  }
  • python/ext/py-cvec.c

    r45c2c5c r088760e  
    2020} Py_cvec;
    2121
    22 static char Py_cvec_doc[] = "cvec object";
     22static char Py_cvec_doc[] = ""
     23"cvec(size)\n"
     24"\n"
     25"A container holding spectral data.\n"
     26"\n"
     27"Create one `cvec` to store the spectral information of a window\n"
     28"of `size` points. The data will be stored  in two vectors,\n"
     29":attr:`phas` and :attr:`norm`, each of shape (:attr:`length`,),\n"
     30"with `length = size // 2 + 1`.\n"
     31"\n"
     32"Parameters\n"
     33"----------\n"
     34"size: int\n"
     35"   Size of spectrum to create.\n"
     36"\n"
     37"Examples\n"
     38"--------\n"
     39">>> c = aubio.cvec(1024)\n"
     40">>> c\n"
     41"aubio cvec of 513 elements\n"
     42">>> c.length\n"
     43"513\n"
     44">>> c.norm.dtype, c.phas.dtype\n"
     45"(dtype('float32'), dtype('float32'))\n"
     46">>> c.norm.shape, c.phas.shape\n"
     47"((513,), (513,))\n"
     48"\n"
     49"See Also\n"
     50"--------\n"
     51"fvec, fft, pvoc\n"
     52"";
    2353
    2454
     
    183213  // TODO remove READONLY flag and define getter/setter
    184214  {"length", T_INT, offsetof (Py_cvec, length), READONLY,
    185       "length attribute"},
     215      "int: Length of `norm` and `phas` vectors."},
    186216  {NULL}                        /* Sentinel */
    187217};
     
    192222
    193223static PyGetSetDef Py_cvec_getseters[] = {
    194   {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm, 
    195       "Numpy vector of shape (length,) containing the magnitude",
     224  {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm,
     225      "numpy.ndarray: Vector of shape `(length,)` containing the magnitude.",
    196226      NULL},
    197   {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas, 
    198       "Numpy vector of shape (length,) containing the phase",
     227  {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas,
     228      "numpy.ndarray: Vector of shape `(length,)` containing the phase.",
    199229      NULL},
    200230  {NULL} /* sentinel */
  • python/ext/py-filterbank.c

    r45c2c5c r088760e  
    9595  if (self->vec.length != self->win_s / 2 + 1) {
    9696    PyErr_Format(PyExc_ValueError,
    97                  "input cvec has length %d, but fft expects length %d",
     97                 "input cvec has length %d, but filterbank expects length %d",
    9898                 self->vec.length, self->win_s / 2 + 1);
    9999    return NULL;
     
    140140  if (err > 0) {
    141141    PyErr_SetString (PyExc_ValueError,
    142         "error when setting filter to A-weighting");
     142        "error when running set_triangle_bands");
    143143    return NULL;
    144144  }
     
    159159  if (err > 0) {
    160160    PyErr_SetString (PyExc_ValueError,
    161         "error when setting filter to A-weighting");
     161        "error when running set_mel_coeffs_slaney");
    162162    return NULL;
    163163  }
  • python/ext/py-musicutils.h

    r45c2c5c r088760e  
    33
    44static char Py_aubio_window_doc[] = ""
    5 "window(string, integer) -> fvec\n"
    6 "\n"
    7 "Create a window\n"
    8 "\n"
    9 "Example\n"
    10 "-------\n"
    11 "\n"
    12 ">>> window('hanningz', 1024)\n"
     5"window(window_type, size)\n"
     6"\n"
     7"Create a window of length `size`. `window_type` should be one\n"
     8"of the following:\n"
     9"\n"
     10"- `default` (same as `hanningz`).\n"
     11"- `ones`\n"
     12"- `rectangle`\n"
     13"- `hamming`\n"
     14"- `hanning`\n"
     15"- `hanningz` [1]_\n"
     16"- `blackman`\n"
     17"- `blackman_harris`\n"
     18"- `gaussian`\n"
     19"- `welch`\n"
     20"- `parzen`\n"
     21"\n"
     22"Parameters\n"
     23"----------\n"
     24"window_type : str\n"
     25"   Type of window.\n"
     26"size : int\n"
     27"   Length of window.\n"
     28"\n"
     29"Returns\n"
     30"-------\n"
     31"fvec\n"
     32"   Array of shape `(length,)` containing the new window.\n"
     33"\n"
     34"See Also\n"
     35"--------\n"
     36"pvoc, fft\n"
     37"\n"
     38"Examples\n"
     39"--------\n"
     40"Compute a zero-phase Hann window on `1024` points:\n"
     41"\n"
     42">>> aubio.window('hanningz', 1024)\n"
    1343"array([  0.00000000e+00,   9.41753387e-06,   3.76403332e-05, ...,\n"
    14 "         8.46982002e-05,   3.76403332e-05,   9.41753387e-06], dtype=float32)";
     44"         8.46982002e-05,   3.76403332e-05,   9.41753387e-06], dtype=float32)\n"
     45"\n"
     46"Plot different window types with `matplotlib <https://matplotlib.org/>`_:\n"
     47"\n"
     48">>> import matplotlib.pyplot as plt\n"
     49">>> modes = ['default', 'ones', 'rectangle', 'hamming', 'hanning',\n"
     50"...          'hanningz', 'blackman', 'blackman_harris', 'gaussian',\n"
     51"...          'welch', 'parzen']; n = 2048\n"
     52">>> for m in modes: plt.plot(aubio.window(m, n), label=m)\n"
     53"...\n"
     54">>> plt.legend(); plt.show()\n"
     55"\n"
     56"Note\n"
     57"----\n"
     58"The following examples contain the equivalent source code to compute\n"
     59"each type of window with `NumPy <https://numpy.org>`_:\n"
     60"\n"
     61">>> n = 1024; x = np.arange(n, dtype=aubio.float_type)\n"
     62">>> ones = np.ones(n).astype(aubio.float_type)\n"
     63">>> rectangle = 0.5 * ones\n"
     64">>> hanning = 0.5 - 0.5 * np.cos(2 * np.pi * x / n)\n"
     65">>> hanningz = 0.5 * (1 - np.cos(2 * np.pi * x / n))\n"
     66">>> hamming = 0.54 - 0.46 * np.cos(2.*np.pi * x / (n - 1))\n"
     67">>> blackman = 0.42 \\\n"
     68"...          - 0.50 * np.cos(2 * np.pi * x / (n - 1)) \\\n"
     69"...          + 0.08 * np.cos(4 * np.pi * x / (n - 1))\n"
     70">>> blackman_harris = 0.35875 \\\n"
     71"...       - 0.48829 * np.cos(2 * np.pi * x / (n - 1)) \\\n"
     72"...       + 0.14128 * np.cos(4 * np.pi * x / (n - 1)) \\\n"
     73"...       + 0.01168 * np.cos(6 * np.pi * x / (n - 1))\n"
     74">>> gaussian = np.exp( - 0.5 * ((x - 0.5 * (n - 1)) \\\n"
     75"...                            / (0.25 * (n - 1)) )**2 )\n"
     76">>> welch = 1 - ((2 * x - n) / (n + 1))**2\n"
     77">>> parzen = 1 - np.abs((2 * x - n) / (n + 1))\n"
     78">>> default = hanningz\n"
     79"References\n"
     80"----------\n"
     81#if 0
     82"`Window function <https://en.wikipedia.org/wiki/Window_function>`_ on\n"
     83"Wikipedia.\n"
     84"\n"
     85#endif
     86".. [1] Amalia de Götzen, Nicolas Bernardini, and Daniel Arfib. Traditional\n"
     87"   (?) implementations of a phase vocoder: the tricks of the trade.\n"
     88"   In *Proceedings of the International Conference on Digital Audio\n"
     89"   Effects* (DAFx-00), pages 37–44, University of Verona, Italy, 2000.\n"
     90"   (`online version <"
     91"https://www.cs.princeton.edu/courses/archive/spr09/cos325/Bernardini.pdf"
     92">`_).\n"
     93"";
    1594
    1695PyObject * Py_aubio_window(PyObject *self, PyObject *args);
    1796
    1897static char Py_aubio_level_lin_doc[] = ""
    19 "level_lin(fvec) -> fvec\n"
    20 "\n"
    21 "Compute sound level on a linear scale.\n"
    22 "\n"
    23 "This gives the average of the square amplitudes.\n"
    24 "\n"
    25 "Example\n"
    26 "-------\n"
    27 "\n"
    28 ">>> level_Lin(numpy.ones(1024))\n"
    29 "1.0";
     98"level_lin(x)\n"
     99"\n"
     100"Compute sound pressure level of `x`, on a linear scale.\n"
     101"\n"
     102"Parameters\n"
     103"----------\n"
     104"x : fvec\n"
     105"   input vector\n"
     106"\n"
     107"Returns\n"
     108"-------\n"
     109"float\n"
     110"   Linear level of `x`.\n"
     111"\n"
     112"Example\n"
     113"-------\n"
     114"\n"
     115">>> aubio.level_lin(aubio.fvec(numpy.ones(1024)))\n"
     116"1.0\n"
     117"\n"
     118"Note\n"
     119"----\n"
     120"Computed as the average of the squared amplitudes:\n"
     121"\n"
     122".. math:: L = \\frac {\\sum_{n=0}^{N-1} {x_n}^2} {N}\n"
     123"\n"
     124"See Also\n"
     125"--------\n"
     126"db_spl, silence_detection, level_detection\n"
     127"";
    30128
    31129PyObject * Py_aubio_level_lin(PyObject *self, PyObject *args);
    32130
    33131static char Py_aubio_db_spl_doc[] = ""
    34 "Compute sound pressure level (SPL) in dB\n"
    35 "\n"
    36 "This quantity is often wrongly called 'loudness'.\n"
    37 "\n"
    38 "This gives ten times the log10 of the average of the square amplitudes.\n"
    39 "\n"
    40 "Example\n"
    41 "-------\n"
    42 "\n"
    43 ">>> db_spl(numpy.ones(1024))\n"
    44 "1.0";
     132"db_spl(x)\n"
     133"\n"
     134"Compute Sound Pressure Level (SPL) of `x`, in dB.\n"
     135"\n"
     136"Parameters\n"
     137"----------\n"
     138"x : fvec\n"
     139"   input vector\n"
     140"\n"
     141"Returns\n"
     142"-------\n"
     143"float\n"
     144"   Level of `x`, in dB SPL.\n"
     145"\n"
     146"Example\n"
     147"-------\n"
     148"\n"
     149">>> aubio.db_spl(aubio.fvec(np.ones(1024)))\n"
     150"1.0\n"
     151">>> aubio.db_spl(0.7*aubio.fvec(np.ones(32)))\n"
     152"-3.098040819168091\n"
     153"\n"
     154"Note\n"
     155"----\n"
     156"Computed as `log10` of :py:func:`level_lin`:\n"
     157"\n"
     158".. math::\n"
     159"\n"
     160"   {SPL}_{dB} = log10{\\frac {\\sum_{n=0}^{N-1}{x_n}^2} {N}}\n"
     161"\n"
     162"This quantity is often incorrectly called 'loudness'.\n"
     163"\n"
     164"See Also\n"
     165"--------\n"
     166"level_lin, silence_detection, level_detection\n"
     167"";
    45168
    46169PyObject * Py_aubio_db_spl(PyObject *self, PyObject *args);
    47170
    48171static char Py_aubio_silence_detection_doc[] = ""
    49 "Check if buffer level in dB SPL is under a given threshold\n"
    50 "\n"
    51 "Return 0 if level is under the given threshold, 1 otherwise.\n"
    52 "\n"
    53 "Example\n"
    54 "-------\n"
    55 "\n"
    56 ">>> import numpy\n"""
    57 ">>> silence_detection(numpy.ones(1024, dtype=\"float32\"), -80)\n"
    58 "0";
     172"silence_detection(vec, level)\n"
     173"\n"
     174"Check if level of `vec`, in dB SPL, is under a given threshold.\n"
     175"\n"
     176"Parameters\n"
     177"----------\n"
     178"vec : fvec\n"
     179"   input vector\n"
     180"level : float\n"
     181"   level threshold, in dB SPL\n"
     182"\n"
     183"Returns\n"
     184"-------\n"
     185"int\n"
     186"   `1` if level of `vec`, in dB SPL, is under `level`,\n"
     187"   `0` otherwise.\n"
     188"\n"
     189"Examples\n"
     190"--------\n"
     191"\n"
     192">>> aubio.silence_detection(aubio.fvec(32), -100.)\n"
     193"1\n"
     194">>> aubio.silence_detection(aubio.fvec(np.ones(32)), 0.)\n"
     195"0\n"
     196"\n"
     197"See Also\n"
     198"--------\n"
     199"level_detection, db_spl, level_lin\n"
     200"";
    59201
    60202PyObject * Py_aubio_silence_detection(PyObject *self, PyObject *args);
    61203
    62204static char Py_aubio_level_detection_doc[] = ""
    63 "Get buffer level in dB SPL if over a given threshold, 1. otherwise.\n"
    64 "\n"
    65 "Example\n"
    66 "-------\n"
    67 "\n"
    68 ">>> import numpy\n"""
    69 ">>> level_detection(0.7*numpy.ones(1024, dtype=\"float32\"), -80)\n"
    70 "0";
     205"level_detection(vec, level)\n"
     206"\n"
     207"Check if `vec` is above threshold `level`, in dB SPL.\n"
     208"\n"
     209"Parameters\n"
     210"----------\n"
     211"vec : fvec\n"
     212"   input vector\n"
     213"level : float\n"
     214"   level threshold, in dB SPL\n"
     215"\n"
     216"Returns\n"
     217"-------\n"
     218"float\n"
     219"   `1.0` if level of `vec` in dB SPL is under `level`,\n"
     220"   `db_spl(vec)` otherwise.\n"
     221"\n"
     222"Example\n"
     223"-------\n"
     224"\n"
     225">>> aubio.level_detection(0.7*aubio.fvec(np.ones(1024)), -3.)\n"
     226"1.0\n"
     227">>> aubio.level_detection(0.7*aubio.fvec(np.ones(1024)), -4.)\n"
     228"-3.0980708599090576\n"
     229"\n"
     230"See Also\n"
     231"--------\n"
     232"silence_detection, db_spl, level_lin\n"
     233"";
    71234
    72235PyObject * Py_aubio_level_detection(PyObject *self, PyObject *args);
    73236
    74237static char Py_aubio_shift_doc[] = ""
    75 "Swap left and right partitions of a vector\n"
    76 "\n"
    77 "Returns the swapped vector. The input vector is also modified.\n"
     238"shift(vec)\n"
     239"\n"
     240"Swap left and right partitions of a vector, in-place.\n"
     241"\n"
     242"Parameters\n"
     243"----------\n"
     244"vec : fvec\n"
     245"   input vector to shift\n"
     246"\n"
     247"Returns\n"
     248"-------\n"
     249"fvec\n"
     250"   The swapped vector.\n"
     251"\n"
     252"Notes\n"
     253"-----\n"
     254"The input vector is also modified.\n"
    78255"\n"
    79256"For a vector of length N, the partition is split at index N - N//2.\n"
     
    82259"-------\n"
    83260"\n"
    84 ">>> import numpy\n"
    85 ">>> shift(numpy.arange(3, dtype=aubio.float_type))\n"
    86 "array([2., 0., 1.], dtype=" AUBIO_NPY_SMPL_STR ")";
     261">>> aubio.shift(aubio.fvec(np.arange(3)))\n"
     262"array([2., 0., 1.], dtype=" AUBIO_NPY_SMPL_STR ")\n"
     263"\n"
     264"See Also\n"
     265"--------\n"
     266"ishift\n"
     267"";
    87268PyObject * Py_aubio_shift(PyObject *self, PyObject *args);
    88269
    89270static char Py_aubio_ishift_doc[] = ""
    90 "Swap right and left partitions of a vector\n"
    91 "\n"
    92 "Returns the swapped vector. The input vector is also modified.\n"
    93 "\n"
    94 "Unlike with shift(), the partition is split at index N//2.\n"
    95 "\n"
    96 "Example\n"
    97 "-------\n"
    98 "\n"
    99 ">>> import numpy\n"
    100 ">>> ishift(numpy.arange(3, dtype=aubio.float_type))\n"
    101 "array([1., 2., 0.], dtype=" AUBIO_NPY_SMPL_STR ")";
     271"ishift(vec)\n"
     272"\n"
     273"Swap right and left partitions of a vector, in-place.\n"
     274"\n"
     275"Parameters\n"
     276"----------\n"
     277"vec : fvec\n"
     278"   input vector to shift\n"
     279"\n"
     280"Returns\n"
     281"-------\n"
     282"fvec\n"
     283"   The swapped vector.\n"
     284"\n"
     285"Notes\n"
     286"-----\n"
     287"The input vector is also modified.\n"
     288"\n"
     289"Unlike with :py:func:`shift`, the partition is split at index N//2.\n"
     290"\n"
     291"Example\n"
     292"-------\n"
     293"\n"
     294">>> aubio.ishift(aubio.fvec(np.arange(3)))\n"
     295"array([1., 2., 0.], dtype=" AUBIO_NPY_SMPL_STR ")\n"
     296"\n"
     297"See Also\n"
     298"--------\n"
     299"shift\n"
     300"";
    102301PyObject * Py_aubio_ishift(PyObject *self, PyObject *args);
    103302
  • python/ext/py-phasevoc.c

    r45c2c5c r088760e  
    11#include "aubio-types.h"
    22
    3 static char Py_pvoc_doc[] = "pvoc object";
     3static char Py_pvoc_doc[] = ""
     4"pvoc(win_s=512, hop_s=256)\n"
     5"\n"
     6"Phase vocoder.\n"
     7"\n"
     8"`pvoc` creates callable object implements a phase vocoder [1]_,\n"
     9"using the tricks detailed in [2]_.\n"
     10"\n"
     11"The call function takes one input of type `fvec` and of size\n"
     12"`hop_s`, and returns a `cvec` of length `win_s//2+1`.\n"
     13"\n"
     14"Parameters\n"
     15"----------\n"
     16"win_s : int\n"
     17"  number of channels in the phase-vocoder.\n"
     18"hop_s : int\n"
     19"  number of samples expected between each call\n"
     20"\n"
     21"Examples\n"
     22"--------\n"
     23">>> x = aubio.fvec(256)\n"
     24">>> pv = aubio.pvoc(512, 256)\n"
     25">>> pv(x)\n"
     26"aubio cvec of 257 elements\n"
     27"\n"
     28"Default values for hop_s and win_s are provided:\n"
     29"\n"
     30">>> pv = aubio.pvoc()\n"
     31">>> pv.win_s, pv.hop_s\n"
     32"512, 256\n"
     33"\n"
     34"A `cvec` can be resynthesised using `rdo()`:\n"
     35"\n"
     36">>> pv = aubio.pvoc(512, 256)\n"
     37">>> y = aubio.cvec(512)\n"
     38">>> x_reconstructed = pv.rdo(y)\n"
     39">>> x_reconstructed.shape\n"
     40"(256,)\n"
     41"\n"
     42"References\n"
     43"----------\n"
     44".. [1] James A. Moorer. The use of the phase vocoder in computer music\n"
     45"   applications. `Journal of the Audio Engineering Society`,\n"
     46"   26(1/2):42–45, 1978.\n"
     47".. [2] Amalia de Götzen, Nicolas Bernardini, and Daniel Arfib. Traditional\n"
     48"   (?) implementations of a phase vocoder: the tricks of the trade.\n"
     49"   In `Proceedings of the International Conference on Digital Audio\n"
     50"   Effects` (DAFx-00), pages 37–44, University of Verona, Italy, 2000.\n"
     51"   (`online version <"
     52"https://www.cs.princeton.edu/courses/archive/spr09/cos325/Bernardini.pdf"
     53">`_).\n"
     54"";
     55
    456
    557typedef struct
     
    122174static PyMemberDef Py_pvoc_members[] = {
    123175  {"win_s", T_INT, offsetof (Py_pvoc, win_s), READONLY,
    124     "size of the window"},
     176    "int: Size of phase vocoder analysis windows, in samples.\n"
     177    ""},
    125178  {"hop_s", T_INT, offsetof (Py_pvoc, hop_s), READONLY,
    126     "size of the hop"},
     179    "int: Interval between two analysis, in samples.\n"
     180    ""},
    127181  { NULL } // sentinel
    128182};
     
    176230static PyMethodDef Py_pvoc_methods[] = {
    177231  {"rdo", (PyCFunction) Py_pvoc_rdo, METH_VARARGS,
    178     "synthesis of spectral grain"},
    179   {"set_window", (PyCFunction) Pyaubio_pvoc_set_window, METH_VARARGS, ""},
     232    "rdo(fftgrain)\n"
     233    "\n"
     234    "Read a new spectral grain and resynthesise the next `hop_s`\n"
     235    "output samples.\n"
     236    "\n"
     237    "Parameters\n"
     238    "----------\n"
     239    "fftgrain : cvec\n"
     240    "    new input `cvec` to synthesize from, should be of size `win_s/2+1`\n"
     241    "\n"
     242    "Returns\n"
     243    "-------\n"
     244    "fvec\n"
     245    "    re-synthesised output of shape `(hop_s,)`\n"
     246    "\n"
     247    "Example\n"
     248    "-------\n"
     249    ">>> pv = aubio.pvoc(2048, 512)\n"
     250    ">>> out = pv.rdo(aubio.cvec(2048))\n"
     251    ">>> out.shape\n"
     252    "(512,)\n"
     253    ""},
     254  {"set_window", (PyCFunction) Pyaubio_pvoc_set_window, METH_VARARGS,
     255    "set_window(window_type)\n"
     256    "\n"
     257    "Set window function\n"
     258    "\n"
     259    "Parameters\n"
     260    "----------\n"
     261    "window_type : str\n"
     262    "    the window type to use for this phase vocoder\n"
     263    "\n"
     264    "Raises\n"
     265    "------\n"
     266    "ValueError\n"
     267    "    If an unknown window type was given.\n"
     268    "\n"
     269    "See Also\n"
     270    "--------\n"
     271    "window : create a window.\n"
     272    ""},
    180273  {NULL}
    181274};
  • python/ext/py-sink.c

    r45c2c5c r088760e  
    1313
    1414static char Py_sink_doc[] = ""
    15 "  __new__(path, samplerate = 44100, channels = 1)\n"
    16 "\n"
    17 "      Create a new sink, opening the given path for writing.\n"
    18 "\n"
    19 "      Examples\n"
    20 "      --------\n"
    21 "\n"
    22 "      Create a new sink at 44100Hz, mono:\n"
    23 "\n"
    24 "      >>> sink('/tmp/t.wav')\n"
    25 "\n"
    26 "      Create a new sink at 8000Hz, mono:\n"
    27 "\n"
    28 "      >>> sink('/tmp/t.wav', samplerate = 8000)\n"
    29 "\n"
    30 "      Create a new sink at 32000Hz, stereo:\n"
    31 "\n"
    32 "      >>> sink('/tmp/t.wav', samplerate = 32000, channels = 2)\n"
    33 "\n"
    34 "      Create a new sink at 32000Hz, 5 channels:\n"
    35 "\n"
    36 "      >>> sink('/tmp/t.wav', channels = 5, samplerate = 32000)\n"
    37 "\n"
    38 "  __call__(vec, write)\n"
    39 "      x(vec,write) <==> x.do(vec, write)\n"
    40 "\n"
    41 "      Write vector to sink.\n"
    42 "\n"
    43 "      See also\n"
    44 "      --------\n"
    45 "      aubio.sink.do\n"
     15"sink(path, samplerate=44100, channels=1)\n"
     16"\n"
     17"Open `path` to write a WAV file.\n"
     18"\n"
     19"Parameters\n"
     20"----------\n"
     21"path : str\n"
     22"   Pathname of the file to be opened for writing.\n"
     23"samplerate : int\n"
     24"   Sampling rate of the file, in Hz.\n"
     25"channels : int\n"
     26"   Number of channels to create the file with.\n"
     27"\n"
     28"Examples\n"
     29"--------\n"
     30"\n"
     31"Create a new sink at 44100Hz, mono:\n"
     32"\n"
     33">>> snk = aubio.sink('out.wav')\n"
     34"\n"
     35"Create a new sink at 32000Hz, stereo, write 100 samples into it:\n"
     36"\n"
     37">>> snk = aubio.sink('out.wav', samplerate=16000, channels=3)\n"
     38">>> snk(aubio.fvec(100), 100)\n"
     39"\n"
     40"Open a new sink at 48000Hz, stereo, write `1234` samples into it:\n"
     41"\n"
     42">>> with aubio.sink('out.wav', samplerate=48000, channels=2) as src:\n"
     43"...     snk(aubio.fvec(1024), 1024)\n"
     44"...     snk(aubio.fvec(210), 210)\n"
     45"...\n"
     46"\n"
     47"See also\n"
     48"--------\n"
     49"source: read audio samples from a file.\n"
    4650"\n";
    4751
    4852static char Py_sink_do_doc[] = ""
    49 "x.do(vec, write) <==> x(vec, write)\n"
    50 "\n"
    51 "write monophonic vector to sink";
     53"do(vec, write)\n"
     54"\n"
     55"Write a single channel vector to sink.\n"
     56"\n"
     57"Parameters\n"
     58"----------\n"
     59"vec : fvec\n"
     60"   input vector `(n,)` where `n >= 0`.\n"
     61"write : int\n"
     62"   Number of samples to write.\n"
     63"";
    5264
    5365static char Py_sink_do_multi_doc[] = ""
    54 "x.do_multi(mat, write)\n"
    55 "\n"
    56 "write polyphonic vector to sink";
     66"do_multi(mat, write)\n"
     67"\n"
     68"Write a matrix containing vectors from multiple channels to sink.\n"
     69"\n"
     70"Parameters\n"
     71"----------\n"
     72"mat : numpy.ndarray\n"
     73"   input matrix of shape `(channels, n)`, where `n >= 0`.\n"
     74"write : int\n"
     75"   Number of frames to write.\n"
     76"";
    5777
    5878static char Py_sink_close_doc[] = ""
    59 "x.close()\n"
    60 "\n"
    61 "close this sink now";
     79"close()\n"
     80"\n"
     81"Close this sink now.\n"
     82"\n"
     83"By default, the sink will be closed before being deleted.\n"
     84"Explicitely closing a sink can be useful to control the number\n"
     85"of files simultaneously opened.\n"
     86"";
    6287
    6388static PyObject *
     
    189214static PyMemberDef Py_sink_members[] = {
    190215  {"uri", T_STRING, offsetof (Py_sink, uri), READONLY,
    191     "path at which the sink was created"},
     216    "str (read-only): Path at which the sink was created."},
    192217  {"samplerate", T_INT, offsetof (Py_sink, samplerate), READONLY,
    193     "samplerate at which the sink was created"},
     218    "int (read-only): Samplerate at which the sink was created."},
    194219  {"channels", T_INT, offsetof (Py_sink, channels), READONLY,
    195     "number of channels with which the sink was created"},
     220    "int (read-only): Number of channels with which the sink was created."},
    196221  { NULL } // sentinel
    197222};
  • python/ext/py-source.c

    r45c2c5c r088760e  
    1717
    1818static char Py_source_doc[] = ""
    19 "   __new__(path, samplerate = 0, hop_size = 512, channels = 1)\n"
    20 "\n"
    21 "       Create a new source, opening the given path for reading.\n"
    22 "\n"
    23 "       Examples\n"
    24 "       --------\n"
    25 "\n"
    26 "       Create a new source, using the original samplerate, with hop_size = 512:\n"
    27 "\n"
    28 "       >>> source('/tmp/t.wav')\n"
    29 "\n"
    30 "       Create a new source, resampling the original to 8000Hz:\n"
    31 "\n"
    32 "       >>> source('/tmp/t.wav', samplerate = 8000)\n"
    33 "\n"
    34 "       Create a new source, resampling it at 32000Hz, hop_size = 32:\n"
    35 "\n"
    36 "       >>> source('/tmp/t.wav', samplerate = 32000, hop_size = 32)\n"
    37 "\n"
    38 "       Create a new source, using its original samplerate:\n"
    39 "\n"
    40 "       >>> source('/tmp/t.wav', samplerate = 0)\n"
    41 "\n"
    42 "   __call__()\n"
    43 "       vec, read = x() <==> vec, read = x.do()\n"
    44 "\n"
    45 "       Read vector from source.\n"
    46 "\n"
    47 "       See also\n"
    48 "       --------\n"
    49 "       aubio.source.do\n"
    50 "\n";
     19"source(path, samplerate=0, hop_size=512, channels=0)\n"
     20"\n"
     21"Create a new source, opening the given pathname for reading.\n"
     22"\n"
     23"`source` open the file specified in `path` and creates a callable\n"
     24"returning `hop_size` new audio samples at each invocation.\n"
     25"\n"
     26"If `samplerate=0` (default), the original sampling rate of `path`\n"
     27"will be used. Otherwise, the output audio samples will be\n"
     28"resampled at the desired sampling-rate.\n"
     29"\n"
     30"If `channels=0` (default), the original number of channels\n"
     31"in `path` will be used. Otherwise, the output audio samples\n"
     32"will be down-mixed or up-mixed to the desired number of\n"
     33"channels.\n"
     34"\n"
     35"If `path` is a URL, a remote connection will be attempted to\n"
     36"open the resource and stream data from it.\n"
     37"\n"
     38"The parameter `hop_size` determines how many samples should be\n"
     39"read at each consecutive calls.\n"
     40"\n"
     41"Parameters\n"
     42"----------\n"
     43"path : str\n"
     44"   pathname (or URL) of the file to be opened for reading\n"
     45"samplerate : int, optional\n"
     46"   sampling rate of the file\n"
     47"hop_size : int, optional\n"
     48"   number of samples to be read per iteration\n"
     49"channels : int, optional\n"
     50"   number of channels of the file\n"
     51"\n"
     52"Examples\n"
     53"--------\n"
     54"By default, when only `path` is given, the file will be opened\n"
     55"with its original sampling rate and channel:\n"
     56"\n"
     57">>> src = aubio.source('stereo.wav')\n"
     58">>> src.uri, src.samplerate, src.channels, src.duration\n"
     59"('stereo.wav', 48000, 2, 86833)\n"
     60"\n"
     61"A typical loop to read all samples from a local file could\n"
     62"look like this:\n"
     63"\n"
     64">>> src = aubio.source('stereo.wav')\n"
     65">>> total_read = 0\n"
     66">>> while True:\n"
     67"...     samples, read = src()\n"
     68"...     # do something with samples\n"
     69"...     total_read += read\n"
     70"...     if read < src.hop_size:\n"
     71"...         break\n"
     72"...\n"
     73"\n"
     74"In a more Pythonic way, it can also look like this:\n"
     75"\n"
     76">>> total_read = 0\n"
     77">>> with aubio.source('stereo.wav') as src:\n"
     78"...     for frames in src:\n"
     79"...         total_read += samples.shape[-1]\n"
     80"...\n"
     81"\n"
     82".. rubric:: Basic interface\n"
     83"\n"
     84"`source` is a **callable**; its :meth:`__call__` method\n"
     85"returns a tuple containing:\n"
     86"\n"
     87"- a vector of shape `(hop_size,)`, filled with the `read` next\n"
     88"  samples available, zero-padded if `read < hop_size`\n"
     89"- `read`, an integer indicating the number of samples read\n"
     90"\n"
     91"To read the first `hop_size` samples from the source, simply call\n"
     92"the instance itself, with no argument:\n"
     93"\n"
     94">>> src = aubio.source('song.ogg')\n"
     95">>> samples, read = src()\n"
     96">>> samples.shape, read, src.hop_size\n"
     97"((512,), 512, 512)\n"
     98"\n"
     99"The first call returned the slice of samples `[0 : hop_size]`.\n"
     100"The next call will return samples `[hop_size: 2*hop_size]`.\n"
     101"\n"
     102"After several invocations of :meth:`__call__`, when reaching the end\n"
     103"of the opened stream, `read` might become less than `hop_size`:\n"
     104"\n"
     105">>> samples, read = src()\n"
     106">>> samples.shape, read\n"
     107"((512,), 354)\n"
     108"\n"
     109"The end of the vector `samples` is filled with zeros.\n"
     110"\n"
     111"After the end of the stream, `read` will be `0` since no more\n"
     112"samples are available:\n"
     113"\n"
     114">>> samples, read = src()\n"
     115">>> samples.shape, read\n"
     116"((512,), 0)\n"
     117"\n"
     118"**Note**: when the source has more than one channels, they\n"
     119"are be down-mixed to mono when invoking :meth:`__call__`.\n"
     120"To read from each individual channel, see :meth:`__next__`.\n"
     121"\n"
     122".. rubric:: ``for`` statements\n"
     123"\n"
     124"The `source` objects are **iterables**. This allows using them\n"
     125"directly in a ``for`` loop, which calls :meth:`__next__` until\n"
     126"the end of the stream is reached:\n"
     127"\n"
     128">>> src = aubio.source('stereo.wav')\n"
     129">>> for frames in src:\n"
     130">>>     print (frames.shape)\n"
     131"...\n"
     132"(2, 512)\n"
     133"(2, 512)\n"
     134"(2, 230)\n"
     135"\n"
     136"**Note**: When `next(self)` is called on a source with multiple\n"
     137"channels, an array of shape `(channels, read)` is returned,\n"
     138"unlike with :meth:`__call__` which always returns the down-mixed\n"
     139"channels.\n"
     140"\n"
     141"If the file is opened with a single channel, `next(self)` returns\n"
     142"an array of shape `(read,)`:\n"
     143"\n"
     144">>> src = aubio.source('stereo.wav', channels=1)\n"
     145">>> next(src).shape\n"
     146"(512,)\n"
     147"\n"
     148".. rubric:: ``with`` statements\n"
     149"\n"
     150"The `source` objects are **context managers**, which allows using\n"
     151"them in ``with`` statements:\n"
     152"\n"
     153">>> with aubio.source('audiotrack.wav') as source:\n"
     154"...     n_frames=0\n"
     155"...     for samples in source:\n"
     156"...         n_frames += len(samples)\n"
     157"...     print('read', n_frames, 'samples in', samples.shape[0], 'channels',\n"
     158"...         'from file \"\%s\"' \% source.uri)\n"
     159"...\n"
     160"read 239334 samples in 2 channels from file \"audiotrack.wav\"\n"
     161"\n"
     162"The file will be closed before exiting the statement.\n"
     163"\n"
     164"See also the methods implementing the context manager,\n"
     165":meth:`__enter__` and :meth:`__exit__`.\n"
     166"\n"
     167".. rubric:: Seeking and closing\n"
     168"\n"
     169"At any time, :meth:`seek` can be used to move to any position in\n"
     170"the file. For instance, to rewind to the start of the stream:\n"
     171"\n"
     172">>> src.seek(0)\n"
     173"\n"
     174"The opened file will be automatically closed when the object falls\n"
     175"out of scope and is scheduled for garbage collection.\n"
     176"\n"
     177"In some cases, it is useful to manually :meth:`close` a given source,\n"
     178"for instance to limit the number of simultaneously opened files:\n"
     179"\n"
     180">>> src.close()\n"
     181"\n"
     182".. rubric:: Input formats\n"
     183"\n"
     184"Depending on how aubio was compiled, :class:`source` may or may not\n"
     185"open certain **files format**. Below are some examples that assume\n"
     186"support for compressed files and remote urls was compiled in:\n"
     187"\n"
     188"- open a local file using its original sampling rate and channels,\n"
     189"  and with the default hop size:\n"
     190"\n"
     191">>> s = aubio.source('sample.wav')\n"
     192">>> s.uri, s.samplerate, s.channels, s.hop_size\n"
     193"('sample.wav', 44100, 2, 512)\n"
     194"\n"
     195"- open a local compressed audio file, resampling to 32000Hz if needed:\n"
     196"\n"
     197">>> s = aubio.source('song.mp3', samplerate=32000)\n"
     198">>> s.uri, s.samplerate, s.channels, s.hop_size\n"
     199"('song.mp3', 32000, 2, 512)\n"
     200"\n"
     201"- open a local video file, down-mixing and resampling it to 16kHz:\n"
     202"\n"
     203">>> s = aubio.source('movie.mp4', samplerate=16000, channels=1)\n"
     204">>> s.uri, s.samplerate, s.channels, s.hop_size\n"
     205"('movie.mp4', 16000, 1, 512)\n"
     206"\n"
     207"- open a remote resource, with hop_size = 1024:\n"
     208"\n"
     209">>> s = aubio.source('https://aubio.org/drum.ogg', hop_size=1024)\n"
     210">>> s.uri, s.samplerate, s.channels, s.hop_size\n"
     211"('https://aubio.org/drum.ogg', 48000, 2, 1024)\n"
     212"\n"
     213"See Also\n"
     214"--------\n"
     215"sink: write audio samples to a file.\n"
     216"";
    51217
    52218static char Py_source_get_samplerate_doc[] = ""
    53 "x.get_samplerate() -> source samplerate\n"
    54 "\n"
    55 "Get samplerate of source.";
     219"get_samplerate()\n"
     220"\n"
     221"Get sampling rate of source.\n"
     222"\n"
     223"Returns\n"
     224"-------\n"
     225"int\n"
     226"    Sampling rate, in Hz.\n"
     227"";
    56228
    57229static char Py_source_get_channels_doc[] = ""
    58 "x.get_channels() -> number of channels\n"
    59 "\n"
    60 "Get number of channels in source.";
     230"get_channels()\n"
     231"\n"
     232"Get number of channels in source.\n"
     233"\n"
     234"Returns\n"
     235"-------\n"
     236"int\n"
     237"    Number of channels.\n"
     238"";
    61239
    62240static char Py_source_do_doc[] = ""
    63 "vec, read = x.do() <==> vec, read = x()\n"
    64 "\n"
    65 "Read monophonic vector from source.";
     241"source.do()\n"
     242"\n"
     243"Read vector of audio samples.\n"
     244"\n"
     245"If the audio stream in the source has more than one channel,\n"
     246"the channels will be down-mixed.\n"
     247"\n"
     248"Returns\n"
     249"-------\n"
     250"samples : numpy.ndarray, shape `(hop_size,)`, dtype aubio.float_type\n"
     251"    `fvec` of size `hop_size` containing the new samples.\n"
     252"read : int\n"
     253"    Number of samples read from the source, equals to `hop_size`\n"
     254"    before the end-of-file is reached, less when it is reached,\n"
     255"    and `0` after.\n"
     256"\n"
     257"See Also\n"
     258"--------\n"
     259"do_multi\n"
     260"\n"
     261"Examples\n"
     262"--------\n"
     263">>> src = aubio.source('sample.wav', hop_size=1024)\n"
     264">>> src.do()\n"
     265"(array([-0.00123001, -0.00036685,  0.00097106, ..., -0.2031033 ,\n"
     266"       -0.2025854 , -0.20221856], dtype=" AUBIO_NPY_SMPL_STR "), 1024)\n"
     267"";
    66268
    67269static char Py_source_do_multi_doc[] = ""
    68 "mat, read = x.do_multi()\n"
    69 "\n"
    70 "Read polyphonic vector from source.";
     270"do_multi()\n"
     271"\n"
     272"Read multiple channels of audio samples.\n"
     273"\n"
     274"If the source was opened with the same number of channels\n"
     275"found in the stream, each channel will be read individually.\n"
     276"\n"
     277"If the source was opened with less channels than the number\n"
     278"of channels in the stream, only the first channels will be read.\n"
     279"\n"
     280"If the source was opened with more channels than the number\n"
     281"of channel in the original stream, the first channels will\n"
     282"be duplicated on the additional output channel.\n"
     283"\n"
     284"Returns\n"
     285"-------\n"
     286"samples : np.ndarray([hop_size, channels], dtype=aubio.float_type)\n"
     287"    NumPy array of shape `(hop_size, channels)` containing the new\n"
     288"    audio samples.\n"
     289"read : int\n"
     290"    Number of samples read from the source, equals to `hop_size`\n"
     291"    before the end-of-file is reached, less when it is reached,\n"
     292"    and `0` after.\n"
     293"\n"
     294"See Also\n"
     295"--------\n"
     296"do\n"
     297"\n"
     298"Examples\n"
     299"--------\n"
     300">>> src = aubio.source('sample.wav')\n"
     301">>> src.do_multi()\n"
     302"(array([[ 0.00668335,  0.0067749 ,  0.00714111, ..., -0.05737305,\n"
     303"        -0.05856323, -0.06018066],\n"
     304"       [-0.00842285, -0.0072937 , -0.00576782, ..., -0.09405518,\n"
     305"        -0.09558105, -0.09725952]], dtype=" AUBIO_NPY_SMPL_STR "), 512)\n"
     306"";
    71307
    72308static char Py_source_close_doc[] = ""
    73 "x.close()\n"
    74 "\n"
    75 "Close this source now.";
     309"close()\n"
     310"\n"
     311"Close this source now.\n"
     312"\n"
     313".. note:: Closing twice a source will **not** raise any exception.\n"
     314"";
    76315
    77316static char Py_source_seek_doc[] = ""
    78 "x.seek(position)\n"
    79 "\n"
    80 "Seek to resampled frame position.";
     317"seek(position)\n"
     318"\n"
     319"Seek to position in file.\n"
     320"\n"
     321"If the source was not opened with its original sampling-rate,\n"
     322"`position` corresponds to the position in the re-sampled file.\n"
     323"\n"
     324"Parameters\n"
     325"----------\n"
     326"position : str\n"
     327"   position to seek to, in samples\n"
     328"";
    81329
    82330static PyObject *
     
    218466static PyMemberDef Py_source_members[] = {
    219467  {"uri", T_STRING, offsetof (Py_source, uri), READONLY,
    220     "path at which the source was created"},
     468    "str (read-only): pathname or URL"},
    221469  {"samplerate", T_INT, offsetof (Py_source, samplerate), READONLY,
    222     "samplerate at which the source is viewed"},
     470    "int (read-only): sampling rate"},
    223471  {"channels", T_INT, offsetof (Py_source, channels), READONLY,
    224     "number of channels found in the source"},
     472    "int (read-only): number of channels"},
    225473  {"hop_size", T_INT, offsetof (Py_source, hop_size), READONLY,
    226     "number of consecutive frames that will be read at each do or do_multi call"},
     474    "int (read-only): number of samples read per iteration"},
    227475  {"duration", T_INT, offsetof (Py_source, duration), READONLY,
    228     "total number of frames in the source (estimated)"},
     476    "int (read-only): total number of frames in the source\n"
     477    "\n"
     478    "Can be estimated, for instance if the opened stream is\n"
     479    "a compressed media or a remote resource.\n"
     480    "\n"
     481    "Example\n"
     482    "-------\n"
     483    ">>> n = 0\n"
     484    ">>> src = aubio.source('track1.mp3')\n"
     485    ">>> for samples in src:\n"
     486    "...     n += samples.shape[-1]\n"
     487    "...\n"
     488    ">>> n, src.duration\n"
     489    "(9638784, 9616561)\n"
     490    ""},
    229491  { NULL } // sentinel
    230492};
  • python/ext/ufuncs.c

    r45c2c5c r088760e  
    5959};
    6060
    61 static char Py_unwrap2pi_doc[] = "map angle to unit circle [-pi, pi[";
     61// Note: these docstrings should *not* include the function signatures
     62
     63static char Py_unwrap2pi_doc[] = ""
     64"\n"
     65"Map angle to unit circle :math:`[-\\pi, \\pi[`.\n"
     66"\n"
     67"Parameters\n"
     68"----------\n"
     69"x : numpy.ndarray\n"
     70"   input array\n"
     71"\n"
     72"Returns\n"
     73"-------\n"
     74"numpy.ndarray\n"
     75"   values clamped to the unit circle :math:`[-\\pi, \\pi[`\n"
     76"";
    6277
    6378static void* Py_unwrap2pi_data[] = {
     
    6883};
    6984
    70 static char Py_freqtomidi_doc[] = "convert frequency to midi";
     85static char Py_freqtomidi_doc[] = ""
     86"\n"
     87"Convert frequency `[0; 23000[` to midi `[0; 128[`.\n"
     88"\n"
     89"Parameters\n"
     90"----------\n"
     91"x : numpy.ndarray\n"
     92"    Array of frequencies, in Hz.\n"
     93"\n"
     94"Returns\n"
     95"-------\n"
     96"numpy.ndarray\n"
     97"    Converted frequencies, in midi note.\n"
     98"";
    7199
    72100static void* Py_freqtomidi_data[] = {
     
    75103};
    76104
    77 static char Py_miditofreq_doc[] = "convert midi to frequency";
     105static char Py_miditofreq_doc[] = ""
     106"\n"
     107"Convert midi `[0; 128[` to frequency `[0, 23000]`.\n"
     108"\n"
     109"Parameters\n"
     110"----------\n"
     111"x : numpy.ndarray\n"
     112"    Array of frequencies, in midi note.\n"
     113"\n"
     114"Returns\n"
     115"-------\n"
     116"numpy.ndarray\n"
     117"    Converted frequencies, in Hz\n"
     118"";
    78119
    79120static void* Py_miditofreq_data[] = {
  • python/lib/aubio/__init__.py

    r45c2c5c r088760e  
    11#! /usr/bin/env python
     2# -*- coding: utf8 -*-
     3
     4"""
     5aubio
     6=====
     7
     8Provides a number of classes and functions for music and audio signal
     9analysis.
     10
     11How to use the documentation
     12----------------------------
     13
     14Documentation of the python module is available as docstrings provided
     15within the code, and a reference guide available online from `the
     16aubio homepage <https://aubio.org/documentation>`_.
     17
     18The docstrings examples are written assuming `aubio` and `numpy` have been
     19imported with:
     20
     21>>> import aubio
     22>>> import numpy as np
     23"""
    224
    325import numpy
     
    931
    1032class fvec(numpy.ndarray):
    11     """a numpy vector holding audio samples"""
     33    """fvec(input_arg=1024)
     34    A vector holding float samples.
    1235
    13     def __new__(cls, input_arg=1024, **kwargs):
     36    If `input_arg` is an `int`, a 1-dimensional vector of length `input_arg`
     37    will be created and filled with zeros. Otherwise, if `input_arg` is an
     38    `array_like` object, it will be converted to a 1-dimensional vector of
     39    type :data:`float_type`.
     40
     41    Parameters
     42    ----------
     43    input_arg : `int` or `array_like`
     44        Can be a positive integer, or any object that can be converted to
     45        a numpy array with :func:`numpy.array`.
     46
     47    Examples
     48    --------
     49    >>> aubio.fvec(10)
     50    array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)
     51    >>> aubio.fvec([0,1,2])
     52    array([0., 1., 2.], dtype=float32)
     53    >>> a = np.arange(10); type(a), type(aubio.fvec(a))
     54    (<class 'numpy.ndarray'>, <class 'numpy.ndarray'>)
     55    >>> a.dtype, aubio.fvec(a).dtype
     56    (dtype('int64'), dtype('float32'))
     57
     58    Notes
     59    -----
     60
     61    In the Python world, `fvec` is simply a subclass of
     62    :class:`numpy.ndarray`. In practice, any 1-dimensional `numpy.ndarray` of
     63    `dtype` :data:`float_type` may be passed to methods accepting
     64    `fvec` as parameter. For instance, `sink()` or `pvoc()`.
     65
     66    See Also
     67    --------
     68    cvec : a container holding spectral data
     69    numpy.ndarray : parent class of :class:`fvec`
     70    numpy.zeros : create a numpy array filled with zeros
     71    numpy.array : create a numpy array from an existing object
     72    """
     73    def __new__(cls, input_arg=1024):
    1474        if isinstance(input_arg, int):
    1575            if input_arg == 0:
    1676                raise ValueError("vector length of 1 or more expected")
    17             return numpy.zeros(input_arg, dtype=float_type, **kwargs)
     77            return numpy.zeros(input_arg, dtype=float_type, order='C')
    1878        else:
    19             return numpy.array(input_arg, dtype=float_type, **kwargs)
     79            np_input = numpy.array(input_arg, dtype=float_type, order='C')
     80            if len(np_input.shape) != 1:
     81                raise ValueError("input_arg should have shape (n,)")
     82            if np_input.shape[0] == 0:
     83                raise ValueError("vector length of 1 or more expected")
     84            return np_input
  • python/lib/aubio/cmd.py

    r45c2c5c r088760e  
    102102    subparser.add_input()
    103103    subparser.add_buf_hop_size()
     104    subparser.add_silence()
     105    subparser.add_release_drop()
    104106    subparser.add_time_format()
    105107    subparser.add_verbose_help()
     
    138140
    139141def parser_add_subcommand_cut(subparsers):
    140     # quiet subcommand
     142    # cut subcommand
    141143    subparser = subparsers.add_parser('cut',
    142144            help='slice at timestamps')
     
    207209                action="store", dest="silence", default=-70,
    208210                help="silence threshold")
     211
     212    def add_release_drop(self):
     213        self.add_argument("-d", "--release-drop",
     214                metavar = "<value>", type=float,
     215                action="store", dest="release_drop", default=10,
     216                help="release drop threshold")
    209217
    210218    def add_minioi(self, default="12ms"):
     
    248256                action = "store", dest = "cut_until_nslices", default = None,
    249257                help="how many extra slices should be added at the end of each slice")
     258        self.add_argument("--create-first",
     259                action = "store_true", dest = "create_first", default = False,
     260                help="always include first slice")
    250261
    251262# some utilities
     
    380391        self.parse_options(args, self.valid_opts)
    381392        self.notes = aubio.notes(**self.options)
     393        if args.silence is not None:
     394            self.notes.set_silence(args.silence)
     395        if args.release_drop is not None:
     396            self.notes.set_release_drop(args.release_drop)
    382397        super(process_notes, self).__init__(args)
    383398    def __call__(self, block):
     
    500515def main():
    501516    parser = aubio_parser()
    502     args = parser.parse_args()
     517    if sys.version_info[0] != 3:
     518        # on py2, create a dummy ArgumentParser to workaround the
     519        # optional subcommand issue. See https://bugs.python.org/issue9253
     520        # This ensures that:
     521        #  - version string is shown when only '-V' is passed
     522        #  - help is printed if  '-V' is passed with any other argument
     523        #  - any other argument get forwarded to the real parser
     524        parser_root = argparse.ArgumentParser(add_help=False)
     525        parser_root.add_argument('-V', '--version', help="show version",
     526                action="store_true", dest="show_version")
     527        args, extras = parser_root.parse_known_args()
     528        if args.show_version == False: # no -V, forward to parser
     529            args = parser.parse_args(extras, namespace=args)
     530        elif len(extras) != 0: # -V with other arguments, print help
     531            parser.print_help()
     532            sys.exit(1)
     533    else: # in py3, we can simply use parser directly
     534        args = parser.parse_args()
    503535    if 'show_version' in args and args.show_version:
    504536        sys.stdout.write('aubio version ' + aubio.version + '\n')
  • python/lib/aubio/cut.py

    r45c2c5c r088760e  
    102102    s = source(source_uri, samplerate, hopsize)
    103103    if samplerate == 0:
    104         samplerate = s.get_samplerate()
     104        samplerate = s.samplerate
    105105        options.samplerate = samplerate
    106106
     
    151151                timestamps, timestamps_end = timestamps_end,
    152152                output_dir = options.output_directory,
    153                 samplerate = options.samplerate)
     153                samplerate = options.samplerate,
     154                create_first = options.create_first)
    154155
    155156def main():
  • python/lib/aubio/midiconv.py

    r45c2c5c r088760e  
    22""" utilities to convert midi note number to and from note names """
    33
    4 __all__ = ['note2midi', 'midi2note', 'freq2note']
     4__all__ = ['note2midi', 'midi2note', 'freq2note', 'note2freq']
    55
    66import sys
     7from ._aubio import freqtomidi, miditofreq
     8
    79py3 = sys.version_info[0] == 3
    810if py3:
     
    1416
    1517def note2midi(note):
    16     " convert note name to midi note number, e.g. [C-1, G9] -> [0, 127] "
     18    """Convert note name to midi note number.
     19
     20    Input string `note` should be composed of one note root
     21    and one octave, with optionally one modifier in between.
     22
     23    List of valid components:
     24
     25    - note roots: `C`, `D`, `E`, `F`, `G`, `A`, `B`,
     26    - modifiers: `b`, `#`, as well as unicode characters
     27      `𝄫`, `♭`, `♮`, `♯` and `𝄪`,
     28    - octave numbers: `-1` -> `11`.
     29
     30    Parameters
     31    ----------
     32    note : str
     33        note name
     34
     35    Returns
     36    -------
     37    int
     38        corresponding midi note number
     39
     40    Examples
     41    --------
     42    >>> aubio.note2midi('C#4')
     43    61
     44    >>> aubio.note2midi('B♭5')
     45    82
     46
     47    Raises
     48    ------
     49    TypeError
     50        If `note` was not a string.
     51    ValueError
     52        If an error was found while converting `note`.
     53
     54    See Also
     55    --------
     56    midi2note, freqtomidi, miditofreq
     57    """
    1758    _valid_notenames = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}
    1859    _valid_modifiers = {
     
    2566    _valid_octaves = range(-1, 10)
    2667    if not isinstance(note, str_instances):
    27         raise TypeError("a string is required, got %s (%s)" % (note, str(type(note))))
     68        msg = "a string is required, got {:s} ({:s})"
     69        raise TypeError(msg.format(str(type(note)), repr(note)))
    2870    if len(note) not in range(2, 5):
    29         raise ValueError("string of 2 to 4 characters expected, got %d (%s)" \
    30                          % (len(note), note))
     71        msg = "string of 2 to 4 characters expected, got {:d} ({:s})"
     72        raise ValueError(msg.format(len(note), note))
    3173    notename, modifier, octave = [None]*3
    3274
     
    5294        raise ValueError("%s is not a valid octave" % octave)
    5395
    54     midi = 12 + octave * 12 + _valid_notenames[notename] + _valid_modifiers[modifier]
     96    midi = 12 + octave * 12 + _valid_notenames[notename] \
     97            + _valid_modifiers[modifier]
    5598    if midi > 127:
    5699        raise ValueError("%s is outside of the range C-2 to G8" % note)
     
    58101
    59102def midi2note(midi):
    60     " convert midi note number to note name, e.g. [0, 127] -> [C-1, G9] "
     103    """Convert midi note number to note name.
     104
     105    Parameters
     106    ----------
     107    midi : int [0, 128]
     108        input midi note number
     109
     110    Returns
     111    -------
     112    str
     113        note name
     114
     115    Examples
     116    --------
     117    >>> aubio.midi2note(70)
     118    'A#4'
     119    >>> aubio.midi2note(59)
     120    'B3'
     121
     122    Raises
     123    ------
     124    TypeError
     125        If `midi` was not an integer.
     126    ValueError
     127        If `midi` is out of the range `[0, 128]`.
     128
     129    See Also
     130    --------
     131    note2midi, miditofreq, freqtomidi
     132    """
    61133    if not isinstance(midi, int_instances):
    62134        raise TypeError("an integer is required, got %s" % midi)
    63135    if midi not in range(0, 128):
    64         raise ValueError("an integer between 0 and 127 is excepted, got %d" % midi)
    65     _valid_notenames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
     136        msg = "an integer between 0 and 127 is excepted, got {:d}"
     137        raise ValueError(msg.format(midi))
     138    _valid_notenames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#',
     139            'A', 'A#', 'B']
    66140    return _valid_notenames[midi % 12] + str(int(midi / 12) - 1)
    67141
    68142def freq2note(freq):
    69     " convert frequency in Hz to nearest note name, e.g. [0, 22050.] -> [C-1, G9] "
    70     from aubio import freqtomidi
    71     return midi2note(int(freqtomidi(freq)))
     143    """Convert frequency in Hz to nearest note name.
     144
     145    Parameters
     146    ----------
     147    freq : float [0, 23000[
     148        input frequency, in Hz
     149
     150    Returns
     151    -------
     152    str
     153        name of the nearest note
     154
     155    Example
     156    -------
     157    >>> aubio.freq2note(440)
     158    'A4'
     159    >>> aubio.freq2note(220.1)
     160    'A3'
     161    """
     162    nearest_note = int(freqtomidi(freq) + .5)
     163    return midi2note(nearest_note)
     164
     165def note2freq(note):
     166    """Convert note name to corresponding frequency, in Hz.
     167
     168    Parameters
     169    ----------
     170    note : str
     171        input note name
     172
     173    Returns
     174    -------
     175    freq : float [0, 23000[
     176        frequency, in Hz
     177
     178    Example
     179    -------
     180    >>> aubio.note2freq('A4')
     181    440
     182    >>> aubio.note2freq('A3')
     183    220.1
     184    """
     185    midi = note2midi(note)
     186    return miditofreq(midi)
  • python/lib/aubio/slicing.py

    r45c2c5c r088760e  
    77
    88def slice_source_at_stamps(source_file, timestamps, timestamps_end=None,
    9                            output_dir=None, samplerate=0, hopsize=256):
    10     """ slice a sound file at given timestamps """
     9                           output_dir=None, samplerate=0, hopsize=256,
     10                           create_first=False):
     11    """Slice a sound file at given timestamps.
     12
     13    This function reads `source_file` and creates slices, new smaller
     14    files each starting at `t` in `timestamps`, a list of integer
     15    corresponding to time locations in `source_file`, in samples.
     16
     17    If `timestamps_end` is unspecified, the slices will end at
     18    `timestamps_end[n] = timestamps[n+1]-1`, or the end of file.
     19    Otherwise, `timestamps_end` should be a list with the same length
     20    as `timestamps` containing the locations of the end of each slice.
     21
     22    If `output_dir` is unspecified, the new slices will be written in
     23    the current directory. If `output_dir` is a string, new slices
     24    will be written in `output_dir`, after creating the directory if
     25    required.
     26
     27    The default `samplerate` is 0, meaning the original sampling rate
     28    of `source_file` will be used. When using a sampling rate
     29    different to the one of the original files, `timestamps` and
     30    `timestamps_end` should be expressed in the re-sampled signal.
     31
     32    The `hopsize` parameter simply tells :class:`source` to use this
     33    hopsize and does not change the output slices.
     34
     35    If `create_first` is True and `timestamps` does not start with `0`, the
     36    first slice from `0` to `timestamps[0] - 1` will be automatically added.
     37
     38    Parameters
     39    ----------
     40    source_file : str
     41        path of the resource to slice
     42    timestamps : :obj:`list` of :obj:`int`
     43        time stamps at which to slice, in samples
     44    timestamps_end : :obj:`list` of :obj:`int` (optional)
     45        time stamps at which to end the slices
     46    output_dir : str (optional)
     47        output directory to write the slices to
     48    samplerate : int (optional)
     49        samplerate to read the file at
     50    hopsize : int (optional)
     51        number of samples read from source per iteration
     52    create_first : bool (optional)
     53        always create the slice at the start of the file
     54
     55    Examples
     56    --------
     57    Create two slices: the first slice starts at the beginning of the
     58    input file `loop.wav` and lasts exactly one second, starting at
     59    sample `0` and ending at sample `44099`; the second slice starts
     60    at sample `44100` and lasts until the end of the input file:
     61
     62    >>> aubio.slice_source_at_stamps('loop.wav', [0, 44100])
     63
     64    Create one slice, from 1 second to 2 seconds:
     65
     66    >>> aubio.slice_source_at_stamps('loop.wav', [44100], [44100 * 2 - 1])
     67
     68    Notes
     69    -----
     70    Slices may be overlapping. If `timestamps_end` is `1` element
     71    shorter than `timestamps`, the last slice will end at the end of
     72    the file.
     73    """
    1174
    1275    if timestamps is None or len(timestamps) == 0:
    1376        raise ValueError("no timestamps given")
    1477
    15     if timestamps[0] != 0:
     78    if timestamps[0] != 0 and create_first:
    1679        timestamps = [0] + timestamps
    1780        if timestamps_end is not None:
     
    1982
    2083    if timestamps_end is not None:
    21         if len(timestamps_end) != len(timestamps):
     84        if len(timestamps_end) == len(timestamps) - 1:
     85            timestamps_end = timestamps_end + [_max_timestamp]
     86        elif len(timestamps_end) != len(timestamps):
    2287            raise ValueError("len(timestamps_end) != len(timestamps)")
    2388    else:
     
    49114        vec, read = _source.do_multi()
    50115        # if the total number of frames read will exceed the next region start
    51         if len(regions) and total_frames + read >= regions[0][0]:
     116        while len(regions) and total_frames + read >= regions[0][0]:
    52117            #print "getting", regions[0], "at", total_frames
    53118            # get next region
     
    76141                    # write remaining samples from current region
    77142                    _sink.do_multi(vec[:, start:remaining], remaining - start)
    78                     #print "closing region", "remaining", remaining
     143                    #print("closing region", "remaining", remaining)
    79144                    # close this file
    80145                    _sink.close()
     
    83148                _sink.do_multi(vec[:, start:read], read - start)
    84149        total_frames += read
     150        # remove old slices
     151        slices = list(filter(lambda s: s['end_stamp'] > total_frames,
     152            slices))
    85153        if read < hopsize:
    86154            break
  • python/lib/gen_code.py

    r45c2c5c r088760e  
    483483
    484484  if (err > 0) {{
    485     PyErr_SetString (PyExc_ValueError, "error running aubio_{shortname}_set_{param}");
     485    if (PyErr_Occurred() == NULL) {{
     486      PyErr_SetString (PyExc_ValueError, "error running aubio_{shortname}_set_{param}");
     487    }} else {{
     488      // change the RuntimeError into ValueError
     489      PyObject *type, *value, *traceback;
     490      PyErr_Fetch(&type, &value, &traceback);
     491      PyErr_Restore(PyExc_ValueError, value, traceback);
     492    }}
    486493    return NULL;
    487494  }}
  • python/lib/gen_external.py

    r45c2c5c r088760e  
    7878        cpp_cmd = os.environ.get('CC', 'cc').split()
    7979        cpp_cmd += ['-E']
    80     cpp_cmd += ['-x', 'c']  # force C language (emcc defaults to c++)
     80    if 'emcc' in cpp_cmd:
     81        cpp_cmd += ['-x', 'c'] # emcc defaults to c++, force C language
    8182    return cpp_cmd
    8283
     
    8586    ''' return a dense and preprocessed  string of all c declarations implied by aubio.h
    8687    '''
     88    cpp_output = get_cpp_output(header=header, usedouble=usedouble)
     89    return filter_cpp_output (cpp_output)
     90
     91
     92def get_cpp_output(header=header, usedouble=False):
     93    ''' find and run a C pre-processor on aubio.h '''
    8794    cpp_cmd = get_preprocessor()
    8895
     
    105112    cpp_output = proc.stdout.read()
    106113    err_output = proc.stderr.read()
     114    if err_output:
     115        print("Warning: preprocessor produced errors or warnings:\n%s" \
     116                % err_output.decode('utf8'))
    107117    if not cpp_output:
    108         raise Exception("preprocessor output is empty:\n%s" % err_output)
    109     elif err_output:
    110         print("Warning: preprocessor produced warnings:\n%s" % err_output)
     118        raise_msg = "preprocessor output is empty! Running command " \
     119                + "\"%s\" failed" % " ".join(cpp_cmd)
     120        if err_output:
     121            raise_msg += " with stderr: \"%s\"" % err_output.decode('utf8')
     122        else:
     123            raise_msg += " with no stdout or stderr"
     124        raise Exception(raise_msg)
    111125    if not isinstance(cpp_output, list):
    112126        cpp_output = [l.strip() for l in cpp_output.decode('utf8').split('\n')]
    113127
    114     cpp_output = filter(lambda y: len(y) > 1, cpp_output)
     128    return cpp_output
     129
     130def filter_cpp_output(cpp_raw_output):
     131    ''' prepare cpp-output for parsing '''
     132    cpp_output = filter(lambda y: len(y) > 1, cpp_raw_output)
    115133    cpp_output = list(filter(lambda y: not y.startswith('#'), cpp_output))
    116134
  • python/tests/test_aubio_cmd.py

    r45c2c5c r088760e  
    2020
    2121    def test_samples2seconds(self):
    22         self.assertEqual(aubio.cmd.samples2seconds(3200, 32000), "0.100000\t")
     22        self.assertEqual(aubio.cmd.samples2seconds(3200, 32000),
     23                "0.100000\t")
    2324
    2425    def test_samples2milliseconds(self):
    25         self.assertEqual(aubio.cmd.samples2milliseconds(3200, 32000), "100.000000\t")
     26        self.assertEqual(aubio.cmd.samples2milliseconds(3200, 32000),
     27                "100.000000\t")
    2628
    2729    def test_samples2samples(self):
    28         self.assertEqual(aubio.cmd.samples2samples(3200, 32000), "3200\t")
     30        self.assertEqual(aubio.cmd.samples2samples(3200, 32000),
     31                "3200\t")
    2932
    3033if __name__ == '__main__':
  • python/tests/test_fvec.py

    r45c2c5c r088760e  
    6060        self.assertRaises(IndexError, a.__getitem__, 3)
    6161        self.assertRaises(IndexError, a.__getitem__, 2)
     62
     63    def test_wrong_dimensions(self):
     64        a = np.array([[[1, 2], [3, 4]]], dtype=float_type)
     65        self.assertRaises(ValueError, fvec, a)
     66
     67    def test_wrong_size(self):
     68        a = np.ndarray([0,], dtype=float_type)
     69        self.assertRaises(ValueError, fvec, a)
    6270
    6371class aubio_wrong_fvec_input(TestCase):
  • python/tests/test_note2midi.py

    r45c2c5c r088760e  
    44from __future__ import unicode_literals
    55
    6 from aubio import note2midi, freq2note
     6from aubio import note2midi, freq2note, note2freq, float_type
    77from nose2.tools import params
    88import unittest
     
    112112class freq2note_simple_test(unittest.TestCase):
    113113
    114     def test_freq2note(self):
     114    def test_freq2note_above(self):
    115115        " make sure freq2note(441) == A4 "
    116116        self.assertEqual("A4", freq2note(441))
     117
     118    def test_freq2note_under(self):
     119        " make sure freq2note(439) == A4 "
     120        self.assertEqual("A4", freq2note(439))
     121
     122class note2freq_simple_test(unittest.TestCase):
     123
     124    def test_note2freq(self):
     125        " make sure note2freq('A3') == 220"
     126        self.assertEqual(220, note2freq("A3"))
     127
     128    def test_note2freq_under(self):
     129        " make sure note2freq(A4) == 440"
     130        if float_type == 'float32':
     131            self.assertEqual(440, note2freq("A4"))
     132        else:
     133            self.assertLess(abs(note2freq("A4")-440), 1.e-12)
    117134
    118135if __name__ == '__main__':
  • python/tests/test_notes.py

    r45c2c5c r088760e  
    66
    77AUBIO_DEFAULT_NOTES_SILENCE = -70.
     8AUBIO_DEFAULT_NOTES_RELEASE_DROP = 10.
    89AUBIO_DEFAULT_NOTES_MINIOI_MS = 30.
    910
     
    3839        self.o.set_silence(val)
    3940        assert_equal (self.o.get_silence(), val)
     41
     42    def test_get_release_drop(self):
     43        assert_equal (self.o.get_release_drop(), AUBIO_DEFAULT_NOTES_RELEASE_DROP)
     44
     45    def test_set_release_drop(self):
     46        val = 50
     47        self.o.set_release_drop(val)
     48        assert_equal (self.o.get_release_drop(), val)
     49
     50    def test_set_release_drop_wrong(self):
     51        val = -10
     52        with self.assertRaises(ValueError):
     53            self.o.set_release_drop(val)
    4054
    4155from .utils import list_all_sounds
  • python/tests/test_slicing.py

    r45c2c5c r088760e  
    2424    def test_slice_start_only_no_zero(self):
    2525        regions_start = [i*1000 for i in range(1, n_slices)]
    26         slice_source_at_stamps(self.source_file, regions_start, output_dir = self.output_dir)
     26        slice_source_at_stamps(self.source_file, regions_start,
     27                output_dir = self.output_dir, create_first=True)
    2728
    2829    def test_slice_start_beyond_end(self):
    2930        regions_start = [i*1000 for i in range(1, n_slices)]
    3031        regions_start += [count_samples_in_file(self.source_file) + 1000]
    31         slice_source_at_stamps(self.source_file, regions_start, output_dir = self.output_dir)
     32        slice_source_at_stamps(self.source_file, regions_start,
     33                output_dir = self.output_dir, create_first=True)
    3234
    3335    def test_slice_start_every_blocksize(self):
    3436        hopsize = 200
    35         regions_start = [i*hopsize for i in range(1, n_slices)]
     37        regions_start = [i*hopsize for i in range(0, n_slices)]
    3638        slice_source_at_stamps(self.source_file, regions_start, output_dir = self.output_dir,
    3739                hopsize = 200)
     40
     41    def test_slice_start_every_half_blocksize(self):
     42        hopsize = 200
     43        regions_start = [i*hopsize//2 for i in range(0, n_slices)]
     44        slice_source_at_stamps(self.source_file, regions_start,
     45                output_dir = self.output_dir, hopsize = 200)
    3846
    3947    def tearDown(self):
     
    92100            "number of samples written different from number of original samples")
    93101
     102    def test_slice_start_and_ends_with_missing_end(self):
     103        regions_start = [i*1000 for i in range(n_slices)]
     104        regions_ends = [r-1 for r in regions_start[1:]]
     105        slice_source_at_stamps(self.source_file, regions_start, regions_ends,
     106                output_dir = self.output_dir)
     107        written_samples = count_samples_in_directory(self.output_dir)
     108        original_samples = count_samples_in_file(self.source_file)
     109        total_files = count_files_in_directory(self.output_dir)
     110        assert_equal(n_slices, total_files,
     111            "number of slices created different from expected")
     112        assert_equal(written_samples, original_samples,
     113            "number of samples written different from number of original samples")
     114
    94115    def tearDown(self):
    95116        shutil.rmtree(self.output_dir)
     
    134155        regions_end = None
    135156        slice_source_at_stamps (self.source_file, regions_start, regions_end,
    136                 output_dir = self.output_dir)
     157                output_dir = self.output_dir, create_first=True)
    137158        total_files = count_files_in_directory(self.output_dir)
    138159        assert_equal(n_slices, total_files,
  • scripts/get_waf.sh

    r45c2c5c r088760e  
    22
    33set -e
    4 set -x
     4#set -x
    55
    66WAFVERSION=2.0.11
    77WAFTARBALL=waf-$WAFVERSION.tar.bz2
    88WAFURL=https://waf.io/$WAFTARBALL
     9WAFUPSTREAMKEY=https://gitlab.com/ita1024/waf/raw/master/utils/pubkey.asc
    910
    1011WAFBUILDDIR=`mktemp -d`
     
    1617trap cleanup SIGINT SIGTERM
    1718
     19function download () {
     20  ( [[ -n `which wget` ]] && wget -qO $1 $2 ) || ( [[ -n `which curl` ]] && curl -so $1 $2 )
     21}
     22
     23function checkwaf () {
     24  download $WAFTARBALL.asc $WAFURL.asc
     25  if [[ -z `which gpg` ]]
     26  then
     27    echo "Warning: gpg not found, not verifying signature for $WAFTARBALL"
     28  else
     29    download - $WAFUPSTREAMKEY | gpg --import
     30    gpg --verify $WAFTARBALL.asc || exit 1
     31  fi
     32}
     33
     34function fetchwaf () {
     35  download $WAFTARBALL $WAFURL
     36  checkwaf
     37}
     38
    1839function buildwaf () {
    19   pushd $WAFBUILDDIR
    20 
    21   ( which wget > /dev/null && wget -qO $WAFTARBALL $WAFURL ) || ( which curl > /dev/null && curl $WAFURL > $WAFTARBALL )
    22 
    2340  tar xf $WAFTARBALL
    2441  pushd waf-$WAFVERSION
    2542  NOCLIMB=1 python waf-light --tools=c_emscripten $*
    26 
    2743  popd
    28   popd
    29 
    30   cp -prv $WAFBUILDDIR/waf-$WAFVERSION/waf $PWD
    31 
    32   chmod +x waf
    3344}
    3445
     46pushd $WAFBUILDDIR
     47fetchwaf
    3548buildwaf
     49popd
     50
     51cp -prv $WAFBUILDDIR/waf-$WAFVERSION/waf $PWD
     52chmod +x waf
    3653
    3754cleanup
  • src/aubio_priv.h

    r45c2c5c r088760e  
    7171#endif
    7272
    73 #ifdef HAVE_ACCELERATE
     73#if defined(HAVE_ACCELERATE)
    7474#define HAVE_ATLAS 1
     75#define HAVE_BLAS 1
    7576#include <Accelerate/Accelerate.h>
    7677#elif defined(HAVE_ATLAS_CBLAS_H)
     78#elif defined(HAVE_BLAS)
     79#if defined(HAVE_ATLAS_CBLAS_H)
    7780#define HAVE_ATLAS 1
    7881#include <atlas/cblas.h>
    79 #else
    80 #undef HAVE_ATLAS
     82#elif defined(HAVE_OPENBLAS_CBLAS_H)
     83#include <openblas/cblas.h>
     84#elif defined(HAVE_CBLAS_H)
     85#include <cblas.h>
     86#endif
    8187#endif
    8288
     
    114120#endif /* HAVE_ACCELERATE */
    115121
     122#if defined(HAVE_BLAS)
     123#ifndef HAVE_AUBIO_DOUBLE
    116124#ifdef HAVE_ATLAS
    117 #ifndef HAVE_AUBIO_DOUBLE
    118125#define aubio_catlas_set      catlas_sset
     126#endif /* HAVE_ATLAS */
    119127#define aubio_cblas_copy      cblas_scopy
    120128#define aubio_cblas_swap      cblas_sswap
    121129#define aubio_cblas_dot       cblas_sdot
    122130#else /* HAVE_AUBIO_DOUBLE */
     131#ifdef HAVE_ATLAS
    123132#define aubio_catlas_set      catlas_dset
     133#endif /* HAVE_ATLAS */
    124134#define aubio_cblas_copy      cblas_dcopy
    125135#define aubio_cblas_swap      cblas_dswap
    126136#define aubio_cblas_dot       cblas_ddot
    127137#endif /* HAVE_AUBIO_DOUBLE */
    128 #endif /* HAVE_ATLAS */
     138#endif /* HAVE_BLAS */
    129139
    130140#if defined HAVE_INTEL_IPP
     
    161171#if !defined(HAVE_MEMCPY_HACKS) && !defined(HAVE_ACCELERATE) && !defined(HAVE_ATLAS) && !defined(HAVE_INTEL_IPP)
    162172#define HAVE_NOOPT 1
    163 #else
    164 #undef HAVE_NOOPT
    165173#endif
    166174
  • src/fmat.c

    r45c2c5c r088760e  
    161161  assert(s->length == scale->length);
    162162#endif
    163 #if !defined(HAVE_ACCELERATE) && !defined(HAVE_ATLAS)
     163#if !defined(HAVE_ACCELERATE) && !defined(HAVE_BLAS)
    164164  uint_t j;
    165165  fvec_zeros(output);
     
    170170    }
    171171  }
    172 #elif defined(HAVE_ATLAS)
     172#elif defined(HAVE_BLAS)
    173173  for (k = 0; k < s->height; k++) {
    174174    output->data[k] = aubio_cblas_dot( s->length, scale->data, 1, s->data[k], 1);
  • src/fvec.c

    r45c2c5c r088760e  
    135135#if defined(HAVE_INTEL_IPP)
    136136  aubio_ippsCopy(s->data, t->data, (int)s->length);
    137 #elif defined(HAVE_ATLAS)
     137#elif defined(HAVE_BLAS)
    138138  aubio_cblas_copy(s->length, s->data, 1, t->data, 1);
    139139#elif defined(HAVE_ACCELERATE)
  • src/io/source_avcodec.c

    r45c2c5c r088760e  
    3535// determine whether we use libavformat from ffmpeg or from libav
    3636#define FFMPEG_LIBAVFORMAT (LIBAVFORMAT_VERSION_MICRO > 99 )
    37 // max_analyze_duration2 was used from ffmpeg libavformat 55.43.100 through 57.2.100
     37// max_analyze_duration2 was used from ffmpeg libavformat 55.43.100 -> 57.2.100
    3838#define FFMPEG_LIBAVFORMAT_MAX_DUR2 FFMPEG_LIBAVFORMAT && ( \
    3939      (LIBAVFORMAT_VERSION_MAJOR == 55 && LIBAVFORMAT_VERSION_MINOR >= 43) \
     
    9393};
    9494
    95 // hack to create or re-create the context the first time _do or _do_multi is called
    96 void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi);
    97 void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_samples);
     95// create or re-create the context when _do or _do_multi is called
     96void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s,
     97    uint_t multi);
     98// actually read a frame
     99void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s,
     100    uint_t * read_samples);
    98101
    99102uint_t aubio_source_avcodec_has_network_url(aubio_source_avcodec_t *s);
     
    112115
    113116
    114 aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path, uint_t samplerate, uint_t hop_size) {
     117aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path,
     118    uint_t samplerate, uint_t hop_size) {
    115119  aubio_source_avcodec_t * s = AUBIO_NEW(aubio_source_avcodec_t);
    116120  AVFormatContext *avFormatCtx = s->avFormatCtx;
     
    129133  }
    130134  if ((sint_t)samplerate < 0) {
    131     AUBIO_ERR("source_avcodec: Can not open %s with samplerate %d\n", path, samplerate);
     135    AUBIO_ERR("source_avcodec: Can not open %s with samplerate %d\n",
     136        path, samplerate);
    132137    goto beach;
    133138  }
    134139  if ((sint_t)hop_size <= 0) {
    135     AUBIO_ERR("source_avcodec: Can not open %s with hop_size %d\n", path, hop_size);
     140    AUBIO_ERR("source_avcodec: Can not open %s with hop_size %d\n",
     141        path, hop_size);
    136142    goto beach;
    137143  }
     
    173179    char errorstr[256];
    174180    av_strerror (err, errorstr, sizeof(errorstr));
    175     AUBIO_ERR("source_avcodec: Could not find stream information " "for %s (%s)\n", s->path,
    176         errorstr);
     181    AUBIO_ERR("source_avcodec: Could not find stream information "
     182        "for %s (%s)\n", s->path, errorstr);
    177183    goto beach;
    178184  }
     
    214220  avCodecCtx = avcodec_alloc_context3(codec);
    215221  if (!avCodecCtx) {
    216     AUBIO_ERR("source_avcodec: Failed to allocate the %s codec context for path %s\n",
    217         av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path);
     222    AUBIO_ERR("source_avcodec: Failed to allocate the %s codec context "
     223        "for path %s\n", av_get_media_type_string(AVMEDIA_TYPE_AUDIO),
     224        s->path);
    218225    goto beach;
    219226  }
     
    230237  /* Copy codec parameters from input stream to output codec context */
    231238  if ((err = avcodec_parameters_to_context(avCodecCtx, codecpar)) < 0) {
    232     AUBIO_ERR("source_avcodec: Failed to copy %s codec parameters to decoder context for %s\n",
    233        av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path);
     239    AUBIO_ERR("source_avcodec: Failed to copy %s codec parameters to "
     240        "decoder context for %s\n",
     241        av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path);
    234242    goto beach;
    235243  }
     
    239247    char errorstr[256];
    240248    av_strerror (err, errorstr, sizeof(errorstr));
    241     AUBIO_ERR("source_avcodec: Could not load codec for %s (%s)\n", s->path, errorstr);
     249    AUBIO_ERR("source_avcodec: Could not load codec for %s (%s)\n", s->path,
     250        errorstr);
    242251    goto beach;
    243252  }
     
    266275
    267276  /* allocate output for avr */
    268   s->output = (smpl_t *)av_malloc(AUBIO_AVCODEC_MAX_BUFFER_SIZE * sizeof(smpl_t));
     277  s->output = (smpl_t *)av_malloc(AUBIO_AVCODEC_MAX_BUFFER_SIZE
     278      * sizeof(smpl_t));
    269279
    270280  s->read_samples = 0;
     
    294304}
    295305
    296 void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi) {
     306void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s,
     307    uint_t multi)
     308{
    297309  // create or reset resampler to/from mono/multi-channel
    298310  if ( (multi != s->multi) || (s->avr == NULL) ) {
     
    309321#endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
    310322
    311     av_opt_set_int(avr, "in_channel_layout",  input_layout,           0);
    312     av_opt_set_int(avr, "out_channel_layout", output_layout,          0);
    313     av_opt_set_int(avr, "in_sample_rate",     s->input_samplerate,    0);
    314     av_opt_set_int(avr, "out_sample_rate",    s->samplerate,          0);
     323    av_opt_set_int(avr, "in_channel_layout",  input_layout,              0);
     324    av_opt_set_int(avr, "out_channel_layout", output_layout,             0);
     325    av_opt_set_int(avr, "in_sample_rate",     s->input_samplerate,       0);
     326    av_opt_set_int(avr, "out_sample_rate",    s->samplerate,             0);
    315327    av_opt_set_int(avr, "in_sample_fmt",      s->avCodecCtx->sample_fmt, 0);
    316328#if HAVE_AUBIO_DOUBLE
    317     av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_DBL,      0);
    318 #else
    319     av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_FLT,      0);
     329    av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_DBL,         0);
     330#else
     331    av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_FLT,         0);
    320332#endif
    321333    // TODO: use planar?
     
    329341      char errorstr[256];
    330342      av_strerror (err, errorstr, sizeof(errorstr));
    331       AUBIO_ERR("source_avcodec: Could not open resampling context for %s (%s)\n",
    332           s->path, errorstr);
     343      AUBIO_ERR("source_avcodec: Could not open resampling context"
     344         " for %s (%s)\n", s->path, errorstr);
    333345      return;
    334346    }
     
    347359}
    348360
    349 void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_samples) {
     361void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s,
     362    uint_t * read_samples)
     363{
    350364  AVFormatContext *avFormatCtx = s->avFormatCtx;
    351365  AVCodecContext *avCodecCtx = s->avCodecCtx;
     
    388402      char errorstr[256];
    389403      av_strerror (err, errorstr, sizeof(errorstr));
    390       AUBIO_ERR("source_avcodec: could not read frame in %s (%s)\n", s->path, errorstr);
     404      AUBIO_ERR("source_avcodec: could not read frame in %s (%s)\n",
     405          s->path, errorstr);
    391406      s->eof = 1;
    392407      goto beach;
     
    406421  if (ret < 0) {
    407422    if (ret == AVERROR(EAGAIN)) {
    408       //AUBIO_WRN("source_avcodec: output is not available right now - user must try to send new input\n");
     423      //AUBIO_WRN("source_avcodec: output is not available right now - "
     424      //    "user must try to send new input\n");
    409425      goto beach;
    410426    } else if (ret == AVERROR_EOF) {
    411       AUBIO_WRN("source_avcodec: the decoder has been fully flushed, and there will be no more output frames\n");
     427      AUBIO_WRN("source_avcodec: the decoder has been fully flushed, "
     428          "and there will be no more output frames\n");
    412429    } else {
    413430      AUBIO_ERR("source_avcodec: decoding errors on %s\n", s->path);
     
    424441#endif
    425442  if (got_frame == 0) {
    426     AUBIO_WRN("source_avcodec: did not get a frame when reading %s\n", s->path);
     443    AUBIO_WRN("source_avcodec: did not get a frame when reading %s\n",
     444        s->path);
    427445    goto beach;
    428446  }
     
    431449  if (avFrame->channels != (sint_t)s->input_channels) {
    432450    AUBIO_WRN ("source_avcodec: trying to read from %d channel(s),"
    433         "but configured for %d; is '%s' corrupt?\n", avFrame->channels,
    434         s->input_channels, s->path);
    435     goto beach;
    436   }
     451        "but configured for %d; is '%s' corrupt?\n",
     452        avFrame->channels, s->input_channels, s->path);
     453    goto beach;
     454  }
     455#else
     456#warning "avutil < 53 is deprecated, crashes might occur on corrupt files"
    437457#endif
    438458
     
    455475#endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
    456476  if (out_samples <= 0) {
    457     AUBIO_WRN("source_avcodec: no sample found while converting frame (%s)\n", s->path);
     477    AUBIO_WRN("source_avcodec: no sample found while converting frame (%s)\n",
     478        s->path);
    458479    goto beach;
    459480  }
     
    473494}
    474495
    475 void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data, uint_t * read){
     496void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data,
     497    uint_t * read) {
    476498  uint_t i;
    477499  uint_t end = 0;
     
    505527}
    506528
    507 void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s, fmat_t * read_data, uint_t * read){
     529void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s,
     530    fmat_t * read_data, uint_t * read) {
    508531  uint_t i,j;
    509532  uint_t end = 0;
     
    551574
    552575uint_t aubio_source_avcodec_seek (aubio_source_avcodec_t * s, uint_t pos) {
    553   int64_t resampled_pos = (uint_t)ROUND(pos * (s->input_samplerate * 1. / s->samplerate));
     576  int64_t resampled_pos =
     577    (uint_t)ROUND(pos * (s->input_samplerate * 1. / s->samplerate));
    554578  int64_t min_ts = MAX(resampled_pos - 2000, 0);
    555579  int64_t max_ts = MIN(resampled_pos + 2000, INT64_MAX);
     
    559583    ret = AUBIO_OK;
    560584  } else {
    561     AUBIO_ERR("source_avcodec: failed seeking in %s (file not opened?)", s->path);
     585    AUBIO_ERR("source_avcodec: failed seeking in %s (file not opened?)",
     586        s->path);
    562587    return ret;
    563588  }
     
    570595      min_ts, resampled_pos, max_ts, seek_flags);
    571596  if (ret < 0) {
    572     AUBIO_ERR("source_avcodec: failed seeking to %d in file %s", pos, s->path);
     597    AUBIO_ERR("source_avcodec: failed seeking to %d in file %s",
     598        pos, s->path);
    573599  }
    574600  // reset read status
  • src/mathutils.c

    r45c2c5c r088760e  
    272272  // if length is odd, middle element is moved to the end
    273273  if (2 * half < s->length) start ++;
    274 #ifndef HAVE_ATLAS
     274#ifndef HAVE_BLAS
    275275  for (j = 0; j < half; j++) {
    276276    ELEM_SWAP (s->data[j], s->data[j + start]);
     
    292292  // if length is odd, middle element is moved to the beginning
    293293  if (2 * half < s->length) start ++;
    294 #ifndef HAVE_ATLAS
     294#ifndef HAVE_BLAS
    295295  for (j = 0; j < half; j++) {
    296296    ELEM_SWAP (s->data[j], s->data[j + start]);
     
    329329{
    330330  smpl_t energy = 0.;
    331 #ifndef HAVE_ATLAS
     331#ifndef HAVE_BLAS
    332332  uint_t j;
    333333  for (j = 0; j < f->length; j++) {
     
    523523  /* log(freq/A-2)/log(2) */
    524524  midi = freq / 6.875;
    525   midi = LOG (midi) / 0.69314718055995;
     525  midi = LOG (midi) / 0.6931471805599453;
    526526  midi *= 12;
    527527  midi -= 3;
     
    535535  if (midi > 140.) return 0.; // avoid infs
    536536  freq = (midi + 3.) / 12.;
    537   freq = EXP (freq * 0.69314718055995);
     537  freq = EXP (freq * 0.6931471805599453);
    538538  freq *= 6.875;
    539539  return freq;
  • src/notes/notes.c

    r45c2c5c r088760e  
    11/*
    2   Copyright (C) 2014 Paul Brossier <piem@aubio.org>
     2  Copyright (C) 2014-2018 Paul Brossier <piem@aubio.org>
    33
    44  This file is part of aubio.
     
    2626
    2727#define AUBIO_DEFAULT_NOTES_SILENCE -70.
     28#define AUBIO_DEFAULT_NOTES_RELEASE_DROP 10.
    2829// increase to 10. for .1  cent precision
    2930//      or to 100. for .01 cent precision
     
    5758
    5859  uint_t isready;
     60
     61  smpl_t last_onset_level;
     62  smpl_t release_drop_level;
    5963};
    6064
     
    102106  aubio_notes_set_minioi_ms (o, AUBIO_DEFAULT_NOTES_MINIOI_MS);
    103107
     108  o->last_onset_level = AUBIO_DEFAULT_NOTES_SILENCE;
     109  o->release_drop_level = AUBIO_DEFAULT_NOTES_RELEASE_DROP;
     110
    104111  return o;
    105112
     
    139146{
    140147  return aubio_onset_get_minioi_ms(o->onset);
     148}
     149
     150uint_t aubio_notes_set_release_drop(aubio_notes_t *o, smpl_t release_drop_level)
     151{
     152  uint_t err = AUBIO_OK;
     153  if (release_drop_level <= 0.) {
     154    AUBIO_ERR("notes: release_drop should be >= 0, got %f\n", release_drop_level);
     155    err = AUBIO_FAIL;
     156  } else {
     157    o->release_drop_level = release_drop_level;
     158  }
     159  return err;
     160}
     161
     162smpl_t aubio_notes_get_release_drop(const aubio_notes_t *o)
     163{
     164  return o->release_drop_level;
    141165}
    142166
     
    185209      //notes->data[0] = o->curnote;
    186210      //notes->data[1] = 0.;
     211      //AUBIO_WRN("notes: sending note-off at onset, not enough level\n");
    187212      notes->data[2] = o->curnote;
    188213    } else {
     
    192217        /* kill old note */
    193218        //send_noteon(o->curnote,0, o->samplerate);
     219        //AUBIO_WRN("notes: sending note-off at onset, new onset detected\n");
    194220        notes->data[2] = o->curnote;
    195221        /* get and send new one */
     
    199225        o->curnote = new_pitch;
    200226      }
     227      o->last_onset_level = curlevel;
    201228    }
    202229  } else {
    203     if (o->median) {
     230    if (curlevel < o->last_onset_level - o->release_drop_level)
     231    {
     232      // send note off
     233      //AUBIO_WRN("notes: sending note-off, release detected\n");
     234      notes->data[0] = 0;
     235      notes->data[1] = 0;
     236      notes->data[2] = o->curnote;
     237      // reset last_onset_level to silence_threshold
     238      o->last_onset_level = o->silence_threshold;
     239      o->curnote = 0;
     240    }
     241    else if (o->median)
     242    {
    204243      if (o->isready > 0)
    205244        o->isready++;
     
    208247        /* kill old note */
    209248        //send_noteon(curnote,0);
    210         notes->data[2] = o->curnote;
     249        if (o->curnote != 0)
     250        {
     251          //AUBIO_WRN("notes: sending note-off, new note detected\n");
     252          notes->data[2] = o->curnote;
     253        }
    211254        o->newnote = aubio_notes_get_latest_note(o);
    212255        o->curnote = o->newnote;
  • src/notes/notes.h

    r45c2c5c r088760e  
    107107uint_t aubio_notes_set_minioi_ms (aubio_notes_t *o, smpl_t minioi_ms);
    108108
     109/** get notes object release drop level, in dB
     110
     111  \param o notes detection object as returned by new_aubio_notes()
     112
     113  \return current release drop level, in dB
     114
     115 */
     116smpl_t aubio_notes_get_release_drop (const aubio_notes_t *o);
     117
     118/** set note release drop level, in dB
     119
     120  This function sets the release_drop_level parameter, in dB. When a new note
     121  is found, the current level in dB is measured. If the measured level drops
     122  under that initial level - release_drop_level, then a note-off will be
     123  emitted.
     124
     125  Defaults to `10`, in dB.
     126
     127  \note This parameter was added in version `0.4.8`. Results obtained with
     128  earlier versions can be reproduced by setting this value to `100`, so that
     129  note-off will not be played until the next note.
     130
     131  \param o notes detection object as returned by new_aubio_notes()
     132  \param release_drop new release drop level, in dB
     133
     134  \return 0 on success, non-zero otherwise
     135
     136*/
     137uint_t aubio_notes_set_release_drop (aubio_notes_t *o, smpl_t release_drop);
     138
    109139#ifdef __cplusplus
    110140}
  • src/spectral/filterbank_mel.h

    r45c2c5c r088760e  
    5959
    6060  The filter coefficients are built according to Malcolm Slaney's Auditory
    61   Toolbox, available at http://engineering.purdue.edu/~malcolm/interval/1998-010/
    62   (see file mfcc.m).
     61  Toolbox, available online at the following address (see file mfcc.m):
     62
     63  https://engineering.purdue.edu/~malcolm/interval/1998-010/
    6364
    6465*/
  • src/spectral/mfcc.c

    r45c2c5c r088760e  
    3232#include "spectral/mfcc.h"
    3333
    34 #undef HAVE_SLOW_DCT
     34#ifdef HAVE_NOOPT
     35#define HAVE_SLOW_DCT 1
     36#endif
    3537
    3638/** Internal structure for mfcc object */
  • src/spectral/mfcc.h

    r45c2c5c r088760e  
    2727
    2828  The implementation follows the specifications established by Malcolm Slaney
    29   in its Auditory Toolbox, available online (see file mfcc.m).
     29  in its Auditory Toolbox, available online at the following address (see
     30  file mfcc.m):
    3031
    31   http://engineering.ecn.purdue.edu/~malcolm/interval/1998-010/
     32  https://engineering.purdue.edu/~malcolm/interval/1998-010/
    3233
    3334  \example spectral/test-mfcc.c
  • src/spectral/phasevoc.c

    r45c2c5c r088760e  
    213213    synthold[i] += synth[i + pv->hop_s] * pv->scale;
    214214}
     215
     216uint_t aubio_pvoc_get_win(aubio_pvoc_t* pv)
     217{
     218  return pv->win_s;
     219}
     220
     221uint_t aubio_pvoc_get_hop(aubio_pvoc_t* pv)
     222{
     223  return pv->hop_s;
     224}
  • src/spectral/phasevoc.h

    r45c2c5c r088760e  
    8989*/
    9090uint_t aubio_pvoc_get_win(aubio_pvoc_t* pv);
     91
    9192/** get hop size
    9293
  • src/synth/wavetable.c

    r45c2c5c r088760e  
    165165  aubio_wavetable_set_amp (s, 0.);
    166166  //s->last_pos = 0;
    167   return aubio_wavetable_set_playing (s, 1);
     167  return aubio_wavetable_set_playing (s, 0);
    168168}
    169169
  • src/synth/wavetable.h

    r45c2c5c r088760e  
    5151*/
    5252aubio_wavetable_t * new_aubio_wavetable(uint_t samplerate, uint_t hop_size);
    53 
    54 /** load source in wavetable
    55 
    56   \param o wavetable, created by new_aubio_wavetable()
    57   \param uri the uri of the source to load
    58 
    59   \return 0 if successful, non-zero otherwise
    60 
    61 */
    62 uint_t aubio_wavetable_load( aubio_wavetable_t * o, const char_t * uri );
    6353
    6454/** process wavetable function
  • wscript

    r45c2c5c r088760e  
    8484            help_str = 'use CoreFoundation (darwin only) (auto)',
    8585            help_disable_str = 'do not use CoreFoundation framework')
     86    add_option_enable_disable(ctx, 'blas', default = False,
     87            help_str = 'use BLAS acceleration library (no)',
     88            help_disable_str = 'do not use BLAS library')
    8689    add_option_enable_disable(ctx, 'atlas', default = False,
    87             help_str = 'use Atlas library (no)',
    88             help_disable_str = 'do not use Atlas library')
     90            help_str = 'use ATLAS acceleration library (no)',
     91            help_disable_str = 'do not use ATLAS library')
    8992    add_option_enable_disable(ctx, 'wavread', default = True,
    9093            help_str = 'compile with source_wavread (default)',
     
    97100            help_str = 'build documentation (auto)',
    98101            help_disable_str = 'do not build documentation')
     102
     103    add_option_enable_disable(ctx, 'tests', default = True,
     104            help_str = 'build tests (true)',
     105            help_disable_str = 'do not build or run tests')
     106
     107    add_option_enable_disable(ctx, 'examples', default = True,
     108            help_str = 'build examples (true)',
     109            help_disable_str = 'do not build examples')
    99110
    100111    ctx.add_option('--with-target-platform', type='string',
     
    266277        ctx.env.LINKFLAGS_cshlib += ['-s', 'EXPORTED_FUNCTIONS=%s' % c_mangled_names]
    267278
    268     if (ctx.options.enable_atlas != True):
    269         ctx.options.enable_atlas = False
    270 
    271279    # check support for C99 __VA_ARGS__ macros
    272280    check_c99_varargs = '''
     
    419427    ctx.msg('Checking if using sink_wavwrite', ctx.options.enable_wavwrite and 'yes' or 'no')
    420428
    421     # use ATLAS
    422     if (ctx.options.enable_atlas != False):
    423         ctx.check(header_name = 'atlas/cblas.h', mandatory = ctx.options.enable_atlas)
    424         #ctx.check(lib = 'lapack', uselib_store = 'LAPACK', mandatory = ctx.options.enable_atlas)
    425         ctx.check(lib = 'cblas', uselib_store = 'BLAS', mandatory = ctx.options.enable_atlas)
     429    # use BLAS/ATLAS
     430    if (ctx.options.enable_blas != False):
     431        ctx.check_cfg(package = 'blas',
     432                args = '--cflags --libs',
     433                uselib_store='BLAS', mandatory = ctx.options.enable_blas)
     434        if 'LIB_BLAS' in ctx.env:
     435            blas_header = None
     436            if ctx.env['LIBPATH_BLAS']:
     437                if 'atlas' in ctx.env['LIBPATH_BLAS'][0]:
     438                    blas_header = 'atlas/cblas.h'
     439                elif 'openblas' in ctx.env['LIBPATH_BLAS'][0]:
     440                    blas_header = 'openblas/cblas.h'
     441            else:
     442                blas_header = 'cblas.h'
     443            ctx.check(header_name = blas_header, mandatory =
     444                    ctx.options.enable_atlas)
    426445
    427446    # use memcpy hacks
     
    474493        if bld.env['DEST_OS']=='emscripten' and not bld.options.testcmd:
    475494            bld.options.testcmd = 'node %s'
    476         bld.recurse('examples')
    477         bld.recurse('tests')
     495        if bld.options.enable_examples:
     496            bld.recurse('examples')
     497        if bld.options.enable_tests:
     498            bld.recurse('tests')
    478499
    479500    # pkg-config template
     
    585606    ctx.excl += ' **/.landscape.yml'
    586607    ctx.excl += ' **/.appveyor.yml'
    587     ctx.excl += ' **/circlei.yml'
     608    ctx.excl += ' **/.circleci/*'
     609    ctx.excl += ' **/azure-pipelines.yml'
     610    ctx.excl += ' **/.coveragerc'
Note: See TracChangeset for help on using the changeset viewer.