Changes in / [086a45b:f2f1b10]


Ignore:
Files:
32 added
14 deleted
159 edited

Legend:

Unmodified
Added
Removed
  • .appveyor.yml

    r086a45b rf2f1b10  
    88    # pre-installed python version, see:
    99    # http://www.appveyor.com/docs/installed-software#python
    10     - PYTHONDIR: "C:\\Python27"
    11       PYTHON_VERSION: "2.7.x"
    12       PYTHON_ARCH: "32"
     10    - PYTHONDIR: C:\Python27
     11      PYTHON_VERSION: 2.7.x
     12      PYTHON_ARCH: 32
    1313
    14     - PYTHONDIR: "C:\\Python27-x64"
    15       PYTHON_VERSION: "2.7.x"
    16       PYTHON_ARCH: "64"
     14    - PYTHONDIR: C:\Python27-x64
     15      PYTHON_VERSION: 2.7.x
     16      PYTHON_ARCH: 64
    1717
    18     - PYTHONDIR: "C:\\Python34"
    19       PYTHON_VERSION: "3.4.x"
    20       PYTHON_ARCH: "32"
     18    - PYTHONDIR: C:\Python35
     19      PYTHON_VERSION: 3.5.x
     20      PYTHON_ARCH: 32
    2121
    22     - PYTHONDIR: "C:\\Python34-x64"
    23       PYTHON_VERSION: "3.4.x"
    24       PYTHON_ARCH: "64"
     22    - PYTHONDIR: C:\Python35-x64
     23      PYTHON_VERSION: 3.5.x
     24      PYTHON_ARCH: 64
    2525
    26     - PYTHONDIR: "C:\\Python35"
    27       PYTHON_VERSION: "3.5.x"
    28       PYTHON_ARCH: "32"
     26    - PYTHONDIR: C:\Python36
     27      PYTHON_VERSION: 3.6.x
     28      PYTHON_ARCH: 32
    2929
    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"
     30    - PYTHONDIR: C:\Python36-x64
     31      PYTHON_VERSION: 3.6.x
     32      PYTHON_ARCH: 64
     33
     34    - PYTHONDIR: C:\Python37
     35      PYTHON_VERSION: 3.7.x
     36      PYTHON_ARCH: 32
     37
     38    - PYTHONDIR: C:\Python37-x64
     39      PYTHON_VERSION: 3.7.x
     40      PYTHON_ARCH: 64
    3541
    3642install:
    37 
    3843  - ECHO "Installed SDKs:"
    3944  - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
    4045
     46  - "SET PATH=%PYTHONDIR%;%PYTHONDIR%\\Scripts;%PATH%"
     47
    4148  # 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)\""
     49  - "python --version"
     50  - "python -c \"import struct; print(struct.calcsize('P') * 8)\""
     51
     52  - "python -m pip install --disable-pip-version-check --user --upgrade pip"
     53  - "python -m pip install --upgrade setuptools"
    4454
    4555  # We need wheel installed to build wheels
    46   - "%PYTHONDIR%\\python.exe -m pip install wheel"
     56  - "python -m pip install wheel"
    4757
    48   - "SET PATH=%PATH_EXTRAS%;%PYTHONDIR%;%PYTHONDIR%\\Scripts;%PATH%"
    49 
    50   - "pip install --disable-pip-version-check --user --upgrade pip"
    51   - "pip install --upgrade setuptools"
     58  - "pip install -r requirements.txt"
    5259
    5360before_build:
     
    5562
    5663build_script:
    57   # build python module without using libaubio
    58   - "pip install -r requirements.txt"
    59   - "python setup.py build"
    60   - "pip install ."
     64  # also build libaubio with waf
     65  - python waf configure build install --verbose --msvc_version="msvc 14.0"
     66  # clean before building python package
     67  - python waf distclean
     68  # build, upload and install wheel (inspired by numpy's appveyor)
     69  - ps: |
     70      pip wheel -v -v -v --wheel-dir=dist .
     71      ls dist -r | Foreach-Object {
     72          Push-AppveyorArtifact $_.FullName
     73          pip install $_.FullName
     74      }
     75
     76test_script:
    6177  - "python python\\demos\\demo_create_test_sounds.py"
    62   - "nose2 --verbose"
    63   # clean up
    64   - "python waf distclean"
    65   # build libaubio
    66   - python waf configure build --verbose --msvc_version="msvc 14.0"
     78  - "pytest --verbose"
  • .gitignore

    r086a45b rf2f1b10  
    66*.gcno
    77*.gcda
     8python/lib/aubio/_aubio.*.so
     9.coverage
    810
    911# ignore compiled examples
     
    4446aubio-*.zip
    4547dist/*.tar.gz
     48dist/*.whl
    4649
    4750# test sounds
    4851python/tests/sounds
    4952aubio.egg-info
     53.eggs
     54.cache
  • .travis.yml

    r086a45b rf2f1b10  
    33matrix:
    44  include:
     5    - python: 3.6
     6      os: linux
     7      compiler: gcc
    58    - python: 3.5
    69      os: linux
    710      compiler: gcc
    8     - python: 3.4
    9       os: linux
    10       compiler: gcc
     11      env: WAFOPTS="--build-type=debug"
    1112    - python: 2.7
    1213      os: linux
    1314      compiler: gcc
    14     - language: C
    15       os: osx
    16       osx_image: xcode8
    17       compiler: clang
    18     - python: 3.5
     15    - python: "pypy3.5"
    1916      os: linux
    2017      compiler: gcc
    21       env: CFLAGS="-Os" WAFOPTS="--disable-samplerate --disable-sndfile"
    22     - python: 3.4
     18      env: CFLAGS="-Os" WAFOPTS="--disable-avcodec"
     19    - python: 3.6
     20      os: linux
     21      compiler: gcc
     22      env: CFLAGS="-Os" WAFOPTS="--disable-samplerate"
     23    - python: 3.5
    2324      os: linux
    2425      compiler: gcc
     
    3031    - language: C
    3132      os: osx
    32       osx_image: xcode8
     33      compiler: clang
     34    - language: C
     35      os: osx
    3336      compiler: clang
    3437      env: CFLAGS="-Os" HAVE_AUBIO_DOUBLE=1 WAFOPTS="--disable-accelerate"
    3538    - language: C
    3639      os: osx
    37       osx_image: xcode8
    3840      compiler: clang
    3941      env: WAFOPTS="--enable-fat --disable-avcodec --disable-sndfile"
    4042    - language: C
    4143      os: osx
    42       osx_image: xcode8
    4344      compiler: clang
    4445      env: WAFOPTS="--with-target-platform=ios --disable-avcodec --disable-sndfile" AUBIO_NOTESTS=1
    4546    - language: C
    4647      os: osx
    47       osx_image: xcode8
    48       compiler: clang
    49       env: WAFOPTS="--with-target-platform=iosimulator --disable-avcodec --disable-sndfile" AUBIO_NOTESTS=1
    50     - language: C
    51       os: osx
    52       osx_image: xcode8.2
    53       compiler: clang
    54       env: WAFOPTS="--enable-fat --disable-avcodec --disable-sndfile"
    55     - language: C
    56       os: osx
    57       osx_image: xcode8.2
    58       compiler: clang
    59       env: WAFOPTS="--with-target-platform=ios --disable-avcodec --disable-sndfile" AUBIO_NOTESTS=1
    60     - language: C
    61       os: osx
    62       osx_image: xcode8.2
    6348      compiler: clang
    6449      env: WAFOPTS="--with-target-platform=iosimulator --disable-avcodec --disable-sndfile" AUBIO_NOTESTS=1
     
    8368    - sox
    8469    - lcov
     70  homebrew:
     71    packages:
     72    - sox
     73    - ffmpeg
     74    - libsndfile
     75    - lcov
     76    #update: true
    8577
    8678before_install:
    8779   - |
    8880     if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
    89        brew update
    90        brew install sox
    91        brew install ffmpeg
    92        brew install libsndfile
    93        brew install lcov
    9481       export PATH="$HOME/Library/Python/2.7/bin/:$PATH"
    9582     fi;
    9683
    9784install:
     85  - |
     86    if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
     87      alias pip=pip2
     88    fi;
    9889  - travis_retry pip install --upgrade pip
    9990  - travis_retry make getwaf expandwaf deps_python
    10091  - which pip
    10192  - pip --version
    102   - pip install python-coveralls
    103   - gem install coveralls-lcov
     93  - pip install coverage
    10494
    10595script:
     
    116106  - |
    117107    if [[ -z "$AUBIO_NOTESTS" ]]; then
    118       # upload lcov coverage to coveralls.io
    119       coveralls-lcov build/coverage.info
    120       # upload python coverage
    121       #coveralls
    122108      # upload to codecov
    123109      bash <(curl -s https://codecov.io/bash)
  • ChangeLog

    r086a45b rf2f1b10  
     12018-12-19 Paul Brossier <piem@aubio.org>
     2
     3        [ Overview ]
     4
     5        * VERSION: bump to 0.4.9
     6        * library: improve stability, fixing potential crashes and memory leaks on
     7        invalid arguments; improve library messages and reporting of system errors
     8        * tests/: major clean-up, check return codes, increase code coverage
     9        * python/tests/: switch to pytest (closes gh-163), check emitted warnings
     10        * python/: add pages to manual with brief descriptions of classes
     11
     12        [ Fixes ]
     13
     14        * security: improve arguments validation in new_aubio_filterbank (prevent
     15        possible null-pointer dereference on invalid n_filters, CVE-2018-19801),
     16        new_aubio-tempo (prevent possible buffer overflow, CVE-2018-19800), and
     17        new_aubio_onset (prevent null-pointer dereference, CVE-2018-19802). Thanks
     18        to Guoxiang Niu (@niugx), from the EaglEye Team for reporting these issues.
     19        * tempo: fix delay_ms methods
     20        * filterbank: fix aubio_filterbank_get_power (thanks to @romanbsd who
     21        also noticed this issue)
     22        * dct: creation fail on negative sizes or invalid accelerate radix,
     23        fix typo in error and warning messages, prevent possible memory leak
     24        * pitch: prevent null pointer dereference in yinfast, comment out unused
     25        functions in mcomb and yin, prevent possible leak in specacf
     26        * mfcc: always use dct module, strengthen input validation, change
     27        get_{scale,power} to return smpl_t
     28        * specdesc: improve error message
     29        * notes: prevent null pointer dereference
     30        * hist: add validation for size argument, prevent possible leak
     31        * awhitening: use shortest length available (closes gh-216)
     32        * io: add macros to display system errors, add helpers to validate input
     33        arguments of source and sink methods, always clean-up after failure
     34        * source: validate input sizes to prevent invalid reads
     35        * apple_audio: use native format conversions in source and sink, prevent
     36        possible apple_audio crash on empty string, get_duration returns 0 on failure
     37        * ffmpeg/avcodec: prevent deprecation warnings, read after close, and skipped
     38        samples warnings, improve warning messages, only show a warning when
     39        swr_convert failed, prevent possible memory leak when closing swr context
     40        * wavwrite: copy to all channels if needed, check fseek and fwrite return
     41        values, call fflush in open to return failure on full disk-system
     42        * source_sndfile: fix reading sizes when resampling, set error message when
     43        reading after close
     44        * aubio_priv.h: include blas first (see gh-225), add STRERROR macros
     45
     46        [ Python ]
     47
     48        * documentation: add pages to manual, add minimal docstrings for fft,
     49        digital_filter, and generated objects, improve specdesc documentation
     50        * filterbank: add get_norm/power documentation
     51        * source: take a copy of the last frame before resizing it, raise an
     52        exception when read failed, fix compilation warning
     53        * fixes: remove unneeded check convert with PyFloat_FromDouble or
     54        PyFloat_FromDouble, check if sink, digital_filter, were created before
     55        deleting
     56
     57        [ Tests ]
     58
     59        * python/tests/: switch to pytest (slightly slower than nose2 but better at
     60        capturing warnings and parametrization), improve coding style and coverage.
     61        Tests should now be run with `pytest`.
     62        * tests/: Each test program in C must now return 0, otherwise the test will
     63        fail. Examples have been modified to run themselves on a test audio file,
     64        but can still be run with arguments. Tests for `source` and `sink` have been
     65        factorised, and some code cleaning. A python script is used to create a
     66        test sound file. Tested on linux, macos, and windows, improvements to
     67        test-mfcc (closes gh-219).
     68
     69        [ Build system ]
     70
     71        * waf: upgrade to 2.0.14, check the return code of each test program,
     72        update rules to build manual and api documentation into build/, check
     73        for errno.h
     74        * osx: use -Os in scripts/build_apple_frameworks
     75        * Makefile: improve coverage reports
     76        * appveyor, travis, circleci: switch to pytest, set one travis config to use
     77        sndfile only
     78        * travis: add py3.6, drop py3.4, use py3.5 to test debug mode
     79        * azure: add basic configuration
     80
     812018-11-21 Paul Brossier <piem@aubio.org>
     82
     83        [ Overview ]
     84
     85        * VERSION: bump to 0.4.8
     86        * notes: new option release_drop (gh-203)
     87        * spectral: new parameters added to filterbank and mfcc (gh-206)
     88        * python: start documenting module (gh-73, debian #480018), improve build for
     89        win-amd64 (gh-154, gh-199, gh-208)
     90        * fixes: prevent crash when using fft sizes unsupported by vDSP (gh-207),
     91        prevent saturation when down-mixing a multi-channel source (avcodec/ffmpeg)
     92
     93        [ Fixes ]
     94
     95        * avcodec: prevent saturation when down-mixing a multi-channel source, emit
     96        a warning if compiling against avutil < 53 (gh-137), wrap long lines
     97        * examples/: avoid hiding global and unreachable code
     98        * fft: limit to r*2*n sizes, with r in [1, 3, 5, 15] (vDSP only) (gh-207)
     99        * fft: fix reconstruction for odd sizes (fftw only)
     100        * pvoc: add missing implementations for aubio_pvoc_get_hop/win
     101        * mathutils: increase ln(2) precision of in freqtomidi/miditofreq
     102        * wavetable: stop sets playing to 0, add dummy implementation for _load
     103
     104        [ New features ]
     105
     106        * src/musicutils.h: new aubio_meltohz, aubio_hztomel, with _htk versions
     107        * src/spectral/filterbank.h: new set_mel_coeffs, set_mel_coeffs_htk,
     108        set_power, and set_norm methods, improved set_triangle_bands
     109        * src/spectral/mfcc.h: new set_scale, set_power, set_norm, set_mel_coeffs,
     110        set_mel_coeffs_htk, set_mel_coeffs_slaney
     111        * src/mathutils.h: new fvec_mul
     112        * src/notes: new option release_drop to prevent missing note-offs (gh-203)
     113
     114        [ Python module ]
     115
     116        * fix: rounding to nearest integer in midi2note and freq2note
     117        * general: supports code generation of setters with none or multiple
     118        parameters
     119        * documentation: add docstrings do fvec, cvec, source, sink, pvoc, frequency
     120        conversion and level detection routines (gh-73, debian #480018)
     121        * slicing: improve and document slice_source_at_stamps
     122        * module: new note2freq function, recover error log when raising exceptions
     123        on failed set_ methods, prevent cyclic import, coding style improvements
     124        * demos: improve coding style, fix bpm_extract arguments
     125        * MANIFEST.in: exclude *.pyc, improve patterns
     126
     127        [ Documentation ]
     128
     129        * doc/: use sphinx autodoc to load docstrings from aubio module, reorganize
     130        python module documentation, add a note about double precision, use https
     131        when possible
     132        * src/spectral/: update Auditory Toolbox url, update copyright year
     133
     134        [ Tools ]
     135
     136        * aubionotes: add --release-drop option
     137        * aubio: add --release-drop and --silence options to `aubio notes`,
     138        workaround for -V to really show version (py2)
     139        * aubiocut: add option --create-first to always create first slice
     140
     141        [ Tests ]
     142
     143        * tests/, python/tests: add tests for new methods, check source channel
     144        down-mix, improve coverage
     145
     146        [ Build system ]
     147
     148        * Makefile: disable docs when measuring coverage, add branch coverage
     149        option, add coverage_zero_counters target, improve html report
     150        * waf: update to 2.0.12, improve wscript style, prevent shipping some
     151        generated files
     152        * python: always show compiler warnings when pre-processing headers,
     153        workaround to fix code generation for win-amd64 (gh-154, gh-199, gh-208).
     154        * continuous integration: add azure pipelines, update and improve
     155        configurations for appveyor, circleci, and travis.
     156
     1572018-09-22 Paul Brossier <piem@aubio.org>
     158
     159        [ Overview ]
     160
     161        * VERSION: bump to 0.4.7
     162        * src/spectral/dct.h: add dct type II object with optimised versions
     163        * src/io/, src/notes/, src/pitch: prevent crashes on corrupted files
     164        * examples/: fix jack midi output, improve messages when jack disabled
     165        * python/: add dct support, minor bug fixes tests and demos
     166        * wscript: improve support for BLAS/ATLAS
     167
     168        [ Library fixes ]
     169
     170        * src/pitch/pitchyinfft.c: fix out of bound read when samplerate > 50kHz
     171        thanks to @fCorleone (closes #189, CVE-2018-14523, debian #904906)
     172        * src/notes/notes.c: bail out if pitch creation failed (see #188)
     173        * src/io/source_wavread.c:
     174         - also exit if samplerate is negative (closes #188, CVE-2018-14522,
     175         debian #904907)
     176         - add some input validation (closes #148 and #158, CVE-2017-17054,
     177         debian #883355)
     178        * src/io/source_avcodec.c:
     179         - give up if resampling context failed opening (see #137, closes #187,
     180         CVE-2018-14521, debian #904908)
     181         - give up reading file if number of channel changes during stream (closes
     182         #137, CVE-2017-17554, debian #884237)
     183         - make sure libavutil > 52 before checking avFrame->channels (see #137)
     184         - fix build with ffmpeg 4.0, thanks to @jcowgill (closes #168, #173)
     185         - avoid deprecated call for ffmpeg >= 4.0
     186        * src/onset/onset.c: add dummy default parameters for wphase (closes #150)
     187
     188        [ Tools ]
     189
     190        * examples/parse_args.h: hide jack options if not available, improve error
     191        message (closes #182)
     192        * examples/utils.h: process_block returns void
     193        * examples/utils.c: fix examples failing to send more than one JACK midi
     194        event per frame, thanks to @cyclopsian (closes #201)
     195
     196        [ New features ]
     197
     198        * src/spectral/dct.h: add dct type II object with implementation factory
     199        * src/spectral/dct_plain.c: add plain dct implementation
     200        * src/spectral/dct_ooura.c: add ooura implementation
     201        * src/spectral/dct_fftw.c: add fftw implementation
     202        * src/spectral/dct_ipp.c: add ipp version
     203        * src/spectral/dct_accelerate.c: add vdsp/accelerate dct
     204        * tests/src/spectral/test-dct.c: check reconstruction works
     205        * src/spectral/mfcc.c: use new dct to compute mfcc
     206
     207        [ Library internals ]
     208
     209        * src/aubio_priv.h: avoid hard-coded undefs, split BLAS and ATLAS support,
     210        add vdsp scalar add and multiply
     211
     212        [ Build system ]
     213
     214        * wscript:
     215         - add options to disable examples and tests
     216         - detect includes for openblas/libblas/atlas
     217        * scripts/get_waf.sh: bump to 2.0.11, verify signature if gpg available
     218        * python/lib/gen_external.py: pass '-x c' to emcc only
     219
     220        [ Python ]
     221
     222        * python/lib/gen_code.py: add support for rdo methods
     223        * python/tests/test_dct.py: add tests for new dct
     224        * python/demos/demo_pitch_sinusoid.py: use // to yield an integer, fixing
     225        demo on py3, thanks to @ancorcruz (closes #176)
     226        * python/ext/py-musicutils.*: add shift(fvec) and ishift(fvec)
     227        * python/tests/test_fvec_shift.py: add tests for shift() and ishift()
     228        * python/lib/aubio/cmd.py: fix typo in comment
     229
     230        [ Documentation ]
     231
     232        * README.md, doc/statuslinks.rst: use latest for commits-since
     233        * examples/parse_args.h: add yinfast to pitch algorithms
     234        * doc/requirements.rst: add some blas documentation
     235        * doc/requirements.rst: split media/optimisation libraries
     236        * doc/develop.rst: fixed spelling error, thanks to Jon Williams (closes #161)
     237        * doc/aubio{pitch,notes}.txt: add yinfast to list of pitch methods
     238
     239        [ Continuous integration ]
     240
     241        * .travis.yml: remove xcode8.2 builds, group osx, add alias pip=pip2
     242        * .appveyor.yml: upgrade pip first, always use python -m pip
     243
    12442017-10-02 Paul Brossier <piem@aubio.org>
    2245
  • MANIFEST.in

    r086a45b rf2f1b10  
    22include python/README.md
    33include this_version.py
     4include waf_gensyms.py
     5include waf
     6recursive-include waflib *.py
    47include Makefile wscript */wscript_build
    5 include waf waflib/* waflib/*/*
    6 exclude waflib/__pycache__/*
    78include aubio.pc.in
    8 include nose2.cfg
    99include requirements.txt
    1010include src/*.c src/*.h
    1111include src/*/*.c src/*/*.h
    1212include examples/*.c examples/*.h
    13 include tests/*.h tests/*/*.c tests/*/*/*.c
     13recursive-include tests *.h *.c *.py
    1414include python/ext/*.h
    15 include python/__init__.py
    16 include python/lib/__init__.py
    17 include python/lib/moresetuptools.py
    18 include python/lib/gen_external.py
    19 include python/lib/gen_code.py
    20 include python/tests/run_all_tests
    21 include python/tests/*.py
     15recursive-include python *.py
     16include python/README.md
    2217include python/tests/eval_pitch
    23 include python/demos/*.py
    2418include python/tests/*.expected
    2519include doc/*.txt doc/*.rst doc/*.cfg doc/Makefile doc/make.bat doc/conf.py
  • Makefile

    r086a45b rf2f1b10  
    3636MANDIR?=$(DATAROOTDIR)/man
    3737
    38 # default nose2 command
    39 NOSE2?=nose2 -N 4 --verbose
     38# default python test command
     39PYTEST?=pytest --verbose
    4040
    4141SOX=sox
    4242
    4343TESTSOUNDS := python/tests/sounds
     44
     45LCOVOPTS += --rc lcov_branch_coverage=1
    4446
    4547all: build
     
    139141test_python: local_dylib
    140142        # run test with installed package
    141         # ./python/tests/run_all_tests --verbose
    142         # run with nose2, multiple processes
    143         $(NOSE2)
     143        $(PYTEST)
    144144
    145145clean_python:
     
    235235        check_clean_python
    236236
     237coverage_cycle: coverage_zero_counters coverage_report
     238
     239coverage_zero_counters:
     240        lcov --zerocounters --directory .
     241
    237242coverage: export CFLAGS=--coverage
    238243coverage: export LDFLAGS=--coverage
     
    241246coverage: force_uninstall_python deps_python \
    242247        clean_python clean distclean build local_dylib
    243         lcov --capture --no-external --directory . --output-file build/coverage_lib.info
     248        # capture coverage after running c tests
     249        lcov $(LCOVOPTS) --capture --no-external --directory . \
     250                --output-file build/coverage_lib.info
     251        # build and test python
    244252        pip install -v -e .
    245         coverage run `which nose2`
    246         lcov --capture --no-external --directory . --output-file build/coverage_python.info
    247         lcov -a build/coverage_python.info -a build/coverage_lib.info -o build/coverage.info
    248 
     253        # run tests, with python coverage
     254        coverage run `which pytest`
     255        # capture coverage again
     256        lcov $(LCOVOPTS) --capture --no-external --directory . \
     257                --output-file build/coverage_python.info
     258        # merge both coverage info files
     259        lcov $(LCOVOPTS) -a build/coverage_python.info -a build/coverage_lib.info \
     260                --output-file build/coverage.info
     261        # remove tests
     262        lcov $(LCOVOPTS) --remove build/coverage.info '*/ooura_fft8g*' \
     263                --output-file build/coverage_lib.info
     264
     265# make sure we don't build the doc, which builds a temporary python module
     266coverage_report: export WAFOPTS += --disable-docs
    249267coverage_report: coverage
    250         genhtml build/coverage.info --output-directory lcov_html
    251         mkdir -p gcovr_html/
    252         gcovr -r . --html --html-details \
    253                 --output gcovr_html/index.html \
    254                 --exclude ".*tests/.*" --exclude ".*examples/.*"
     268        # generate report with lcov's genhtml
     269        genhtml build/coverage_lib.info --output-directory build/coverage_c \
     270                --branch-coverage --highlight --legend
     271        # generate python report with coverage python package
    255272        coverage report
    256         coverage html
     273        coverage html -d build/coverage_python
     274        # show links to generated reports
     275        for i in $$(ls build/coverage_*/index.html); do echo file://$(PWD)/$$i; done
    257276
    258277sphinx: configure
  • README.md

    r086a45b rf2f1b10  
    44[![Travis build status](https://travis-ci.org/aubio/aubio.svg?branch=master)](https://travis-ci.org/aubio/aubio "Travis build status")
    55[![Appveyor build status](https://img.shields.io/appveyor/ci/piem/aubio/master.svg)](https://ci.appveyor.com/project/piem/aubio "Appveyor build status")
    6 [![Landscape code health](https://landscape.io/github/aubio/aubio/master/landscape.svg?style=flat)](https://landscape.io/github/aubio/aubio/master "Landscape code health")
    7 [![Commits since last release](https://img.shields.io/github/commits-since/aubio/aubio/0.4.6.svg)](https://github.com/aubio/aubio "Commits since last release")
     6[![Commits since last release](https://img.shields.io/github/commits-since/aubio/aubio/latest.svg)](https://github.com/aubio/aubio "Commits since last release")
    87
    98[![Documentation](https://readthedocs.org/projects/aubio/badge/?version=latest)](http://aubio.readthedocs.io/en/latest/?badge=latest "Latest documentation")
  • VERSION

    r086a45b rf2f1b10  
    11AUBIO_MAJOR_VERSION=0
    2 AUBIO_MINOR_VERSION=4
    3 AUBIO_PATCH_VERSION=7
     2AUBIO_MINOR_VERSION=5
     3AUBIO_PATCH_VERSION=0
    44AUBIO_VERSION_STATUS='~alpha'
    55LIBAUBIO_LT_CUR=5
    6 LIBAUBIO_LT_REV=3
    7 LIBAUBIO_LT_AGE=7
     6LIBAUBIO_LT_REV=4
     7LIBAUBIO_LT_AGE=8
  • doc/about.rst

    r086a45b rf2f1b10  
    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

    r086a45b rf2f1b10  
    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/aubiocut.txt

    r086a45b rf2f1b10  
    5151  each slice (default 0).
    5252
     53  --create-first  Alway create first slice.
     54
    5355  -h, --help  Print a short help message and exit.
    5456
  • doc/aubiomfcc.txt

    r086a45b rf2f1b10  
    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

    r086a45b rf2f1b10  
    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

    r086a45b rf2f1b10  
    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

    r086a45b rf2f1b10  
    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

    r086a45b rf2f1b10  
    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/develop.rst

    r086a45b rf2f1b10  
    11.. _develop:
    22
    3 Developping with aubio
    4 ======================
     3Developing with aubio
     4=====================
    55
    66Here is a brief overview of the C library.
  • doc/index.rst

    r086a45b rf2f1b10  
    7171   installing
    7272   python_module
     73   python
    7374   cli
    7475   develop
  • doc/installing.rst

    r086a45b rf2f1b10  
    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

    r086a45b rf2f1b10  
    1 .. _python:
     1.. _python-install:
    22
    3 Python module
    4 =============
     3Installing aubio for Python
     4===========================
    55
    6 The aubio extension for Python is available for Python 2.7 and Python 3.
     6aubio is available as a package for Python 2.7 and Python 3. The aubio
     7extension is written C using the `Python/C`_ and the `Numpy/C`_ APIs.
     8
     9.. _Python/C: https://docs.python.org/c-api/index.html
     10.. _Numpy/C: https://docs.scipy.org/doc/numpy/reference/c-api.html
     11
     12For general documentation on how to install Python packages, see `Installing
     13Packages`_.
    714
    815Installing aubio with pip
    916-------------------------
    1017
    11 aubio can now be installed using ``pip``:
     18aubio can be installed from `PyPI`_ using ``pip``:
    1219
    13 .. code-block:: bash
     20.. code-block:: console
    1421
    1522    $ pip install aubio
    1623
    17 Building the module
    18 -------------------
     24See also `Installing from PyPI`_ for general documentation.
    1925
    20 From ``aubio`` source directory, run the following:
     26.. note::
    2127
    22 .. code-block:: bash
     28  aubio is currently a `source only`_ package, so you will need a compiler to
     29  install it from `PyPI`_. See also `Installing aubio with conda`_ for
     30  pre-compiled binaries.
     31
     32.. _PyPI: https://pypi.python.org/pypi/aubio
     33.. _Installing Packages: https://packaging.python.org/tutorials/installing-packages/
     34.. _Installing from PyPI: https://packaging.python.org/tutorials/installing-packages/#installing-from-pypi
     35.. _source only: https://packaging.python.org/tutorials/installing-packages/#source-distributions-vs-wheels
     36
     37Installing aubio with conda
     38---------------------------
     39
     40`Conda packages`_ are available through the `conda-forge`_ channel for Linux,
     41macOS, and Windows:
     42
     43.. code-block:: console
     44
     45    $ conda config --add channels conda-forge
     46    $ conda install -c conda-forge aubio
     47
     48.. _Conda packages: https://anaconda.org/conda-forge/aubio
     49.. _conda-forge: https://conda-forge.org/
     50
     51.. _py-doubleprecision:
     52
     53Double precision
     54----------------
     55
     56This module can be compiled in double-precision mode, in which case the
     57default type for floating-point samples will be 64-bit. The default is
     58single precision mode (32-bit, recommended).
     59
     60To build the aubio module with double precision, use the option
     61`--enable-double` of the `build_ext` subcommand:
     62
     63.. code:: bash
    2364
    2465    $ ./setup.py clean
    25     $ ./setup.py build
    26     $ sudo ./setup.py install
     66    $ ./setup.py build_ext --enable-double
     67    $ pip install -v .
    2768
    28 Using aubio in python
    29 ---------------------
     69**Note**: If linking against `libaubio`, make sure the library was also
     70compiled in :ref:`doubleprecision` mode.
    3071
    31 Once you have python-aubio installed, you should be able to run ``python -c
    32 "import aubio; print(aubio.version)"``.
    3372
    34 A simple example
    35 ................
     73Checking your installation
     74--------------------------
    3675
    37 Here is a :download:`simple script <../python/demos/demo_source_simple.py>`
    38 that reads all the samples from a media file:
     76Once the python module is installed, its version can be checked with:
    3977
    40 .. literalinclude:: ../python/demos/demo_source_simple.py
    41    :language: python
     78.. code-block:: console
    4279
    43 Filtering an input sound file
    44 .............................
     80    $ python -c "import aubio; print(aubio.version, aubio.float_type)"
    4581
    46 Here is a more complete example, :download:`demo_filter.py
    47 <../python/demos/demo_filter.py>`. This files executes the following:
     82The command line `aubio` is also installed:
    4883
    49 * read an input media file (``aubio.source``)
     84.. code-block:: console
    5085
    51 * filter it using an `A-weighting <https://en.wikipedia.org/wiki/A-weighting>`_
    52   filter (``aubio.digital_filter``)
     86    $ aubio -h
    5387
    54 * write result to a new file (``aubio.sink``)
    55 
    56 .. literalinclude:: ../python/demos/demo_filter.py
    57    :language: python
    58 
    59 More demos
    60 ..........
    61 
    62 Check out the `python demos folder`_ for more examples.
    6388
    6489Python tests
    6590------------
    6691
    67 A number of `python tests`_ are provided. To run them, use
    68 ``python/tests/run_all_tests``.
     92A number of Python tests are provided in the `python/tests`_ folder. To run
     93them, install `pytest`_ and run it from the aubio source directory:
    6994
    70 .. _python demos folder: https://github.com/aubio/aubio/blob/master/python/demos
    71 .. _demo_filter.py: https://github.com/aubio/aubio/blob/master/python/demos/demo_filter.py
    72 .. _python tests: https://github.com/aubio/aubio/blob/master/python/tests
     95.. code-block:: console
    7396
     97    $ pip install pytest
     98    $ git clone https://git.aubio.org/aubio/aubio
     99    $ cd aubio
     100    $ pytest
     101
     102.. _python/tests: https://github.com/aubio/aubio/blob/master/python/tests
     103.. _pytest: https://pytest.org
  • doc/requirements.rst

    r086a45b rf2f1b10  
    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................
    202304
     305The datatype used to store real numbers in aubio is named `smpl_t`. By default,
     306`smpl_t` is defined as `float`, a `single-precision format
     307<https://en.wikipedia.org/wiki/Single-precision_floating-point_format>`_
     308(32-bit).  Some algorithms require a floating point representation with a
     309higher precision, for instance to prevent arithmetic underflow in recursive
     310filters.  In aubio, these special samples are named `lsmp_t` and defined as
     311`double` by default (64-bit).
     312
     313Sometimes it may be useful to compile aubio in `double-precision`, for instance
     314to reproduce numerical results obtained with 64-bit routines. In this case,
     315`smpl_t` will be defined as `double`.
     316
     317The following table shows how `smpl_t` and `lsmp_t` are defined in single- and
     318double-precision modes:
     319
     320.. list-table:: Single and double-precision modes
     321   :align: center
     322
     323   * -
     324     - single
     325     - double
     326   * - `smpl_t`
     327     - ``float``
     328     - ``double``
     329   * - `lsmp_t`
     330     - ``double``
     331     - ``long double``
     332
    203333To compile aubio in double precision mode, configure with ``--enable-double``.
    204334
    205 To compile aubio in single precision mode, use ``--disable-double`` (default).
     335To compile in single-precision mode (default), use ``--disable-double`` (or
     336simply none of these two options).
    206337
    207338Disabling the tests
  • doc/statuslinks.rst

    r086a45b rf2f1b10  
    1010   :alt: Appveyor build status
    1111
    12 .. image:: https://landscape.io/github/aubio/aubio/master/landscape.svg?style=flat
    13    :target: https://landscape.io/github/aubio/aubio/master
    14    :alt: Landscape code health
    15 
    1612.. image:: https://readthedocs.org/projects/aubio/badge/?version=latest
    1713   :target: https://aubio.readthedocs.io/en/latest/?badge=latest
    1814   :alt: Documentation status
    1915
    20 .. image:: https://img.shields.io/github/commits-since/aubio/aubio/0.4.6.svg?maxAge=2592000
     16.. image:: https://img.shields.io/github/commits-since/aubio/aubio/latest.svg
    2117   :target: https://github.com/aubio/aubio
    2218   :alt: Commits since last release
  • examples/aubiomfcc.c

    r086a45b rf2f1b10  
    6969  }
    7070
    71   examples_common_process((aubio_process_func_t)process_block, process_print);
     71  examples_common_process(process_block, process_print);
    7272
    7373  del_aubio_pvoc (pv);
  • examples/aubionotes.c

    r086a45b rf2f1b10  
    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
    86   examples_common_process((aubio_process_func_t)process_block, process_print);
     93  examples_common_process(process_block, process_print);
    8794
    8895  // send a last note off if required
  • examples/aubioonset.c

    r086a45b rf2f1b10  
    8787  //aubio_sampler_load (sampler, "/archives/sounds/woodblock.aiff");
    8888
    89   examples_common_process((aubio_process_func_t)process_block, process_print);
     89  examples_common_process(process_block, process_print);
    9090
    9191  // send a last note off
  • examples/aubiopitch.c

    r086a45b rf2f1b10  
    8080  aubio_wavetable_play ( wavetable );
    8181
    82   examples_common_process((aubio_process_func_t)process_block,process_print);
     82  examples_common_process(process_block, process_print);
    8383
    8484  del_aubio_pitch (o);
  • examples/aubioquiet.c

    r086a45b rf2f1b10  
    5656  verbmsg ("buffer_size: %d, ", buffer_size);
    5757  verbmsg ("hop_size: %d\n", hop_size);
    58   examples_common_process((aubio_process_func_t)process_block,process_print);
     58  examples_common_process(process_block, process_print);
    5959  examples_common_del();
    6060  return 0;
  • examples/aubiotrack.c

    r086a45b rf2f1b10  
    8888  //aubio_sampler_load (sampler, "/archives/sounds/woodblock.aiff");
    8989
    90   examples_common_process((aubio_process_func_t)process_block,process_print);
     90  examples_common_process(process_block, process_print);
    9191
    9292  // send a last note off
  • examples/parse_args.h

    r086a45b rf2f1b10  
    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"
     
    116121      "                 do not fail if output file already exists\n"
    117122#endif /* PROG_HAS_OUTPUT */
    118 #ifdef PROG_HAS_JACK
     123#if defined(PROG_HAS_JACK) && defined(HAVE_JACK)
    119124      "       -j      --jack             use Jack\n"
    120125#if defined(PROG_HAS_ONSET) && !defined(PROG_HAS_PITCH)
     
    122127      "       -V      --miditap-velo     MIDI velocity; default=65.\n"
    123128#endif /* defined(PROG_HAS_ONSET) && !defined(PROG_HAS_PITCH) */
    124 #endif /* PROG_HAS_JACK */
     129#endif /* defined(PROG_HAS_JACK) && defined(HAVE_JACK) */
    125130      "       -v      --verbose          be verbose\n"
    126131      "       -h      --help             display this message\n"
     
    157162#ifdef PROG_HAS_SILENCE
    158163    "s:"
     164#endif /* PROG_HAS_SILENCE */
     165#ifdef PROG_HAS_NOTES
     166    "d:"
    159167#endif /* PROG_HAS_SILENCE */
    160168#ifdef PROG_HAS_OUTPUT
     
    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 {
     
    275286        silence_threshold = (smpl_t) atof (optarg);
    276287        break;
     288      case 'd':                /* release-drop threshold */
     289        release_drop = (smpl_t) atof (optarg);
     290        break;
    277291      case 'm':                /* mix_input flag */
    278292        mix_input = 1;
     
    314328#else
    315329    errmsg("Error: no arguments given (and no available audio input)\n");
    316     usage ( stderr, 1 );
     330    errmsg("       consider recompiling with jack support (--enable-jack)\n");
     331    exit ( 1 );
    317332#endif /* HAVE_JACK */
    318333#else
  • examples/utils.c

    r086a45b rf2f1b10  
    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++;
     
    184185
    185186    del_aubio_source (this_source);
    186     del_aubio_sink   (this_sink);
     187    if (this_sink)
     188      del_aubio_sink   (this_sink);
    187189
    188190  }
     
    194196#ifdef HAVE_JACK
    195197  if (usejack) {
     198    ev.buffer = midi_data + midi_event_count++ * MAX_MIDI_EVENT_SIZE;
     199    if (midi_event_count >= MAX_MIDI_EVENTS) {
     200      midi_event_count = 0;
     201    }
    196202    ev.buffer[2] = velo;
    197203    ev.buffer[1] = pitch;
  • examples/utils.h

    r086a45b rf2f1b10  
    6767
    6868/** common process function */
    69 typedef int (*aubio_process_func_t) (fvec_t * input, fvec_t * output);
     69typedef void (*aubio_process_func_t) (fvec_t * input, fvec_t * output);
    7070
    7171void process_block (fvec_t *ibuf, fvec_t *obuf);
  • python/README.md

    r086a45b rf2f1b10  
    1 Python aubio module
    2 ===================
     1aubio
     2=====
    33
    4 This module wraps the aubio library for Python using the numpy module.
     4aubio is a collection of tools for music and audio analysis.
    55
    6 Using the Python aubio module
    7 -----------------------------
     6This package integrates the aubio library with [NumPy] to provide a set of
     7efficient tools to process and analyse audio signals, including:
    88
    9 After installing python-aubio, you will be able to import the aubio module:
     9- read audio from any media file, including videos and remote streams
     10- high quality phase vocoder, spectral filterbanks, and linear filters
     11- Mel-Frequency Cepstrum Coefficients and standard spectral descriptors
     12- detection of note attacks (onset)
     13- pitch tracking (fundamental frequency estimation)
     14- beat detection and tempo tracking
    1015
    11     $ python
    12     [...]
    13     >>> import aubio
    14     >>> help(aubio.miditofreq)
     16aubio works with both Python 2 and Python 3.
    1517
    16 Finding some inspiration
    17 ------------------------
     18Links
     19-----
    1820
    19 Some examples are available in the `python/demos` directory. These scripts are
    20 small programs written in python and using python-aubio.
     21- [module documentation][doc_python]
     22- [installation instructions][doc_python_install]
     23- [aubio manual][manual]
     24- [aubio homepage][homepage]
     25- [issue tracker][bugtracker]
    2126
    22 For instance, `demo_source.py` reads a media file.
     27Demos
     28-----
    2329
    24     $ ./python/demos/demo_source.py /path/to/sound/sample.wav
     30Some examples are available in the [`python/demos` folder][demos_dir]. Each
     31script is a command line program which accepts one ore more argument.
    2532
    26 and `demo_timestretch_online.py` stretches the original file into a new one:
     33**Notes**: installing additional modules is required to run some of the demos.
    2734
    28     $ ./python/demo/demo_timestretch_online.py loop.wav stretched_loop.wav 0.92`
     35### Analysis
    2936
    30 Note: you might need to install additional modules to run some of the demos.
    31 Some demos use [matplotlib](http://matplotlib.org/) to draw plots, others use
    32 [PySoundCard](https://github.com/bastibe/PySoundCard) to play and record
    33 sounds.
     37- `demo_source.py` uses aubio to read audio samples from media files
     38- `demo_onset_plot.py` detects attacks in a sound file and plots the results
     39  using [matplotlib]
     40- `demo_pitch.py` looks for fundamental frequency in a sound file and plots the
     41  results using [matplotlib]
     42- `demo_spectrogram.py`, `demo_specdesc.py`, `demo_mfcc.py` for spectral
     43  analysis.
    3444
    35 Testing the Python module
    36 -------------------------
     45### Real-time
    3746
    38 Python tests are in `python/tests` and use the [nose2 python package][nose2].
     47- `demo_pyaudio.py` and `demo_tapthebeat.py` use [pyaudio]
     48- `demo_pysoundcard_play.py`, `demo_pysoundcard.py` use [PySoundCard]
     49- `demo_alsa.py` uses [pyalsaaudio]
    3950
    40 To run the all the python tests, use the script:
     51### Others
    4152
    42     $ ./python/tests/run_all_tests
     53- `demo_timestretch.py` can change the duration of an input file and write the
     54  new sound to disk,
     55- `demo_wav2midi.py` detects the notes in a file and uses [mido] to write the
     56  results into a MIDI file
    4357
    44 Each test script can also be called one at a time. For instance:
     58### Example
    4559
    46     $ ./python/tests/test_note2midi.py -v
     60Use `demo_timestretch_online.py` to slow down `loop.wav`, write the results in
     61`stretched_loop.wav`:
    4762
    48 [nose2]: https://github.com/nose-devs/nose2
     63    $ python demo_timestretch_online.py loop.wav stretched_loop.wav 0.92
    4964
    50 Install in a virtualenv
    51 -----------------------
    52 
    53 You should be able to install python-aubio directly from the top source
    54 directory of aubio.
    55 
    56 First, create a virtualenv to hold the required python module:
    57 
    58     $ virtualenv pyaubio
    59     $ source pyaubio/bin/activate
    60 
    61 Now install and build the python extension using:
    62 
    63     $ pip install .
    64 
    65 Install requirements
    66 --------------------
    67 
    68 Before compiling this module, you must have compiled libaubio.
    69 
    70 A simple way to do this is with pip:
    71 
    72     $ pip install -r requirements.txt
    73 
    74 For more information about how this module works, please refer to the [Python/C
    75 API Reference Manual] (http://docs.python.org/c-api/index.html) and the
    76 [Numpy/C API Reference](http://docs.scipy.org/doc/numpy/reference/c-api.html).
    77 
    78 Compiling python aubio
    79 ----------------------
    80 
    81 To build the aubio Python module, run the following command from the top source
    82 directory of aubio:
    83 
    84     $ ./setup.py build
    85 
    86 Note: if libaubio was previously built using waf, the script will use it.
    87 Otherwise, the entire library will be built inside the python extension.
    88 
    89 To find out more about `setup.py` options:
    90 
    91     $ ./setup.py --help
    92 
    93 Installing
     65Built with
    9466----------
    9567
    96 To install the Python module:
     68The core of aubio is written in C for portability and speed. In addition to
     69[NumPy], aubio can be optionally built to use one or more of the following
     70libraries:
    9771
    98     $ ./setup.py install
     72- media file reading:
    9973
    100 Alternatively, you may want to use the Python module without installing it by
    101 setting your PYTHONPATH, for instance as follows:
     74    - [ffmpeg] / [avcodec] to decode and read audio from almost any format,
     75    - [libsndfile] to read audio from uncompressed sound files,
     76    - [libsamplerate] to re-sample audio signals,
     77    - [CoreAudio] to read all media formats supported by macOS, iOS, and tvOS.
    10278
    103     $ export PYTHONPATH=$PYTHONPATH:$PWD/`ls -rtd build/lib.* | head -1`:$PWD/tests
     79- hardware acceleration:
    10480
     81    - [Atlas] and [Blas], for accelerated vector and matrix computations,
     82    - [fftw3], to compute fast Fourier Transforms of any size,
     83    - [Accelerate] for accelerated FFT and matrix computations (macOS/iOS),
     84    - [Intel IPP], accelerated vector computation and FFT implementation.
     85
     86[ffmpeg]: https://ffmpeg.org
     87[avcodec]: https://libav.org
     88[libsndfile]: http://www.mega-nerd.com/libsndfile/
     89[libsamplerate]: http://www.mega-nerd.com/SRC/
     90[CoreAudio]: https://developer.apple.com/reference/coreaudio
     91[Atlas]: http://math-atlas.sourceforge.net/
     92[Blas]: https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms
     93[fftw3]: http://fftw.org
     94[Accelerate]: https://developer.apple.com/reference/accelerate
     95[Intel IPP]: https://software.intel.com/en-us/intel-ipp
     96
     97[demos_dir]:https://github.com/aubio/aubio/tree/master/python/demos
     98[pyaudio]:https://people.csail.mit.edu/hubert/pyaudio/
     99[PySoundCard]:https://github.com/bastibe/PySoundCard
     100[pyalsaaudio]:https://larsimmisch.github.io/pyalsaaudio/
     101[mido]:https://mido.readthedocs.io
     102
     103[manual]: https://aubio.org/manual/latest/
     104[doc_python]: https://aubio.org/manual/latest/python.html
     105[doc_python_install]: https://aubio.org/manual/latest/python_module.html
     106[homepage]: https://aubio.org
     107[NumPy]: https://www.numpy.org
     108[bugtracker]: https://github.com/aubio/aubio/issues
     109[matplotlib]:https://matplotlib.org/
  • python/demos/demo_bpm_extract.py

    r086a45b rf2f1b10  
    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

    r086a45b rf2f1b10  
    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
    77
     8def apply_filter(path, target):
    89    # open input file, get its samplerate
    9     s = source(path)
     10    s = aubio.source(path)
    1011    samplerate = s.samplerate
    1112
    1213    # create an A-weighting filter
    13     f = digital_filter(7)
     14    f = aubio.digital_filter(7)
    1415    f.set_a_weighting(samplerate)
    15     # alternatively, apply another filter
    1616
    1717    # create output file
    18     o = sink("filtered_" + splitext(basename(path))[0] + ".wav", samplerate)
     18    o = aubio.sink(target, samplerate)
    1919
    2020    total_frames = 0
    2121    while True:
     22        # read from source
    2223        samples, read = s()
     24        # filter samples
    2325        filtered_samples = f(samples)
     26        # write to sink
    2427        o(filtered_samples, read)
     28        # count frames read
    2529        total_frames += read
    26         if read < s.hop_size: break
     30        # end of file reached
     31        if read < s.hop_size:
     32            break
    2733
     34    # print some info
    2835    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))
     36    input_str = "input: {:s} ({:.2f} s, {:d} Hz)"
     37    output_str = "output: {:s}, A-weighting filtered ({:d} frames total)"
     38    print(input_str.format(s.uri, duration, samplerate))
     39    print(output_str.format(o.uri, total_frames))
    3240
    3341if __name__ == '__main__':
    34     import sys
    35     for f in sys.argv[1:]:
    36         apply_filter(f)
     42    usage = "{:s} <input_file> [output_file]".format(sys.argv[0])
     43    if not 1 < len(sys.argv) < 4:
     44        print(usage)
     45        sys.exit(1)
     46    if len(sys.argv) < 3:
     47        input_path = sys.argv[1]
     48        basename = os.path.splitext(os.path.basename(input_path))[0] + ".wav"
     49        output_path = "filtered_" + basename
     50    else:
     51        input_path, output_path = sys.argv[1:]
     52    # run function
     53    apply_filter(input_path, output_path)
  • python/demos/demo_filterbank.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from aubio import filterbank, fvec
    4 from pylab import loglog, show, xlim, ylim, xlabel, ylabel, title
    5 from numpy import vstack, arange
     3"""Create a filterbank from a list of frequencies.
    64
     5This demo uses `aubio.filterbank.set_triangle_bands` to build a set of
     6triangular filters from a list of frequencies.
     7
     8The filterbank coefficients are then modified before being displayed."""
     9
     10import aubio
     11import numpy as np
     12import matplotlib.pyplot as plt
     13
     14# sampling rate and size of the fft
     15samplerate = 48000
    716win_s = 2048
    8 samplerate = 48000
    917
     18# define a list of custom frequency
    1019freq_list = [60, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 24000]
     20# number of filters to create
    1121n_filters = len(freq_list) - 2
    1222
    13 f = filterbank(n_filters, win_s)
    14 freqs = fvec(freq_list)
     23# create a new filterbank
     24f = aubio.filterbank(n_filters, win_s)
     25freqs = aubio.fvec(freq_list)
    1526f.set_triangle_bands(freqs, samplerate)
    1627
     28# get the coefficients from the filterbank
    1729coeffs = f.get_coeffs()
    18 coeffs[4] *= 5.
    19 
     30# apply a gain to fifth band
     31coeffs[4] *= 6.
     32# load the modified coeffs into the filterbank
    2033f.set_coeffs(coeffs)
    2134
    22 times = vstack([arange(win_s // 2 + 1) * samplerate / win_s] * n_filters)
    23 title('Bank of filters built using a simple list of boundaries\nThe middle band has been amplified by 2.')
    24 loglog(times.T, f.get_coeffs().T, '.-')
    25 xlim([50, samplerate/2])
    26 ylim([1.0e-6, 2.0e-2])
    27 xlabel('log frequency (Hz)')
    28 ylabel('log amplitude')
    29 
    30 show()
     35# display the band gains in a loglog plot
     36freqs = np.vstack([np.arange(win_s // 2 + 1) * samplerate / win_s] * n_filters)
     37plt.title('filterbank built from a list of frequencies\n'
     38          'The 5th band has been amplified by a factor 6.')
     39plt.loglog(freqs.T, f.get_coeffs().T, '.-')
     40plt.xlim([50, samplerate/2])
     41plt.ylim([1.0e-6, 2.0e-2])
     42plt.xlabel('log frequency (Hz)')
     43plt.ylabel('log amplitude')
     44plt.show()
  • python/demos/demo_pitch_sinusoid.py

    r086a45b rf2f1b10  
    3838pointer += partition
    3939pointer += partition
    40 freqs[ pointer : pointer + partition ] = 400 + 5 * np.random.random(sin_length/8)
     40freqs[ pointer : pointer + partition ] = 400 + 5 * np.random.random(sin_length//8)
    4141
    4242a = build_sinusoid(sin_length, freqs, samplerate)
  • python/demos/demo_source_simple.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    2 import sys, aubio
     2
     3"""A simple example using aubio.source."""
     4
     5import sys
     6import aubio
    37
    48samplerate = 0  # use original source samplerate
    5 hop_size = 256 # number of frames to read in one block
    6 s = aubio.source(sys.argv[1], samplerate, hop_size)
     9hop_size = 256  # number of frames to read in one block
     10src = aubio.source(sys.argv[1], samplerate, hop_size)
    711total_frames = 0
    812
    9 while True: # reading loop
    10     samples, read = s()
    11     total_frames += read
    12     if read < hop_size: break # end of file reached
     13while True:
     14    samples, read = src()  # read hop_size new samples from source
     15    total_frames += read   # increment total number of frames
     16    if read < hop_size:    # end of file reached
     17        break
    1318
    1419fmt_string = "read {:d} frames at {:d}Hz from {:s}"
    15 print (fmt_string.format(total_frames, s.samplerate, sys.argv[1]))
    16 
     20print(fmt_string.format(total_frames, src.samplerate, src.uri))
  • python/demos/demo_wav2midi.py

    r086a45b rf2f1b10  
    6464        if new_note[2] > 0:
    6565            track.append(Message('note_off', note=int(new_note[2]),
    66                 velocity=127, time=0)
     66                velocity=127, time=delta)
    6767                )
    6868        track.append(Message('note_on',
  • python/ext/aubio-types.h

    r086a45b rf2f1b10  
    22#include <structmember.h>
    33
     4#include "aubio-docstrings.h"
    45#include "aubio-generated.h"
    56
  • python/ext/aubiomodule.c

    r086a45b rf2f1b10  
    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 );
     
    104224
    105225  // compute the function
    106   result = Py_BuildValue (AUBIO_NPY_SMPL_CHR, fvec_alpha_norm (&vec, alpha));
     226  result = PyFloat_FromDouble(fvec_alpha_norm (&vec, alpha));
    107227  if (result == NULL) {
    108228    return NULL;
     
    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  }
     
    192320
    193321  // compute the function
    194   result = Py_BuildValue (AUBIO_NPY_SMPL_CHR, aubio_zero_crossing_rate (&vec));
     322  result = PyFloat_FromDouble(aubio_zero_crossing_rate (&vec));
    195323  if (result == NULL) {
    196324    return NULL;
     
    243371  {"level_detection", Py_aubio_level_detection, METH_VARARGS, Py_aubio_level_detection_doc},
    244372  {"window", Py_aubio_window, METH_VARARGS, Py_aubio_window_doc},
     373  {"shift", Py_aubio_shift, METH_VARARGS, Py_aubio_shift_doc},
     374  {"ishift", Py_aubio_ishift, METH_VARARGS, Py_aubio_ishift_doc},
     375  {"hztomel", Py_aubio_hztomel, METH_VARARGS|METH_KEYWORDS, Py_aubio_hztomel_doc},
     376  {"meltohz", Py_aubio_meltohz, METH_VARARGS|METH_KEYWORDS, Py_aubio_meltohz_doc},
     377  {"hztomel_htk", Py_aubio_hztomel_htk, METH_VARARGS, Py_aubio_hztomel_htk_doc},
     378  {"meltohz_htk", Py_aubio_meltohz_htk, METH_VARARGS, Py_aubio_meltohz_htk_doc},
    245379  {NULL, NULL, 0, NULL} /* Sentinel */
    246380};
  • python/ext/py-cvec.c

    r086a45b rf2f1b10  
    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
     
    107137  }
    108138
    109   args = Py_BuildValue ("I", self->length);
     139  args = PyLong_FromLong(self->length);
    110140  if (args == NULL) {
    111141    goto fail;
     
    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-fft.c

    r086a45b rf2f1b10  
    11#include "aubio-types.h"
    22
    3 static char Py_fft_doc[] = "fft object";
     3static char Py_fft_doc[] = ""
     4"fft(size=1024)\n"
     5"\n"
     6"Compute Fast Fourier Transorms.\n"
     7"\n"
     8"Parameters\n"
     9"----------\n"
     10"size : int\n"
     11"    size of the FFT to compute\n"
     12"\n"
     13"Example\n"
     14"-------\n"
     15">>> x = aubio.fvec(512)\n"
     16">>> f = aubio.fft(512)\n"
     17">>> c = f(x); c\n"
     18"aubio cvec of 257 elements\n"
     19">>> x2 = f.rdo(c); x2.shape\n"
     20"(512,)\n"
     21"";
    422
    523typedef struct
  • python/ext/py-filter.c

    r086a45b rf2f1b10  
    1111} Py_filter;
    1212
    13 static char Py_filter_doc[] = "filter object";
     13static char Py_filter_doc[] = ""
     14"digital_filter(order=7)\n"
     15"\n"
     16"Create a digital filter.\n"
     17"";
     18
     19static char Py_filter_set_c_weighting_doc[] = ""
     20"set_c_weighting(samplerate)\n"
     21"\n"
     22"Set filter coefficients to C-weighting.\n"
     23"\n"
     24"`samplerate` should be one of 8000, 11025, 16000, 22050, 24000, 32000,\n"
     25"44100, 48000, 88200, 96000, or 192000. `order` of the filter should be 5.\n"
     26"\n"
     27"Parameters\n"
     28"----------\n"
     29"samplerate : int\n"
     30"    Sampling-rate of the input signal, in Hz.\n"
     31"";
     32
     33static char Py_filter_set_a_weighting_doc[] = ""
     34"set_a_weighting(samplerate)\n"
     35"\n"
     36"Set filter coefficients to A-weighting.\n"
     37"\n"
     38"`samplerate` should be one of 8000, 11025, 16000, 22050, 24000, 32000,\n"
     39"44100, 48000, 88200, 96000, or 192000. `order` of the filter should be 7.\n"
     40"\n"
     41"Parameters\n"
     42"----------\n"
     43"samplerate : int\n"
     44"    Sampling-rate of the input signal.\n"
     45"";
     46
     47static char Py_filter_set_biquad_doc[] = ""
     48"set_biquad(b0, b1, b2, a1, a2)\n"
     49"\n"
     50"Set biquad coefficients. `order` of the filter should be 3.\n"
     51"\n"
     52"Parameters\n"
     53"----------\n"
     54"b0 : float\n"
     55"    Forward filter coefficient.\n"
     56"b1 : float\n"
     57"    Forward filter coefficient.\n"
     58"b2 : float\n"
     59"    Forward filter coefficient.\n"
     60"a1 : float\n"
     61"    Feedback filter coefficient.\n"
     62"a2 : float\n"
     63"    Feedback filter coefficient.\n"
     64"";
    1465
    1566static PyObject *
     
    59110{
    60111  Py_XDECREF(self->out);
    61   del_aubio_filter (self->o);
     112  if (self->o)
     113    del_aubio_filter (self->o);
    62114  Py_TYPE(self)->tp_free ((PyObject *) self);
    63115}
     
    157209static PyMethodDef Py_filter_methods[] = {
    158210  {"set_c_weighting", (PyCFunction) Py_filter_set_c_weighting, METH_VARARGS,
    159       "set filter coefficients to C-weighting"},
     211      Py_filter_set_c_weighting_doc},
    160212  {"set_a_weighting", (PyCFunction) Py_filter_set_a_weighting, METH_VARARGS,
    161       "set filter coefficients to A-weighting"},
     213      Py_filter_set_a_weighting_doc},
    162214  {"set_biquad", (PyCFunction) Py_filter_set_biquad, METH_VARARGS,
    163       "set b0, b1, b2, a1, a2 biquad coefficients"},
     215      Py_filter_set_biquad_doc},
    164216  {NULL}
    165217};
  • python/ext/py-filterbank.c

    r086a45b rf2f1b10  
    11#include "aubio-types.h"
    22
    3 static char Py_filterbank_doc[] = "filterbank object";
     3static char Py_filterbank_doc[] = ""
     4"filterbank(n_filters=40, win_s=1024)\n"
     5"\n"
     6"Create a bank of spectral filters. Each instance is a callable\n"
     7"that holds a matrix of coefficients.\n"
     8"\n"
     9"See also :meth:`set_mel_coeffs`, :meth:`set_mel_coeffs_htk`,\n"
     10":meth:`set_mel_coeffs_slaney`, :meth:`set_triangle_bands`, and\n"
     11":meth:`set_coeffs`.\n"
     12"\n"
     13"Parameters\n"
     14"----------\n"
     15"n_filters : int\n"
     16"    Number of filters to create.\n"
     17"win_s : int\n"
     18"    Size of the input spectrum to process.\n"
     19"\n"
     20"Examples\n"
     21"--------\n"
     22">>> f = aubio.filterbank(128, 1024)\n"
     23">>> f.set_mel_coeffs(44100, 0, 10000)\n"
     24">>> c = aubio.cvec(1024)\n"
     25">>> f(c).shape\n"
     26"(128, )\n"
     27"";
     28
     29static char Py_filterbank_set_triangle_bands_doc[] =""
     30"set_triangle_bands(freqs, samplerate)\n"
     31"\n"
     32"Set triangular bands. The coefficients will be set to triangular\n"
     33"overlapping windows using the boundaries specified by `freqs`.\n"
     34"\n"
     35"`freqs` should contain `n_filters + 2` frequencies in Hz, ordered\n"
     36"by value, from smallest to largest. The first element should be greater\n"
     37"or equal to zero; the last element should be smaller or equal to\n"
     38"`samplerate / 2`.\n"
     39"\n"
     40"Parameters\n"
     41"----------\n"
     42"freqs: fvec\n"
     43"    List of frequencies, in Hz.\n"
     44"samplerate : float\n"
     45"    Sampling-rate of the expected input.\n"
     46"\n"
     47"Example\n"
     48"-------\n"
     49">>> fb = aubio.filterbank(n_filters=100, win_s=2048)\n"
     50">>> samplerate = 44100; freqs = np.linspace(0, 20200, 102)\n"
     51">>> fb.set_triangle_bands(aubio.fvec(freqs), samplerate)\n"
     52"";
     53
     54static char Py_filterbank_set_mel_coeffs_slaney_doc[] = ""
     55"set_mel_coeffs_slaney(samplerate)\n"
     56"\n"
     57"Set coefficients of filterbank to match Slaney's Auditory Toolbox.\n"
     58"\n"
     59"The filter coefficients will be set as in Malcolm Slaney's\n"
     60"implementation. The filterbank should have been created with\n"
     61"`n_filters = 40`.\n"
     62"\n"
     63"This is approximately equivalent to using :meth:`set_mel_coeffs` with\n"
     64"`fmin = 400./3., fmax = 6853.84`.\n"
     65"\n"
     66"Parameters\n"
     67"----------\n"
     68"samplerate : float\n"
     69"    Sampling-rate of the expected input.\n"
     70"\n"
     71"References\n"
     72"----------\n"
     73"\n"
     74"Malcolm Slaney, `Auditory Toolbox Version 2, Technical Report #1998-010\n"
     75"<https://engineering.purdue.edu/~malcolm/interval/1998-010/>`_\n"
     76"";
     77
     78static char Py_filterbank_set_mel_coeffs_doc[] = ""
     79"set_mel_coeffs(samplerate, fmin, fmax)\n"
     80"\n"
     81"Set coefficients of filterbank to linearly spaced mel scale.\n"
     82"\n"
     83"Parameters\n"
     84"----------\n"
     85"samplerate : float\n"
     86"    Sampling-rate of the expected input.\n"
     87"fmin : float\n"
     88"    Lower frequency boundary of the first filter.\n"
     89"fmax : float\n"
     90"    Upper frequency boundary of the last filter.\n"
     91"\n"
     92"See also\n"
     93"--------\n"
     94"hztomel\n"
     95"";
     96
     97static char Py_filterbank_set_mel_coeffs_htk_doc[] = ""
     98"set_mel_coeffs_htk(samplerate, fmin, fmax)\n"
     99"\n"
     100"Set coefficients of the filters to be linearly spaced in the HTK mel scale.\n"
     101"\n"
     102"Parameters\n"
     103"----------\n"
     104"samplerate : float\n"
     105"    Sampling-rate of the expected input.\n"
     106"fmin : float\n"
     107"    Lower frequency boundary of the first filter.\n"
     108"fmax : float\n"
     109"    Upper frequency boundary of the last filter.\n"
     110"\n"
     111"See also\n"
     112"--------\n"
     113"hztomel with `htk=True`\n"
     114"";
     115
     116static char Py_filterbank_get_coeffs_doc[] = ""
     117"get_coeffs()\n"
     118"\n"
     119"Get coefficients matrix of filterbank.\n"
     120"\n"
     121"Returns\n"
     122"-------\n"
     123"array_like\n"
     124"    Array of shape (n_filters, win_s/2+1) containing the coefficients.\n"
     125"";
     126
     127static char Py_filterbank_set_coeffs_doc[] = ""
     128"set_coeffs(coeffs)\n"
     129"\n"
     130"Set coefficients of filterbank.\n"
     131"\n"
     132"Parameters\n"
     133"----------\n"
     134"coeffs : fmat\n"
     135"    Array of shape (n_filters, win_s/2+1) containing the coefficients.\n"
     136"";
     137
     138static char Py_filterbank_set_power_doc[] = ""
     139"set_power(power)\n"
     140"\n"
     141"Set power applied to input spectrum of filterbank.\n"
     142"\n"
     143"Parameters\n"
     144"----------\n"
     145"power : float\n"
     146"    Power to raise input spectrum to before computing the filters.\n"
     147"";
     148
     149static char Py_filterbank_get_power_doc[] = ""
     150"get_power()\n"
     151"\n"
     152"Get power applied to filterbank.\n"
     153"\n"
     154"Returns\n"
     155"-------\n"
     156"float\n"
     157"    Power parameter.\n"
     158"";
     159
     160static char Py_filterbank_set_norm_doc[] = ""
     161"set_norm(norm)\n"
     162"\n"
     163"Set norm parameter. If set to `0`, the filters will not be normalized.\n"
     164"If set to `1`, the filters will be normalized to one. Default to `1`.\n"
     165"\n"
     166"This function should be called *before* :meth:`set_triangle_bands`,\n"
     167":meth:`set_mel_coeffs`, :meth:`set_mel_coeffs_htk`, or\n"
     168":meth:`set_mel_coeffs_slaney`.\n"
     169"\n"
     170"Parameters\n"
     171"----------\n"
     172"norm : int\n"
     173"   `0` to disable, `1` to enable\n"
     174"";
     175
     176static char Py_filterbank_get_norm_doc[] = ""
     177"get_norm()\n"
     178"\n"
     179"Get norm parameter of filterbank.\n"
     180"\n"
     181"Returns\n"
     182"-------\n"
     183"float\n"
     184"    Norm parameter.\n"
     185"";
    4186
    5187typedef struct
     
    95277  if (self->vec.length != self->win_s / 2 + 1) {
    96278    PyErr_Format(PyExc_ValueError,
    97                  "input cvec has length %d, but fft expects length %d",
     279                 "input cvec has length %d, but filterbank expects length %d",
    98280                 self->vec.length, self->win_s / 2 + 1);
    99281    return NULL;
     
    123305
    124306  PyObject *input;
    125   uint_t samplerate;
    126   if (!PyArg_ParseTuple (args, "OI", &input, &samplerate)) {
     307  smpl_t samplerate;
     308  if (!PyArg_ParseTuple (args, "O" AUBIO_NPY_SMPL_CHR, &input, &samplerate)) {
    127309    return NULL;
    128310  }
     
    139321      &(self->freqs), samplerate);
    140322  if (err > 0) {
    141     PyErr_SetString (PyExc_ValueError,
    142         "error when setting filter to A-weighting");
     323    if (PyErr_Occurred() == NULL) {
     324      PyErr_SetString (PyExc_ValueError, "error running set_triangle_bands");
     325    } else {
     326      // change the RuntimeError into ValueError
     327      PyObject *type, *value, *traceback;
     328      PyErr_Fetch(&type, &value, &traceback);
     329      PyErr_Restore(PyExc_ValueError, value, traceback);
     330    }
    143331    return NULL;
    144332  }
     
    151339  uint_t err = 0;
    152340
    153   uint_t samplerate;
    154   if (!PyArg_ParseTuple (args, "I", &samplerate)) {
     341  smpl_t samplerate;
     342  if (!PyArg_ParseTuple (args, AUBIO_NPY_SMPL_CHR, &samplerate)) {
    155343    return NULL;
    156344  }
     
    158346  err = aubio_filterbank_set_mel_coeffs_slaney (self->o, samplerate);
    159347  if (err > 0) {
    160     PyErr_SetString (PyExc_ValueError,
    161         "error when setting filter to A-weighting");
     348    if (PyErr_Occurred() == NULL) {
     349      PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs_slaney");
     350    } else {
     351      // change the RuntimeError into ValueError
     352      PyObject *type, *value, *traceback;
     353      PyErr_Fetch(&type, &value, &traceback);
     354      PyErr_Restore(PyExc_ValueError, value, traceback);
     355    }
     356    return NULL;
     357  }
     358  Py_RETURN_NONE;
     359}
     360
     361static PyObject *
     362Py_filterbank_set_mel_coeffs (Py_filterbank * self, PyObject *args)
     363{
     364  uint_t err = 0;
     365
     366  smpl_t samplerate;
     367  smpl_t freq_min;
     368  smpl_t freq_max;
     369  if (!PyArg_ParseTuple (args, AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR
     370        AUBIO_NPY_SMPL_CHR, &samplerate, &freq_min, &freq_max)) {
     371    return NULL;
     372  }
     373
     374  err = aubio_filterbank_set_mel_coeffs (self->o, samplerate,
     375      freq_min, freq_max);
     376  if (err > 0) {
     377    if (PyErr_Occurred() == NULL) {
     378      PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs");
     379    } else {
     380      // change the RuntimeError into ValueError
     381      PyObject *type, *value, *traceback;
     382      PyErr_Fetch(&type, &value, &traceback);
     383      PyErr_Restore(PyExc_ValueError, value, traceback);
     384    }
     385    return NULL;
     386  }
     387  Py_RETURN_NONE;
     388}
     389
     390static PyObject *
     391Py_filterbank_set_mel_coeffs_htk (Py_filterbank * self, PyObject *args)
     392{
     393  uint_t err = 0;
     394
     395  smpl_t samplerate;
     396  smpl_t freq_min;
     397  smpl_t freq_max;
     398  if (!PyArg_ParseTuple (args, AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR
     399        AUBIO_NPY_SMPL_CHR, &samplerate, &freq_min, &freq_max)) {
     400    return NULL;
     401  }
     402
     403  err = aubio_filterbank_set_mel_coeffs_htk (self->o, samplerate,
     404      freq_min, freq_max);
     405  if (err > 0) {
     406    if (PyErr_Occurred() == NULL) {
     407      PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs_htk");
     408    } else {
     409      // change the RuntimeError into ValueError
     410      PyObject *type, *value, *traceback;
     411      PyErr_Fetch(&type, &value, &traceback);
     412      PyErr_Restore(PyExc_ValueError, value, traceback);
     413    }
    162414    return NULL;
    163415  }
     
    196448}
    197449
     450static PyObject *
     451Py_filterbank_set_power(Py_filterbank *self, PyObject *args)
     452{
     453  smpl_t power;
     454
     455  if (!PyArg_ParseTuple (args, AUBIO_NPY_SMPL_CHR, &power)) {
     456    return NULL;
     457  }
     458  if(aubio_filterbank_set_power (self->o, power)) {
     459    if (PyErr_Occurred() == NULL) {
     460      PyErr_SetString (PyExc_ValueError,
     461          "error running filterbank.set_power");
     462    } else {
     463      // change the RuntimeError into ValueError
     464      PyObject *type, *value, *traceback;
     465      PyErr_Fetch(&type, &value, &traceback);
     466      PyErr_Restore(PyExc_ValueError, value, traceback);
     467    }
     468    return NULL;
     469  }
     470  Py_RETURN_NONE;
     471}
     472
     473static PyObject *
     474Py_filterbank_get_power (Py_filterbank * self, PyObject *unused)
     475{
     476  smpl_t power = aubio_filterbank_get_power(self->o);
     477  return (PyObject *)PyFloat_FromDouble (power);
     478}
     479
     480static PyObject *
     481Py_filterbank_set_norm(Py_filterbank *self, PyObject *args)
     482{
     483  smpl_t norm;
     484
     485  if (!PyArg_ParseTuple (args, AUBIO_NPY_SMPL_CHR, &norm)) {
     486    return NULL;
     487  }
     488  if(aubio_filterbank_set_norm (self->o, norm)) {
     489    if (PyErr_Occurred() == NULL) {
     490      PyErr_SetString (PyExc_ValueError,
     491          "error running filterbank.set_power");
     492    } else {
     493      // change the RuntimeError into ValueError
     494      PyObject *type, *value, *traceback;
     495      PyErr_Fetch(&type, &value, &traceback);
     496      PyErr_Restore(PyExc_ValueError, value, traceback);
     497    }
     498    return NULL;
     499  }
     500  Py_RETURN_NONE;
     501}
     502
     503static PyObject *
     504Py_filterbank_get_norm (Py_filterbank * self, PyObject *unused)
     505{
     506  smpl_t norm = aubio_filterbank_get_norm(self->o);
     507  return (PyObject *)PyFloat_FromDouble (norm);
     508}
     509
    198510static PyMethodDef Py_filterbank_methods[] = {
    199511  {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
    200     METH_VARARGS, "set coefficients of filterbanks"},
     512    METH_VARARGS, Py_filterbank_set_triangle_bands_doc},
    201513  {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
    202     METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
     514    METH_VARARGS, Py_filterbank_set_mel_coeffs_slaney_doc},
     515  {"set_mel_coeffs", (PyCFunction) Py_filterbank_set_mel_coeffs,
     516    METH_VARARGS, Py_filterbank_set_mel_coeffs_doc},
     517  {"set_mel_coeffs_htk", (PyCFunction) Py_filterbank_set_mel_coeffs_htk,
     518    METH_VARARGS, Py_filterbank_set_mel_coeffs_htk_doc},
    203519  {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
    204     METH_NOARGS, "get coefficients of filterbank"},
     520    METH_NOARGS, Py_filterbank_get_coeffs_doc},
    205521  {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
    206     METH_VARARGS, "set coefficients of filterbank"},
     522    METH_VARARGS, Py_filterbank_set_coeffs_doc},
     523  {"set_power", (PyCFunction) Py_filterbank_set_power,
     524    METH_VARARGS, Py_filterbank_set_power_doc},
     525  {"get_power", (PyCFunction) Py_filterbank_get_power,
     526    METH_NOARGS, Py_filterbank_get_power_doc},
     527  {"set_norm", (PyCFunction) Py_filterbank_set_norm,
     528    METH_VARARGS, Py_filterbank_set_norm_doc},
     529  {"get_norm", (PyCFunction) Py_filterbank_get_norm,
     530    METH_NOARGS, Py_filterbank_get_norm_doc},
    207531  {NULL}
    208532};
  • python/ext/py-musicutils.c

    r086a45b rf2f1b10  
    4040  }
    4141
    42   level_lin = Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_level_lin(&vec));
     42  level_lin = PyFloat_FromDouble(aubio_level_lin(&vec));
    4343  if (level_lin == NULL) {
    4444    PyErr_SetString (PyExc_ValueError, "failed computing level_lin");
     
    6868  }
    6969
    70   db_spl = Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_db_spl(&vec));
     70  db_spl = PyFloat_FromDouble(aubio_db_spl(&vec));
    7171  if (db_spl == NULL) {
    7272    PyErr_SetString (PyExc_ValueError, "failed computing db_spl");
     
    9797  }
    9898
    99   silence_detection = Py_BuildValue("I", aubio_silence_detection(&vec, threshold));
     99  silence_detection = PyLong_FromLong(aubio_silence_detection(&vec, threshold));
    100100  if (silence_detection == NULL) {
    101101    PyErr_SetString (PyExc_ValueError, "failed computing silence_detection");
     
    126126  }
    127127
    128   level_detection = Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_level_detection(&vec, threshold));
     128  level_detection = PyFloat_FromDouble(aubio_level_detection(&vec, threshold));
    129129  if (level_detection == NULL) {
    130130    PyErr_SetString (PyExc_ValueError, "failed computing level_detection");
     
    134134  return level_detection;
    135135}
     136
     137PyObject *
     138Py_aubio_shift(PyObject *self, PyObject *args)
     139{
     140  PyObject *input;
     141  fvec_t vec;
     142
     143  if (!PyArg_ParseTuple (args, "O:shift", &input)) {
     144    return NULL;
     145  }
     146
     147  if (input == NULL) {
     148    return NULL;
     149  }
     150
     151  if (!PyAubio_ArrayToCFvec(input, &vec)) {
     152    return NULL;
     153  }
     154
     155  fvec_shift(&vec);
     156
     157  //Py_RETURN_NONE;
     158  return (PyObject *) PyAubio_CFvecToArray(&vec);
     159}
     160
     161PyObject *
     162Py_aubio_ishift(PyObject *self, PyObject *args)
     163{
     164  PyObject *input;
     165  fvec_t vec;
     166
     167  if (!PyArg_ParseTuple (args, "O:shift", &input)) {
     168    return NULL;
     169  }
     170
     171  if (input == NULL) {
     172    return NULL;
     173  }
     174
     175  if (!PyAubio_ArrayToCFvec(input, &vec)) {
     176    return NULL;
     177  }
     178
     179  fvec_ishift(&vec);
     180
     181  //Py_RETURN_NONE;
     182  return (PyObject *) PyAubio_CFvecToArray(&vec);
     183}
     184
     185PyObject*
     186Py_aubio_hztomel(PyObject *self, PyObject *args, PyObject *kwds)
     187{
     188  smpl_t v;
     189  PyObject *htk = NULL;
     190  static char *kwlist[] = {"f", "htk", NULL};
     191  if (!PyArg_ParseTupleAndKeywords(args, kwds, AUBIO_NPY_SMPL_CHR "|O",
     192        kwlist, &v, &htk))
     193  {
     194    return NULL;
     195  }
     196  if (htk != NULL && PyObject_IsTrue(htk) == 1)
     197    return PyFloat_FromDouble(aubio_hztomel_htk(v));
     198  else
     199    return PyFloat_FromDouble(aubio_hztomel(v));
     200}
     201
     202PyObject*
     203Py_aubio_meltohz(PyObject *self, PyObject *args, PyObject *kwds)
     204{
     205  smpl_t v;
     206  PyObject *htk = NULL;
     207  static char *kwlist[] = {"m", "htk", NULL};
     208  if (!PyArg_ParseTupleAndKeywords(args, kwds, AUBIO_NPY_SMPL_CHR "|O",
     209        kwlist, &v, &htk))
     210  {
     211    return NULL;
     212  }
     213  if (htk != NULL && PyObject_IsTrue(htk) == 1)
     214    return PyFloat_FromDouble(aubio_meltohz_htk(v));
     215  else
     216    return PyFloat_FromDouble(aubio_meltohz(v));
     217}
     218
     219PyObject*
     220Py_aubio_hztomel_htk(PyObject *self, PyObject *args)
     221{
     222  smpl_t v;
     223  if (!PyArg_ParseTuple(args, AUBIO_NPY_SMPL_CHR, &v)) {
     224    return NULL;
     225  }
     226  return PyFloat_FromDouble(aubio_hztomel_htk(v));
     227}
     228
     229PyObject*
     230Py_aubio_meltohz_htk(PyObject *self, PyObject *args)
     231{
     232  smpl_t v;
     233  if (!PyArg_ParseTuple(args, AUBIO_NPY_SMPL_CHR, &v)) {
     234    return NULL;
     235  }
     236  return PyFloat_FromDouble(aubio_meltohz_htk(v));
     237}
  • python/ext/py-musicutils.h

    r086a45b rf2f1b10  
    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
     237static char Py_aubio_shift_doc[] = ""
     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"
     255"\n"
     256"For a vector of length N, the partition is split at index N - N//2.\n"
     257"\n"
     258"Example\n"
     259"-------\n"
     260"\n"
     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"";
     268PyObject * Py_aubio_shift(PyObject *self, PyObject *args);
     269
     270static char Py_aubio_ishift_doc[] = ""
     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"";
     301PyObject * Py_aubio_ishift(PyObject *self, PyObject *args);
     302
     303static char Py_aubio_hztomel_doc[] = ""
     304"hztomel(f, htk=False)\n"
     305"\n"
     306"Convert a scalar from frequency to mel scale.\n"
     307"\n"
     308"Parameters\n"
     309"----------\n"
     310"m : float\n"
     311"   input frequency, in Hz\n"
     312"htk : bool\n"
     313"   if `True`, use Htk mel scale instead of Slaney.\n"
     314"\n"
     315"Returns\n"
     316"-------\n"
     317"float\n"
     318"   output mel\n"
     319"\n"
     320"See Also\n"
     321"--------\n"
     322"meltohz\n"
     323"";
     324PyObject * Py_aubio_hztomel(PyObject *self, PyObject *args);
     325
     326static char Py_aubio_meltohz_doc[] = ""
     327"meltohz(m, htk=False)\n"
     328"\n"
     329"Convert a scalar from mel scale to frequency.\n"
     330"\n"
     331"Parameters\n"
     332"----------\n"
     333"m : float\n"
     334"   input mel\n"
     335"htk : bool\n"
     336"   if `True`, use Htk mel scale instead of Slaney.\n"
     337"\n"
     338"Returns\n"
     339"-------\n"
     340"float\n"
     341"   output frequency, in Hz\n"
     342"\n"
     343"See Also\n"
     344"--------\n"
     345"hztomel\n"
     346"";
     347PyObject * Py_aubio_meltohz(PyObject *self, PyObject *args);
     348
     349static char Py_aubio_hztomel_htk_doc[] = ""
     350"hztomel_htk(m)\n"
     351"\n"
     352"Same as `hztomel(m, htk=True)`\n"
     353"\n"
     354"See Also\n"
     355"--------\n"
     356"hztomel\n"
     357"";
     358PyObject * Py_aubio_hztomel_htk(PyObject *self, PyObject *args);
     359
     360static char Py_aubio_meltohz_htk_doc[] = ""
     361"meltohz_htk(m)\n"
     362"\n"
     363"Same as `meltohz(m, htk=True)`\n"
     364"\n"
     365"See Also\n"
     366"--------\n"
     367"meltohz\n"
     368"";
     369PyObject * Py_aubio_meltohz_htk(PyObject *self, PyObject *args);
     370
    74371#endif /* PY_AUBIO_MUSICUTILS_H */
  • python/ext/py-phasevoc.c

    r086a45b rf2f1b10  
    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
     
    3991  self->hop_s = Py_default_vector_length/2;
    4092
    41   if (self == NULL) {
    42     return NULL;
    43   }
    44 
    4593  if (win_s > 0) {
    4694    self->win_s = win_s;
     
    122170static PyMemberDef Py_pvoc_members[] = {
    123171  {"win_s", T_INT, offsetof (Py_pvoc, win_s), READONLY,
    124     "size of the window"},
     172    "int: Size of phase vocoder analysis windows, in samples.\n"
     173    ""},
    125174  {"hop_s", T_INT, offsetof (Py_pvoc, hop_s), READONLY,
    126     "size of the hop"},
     175    "int: Interval between two analysis, in samples.\n"
     176    ""},
    127177  { NULL } // sentinel
    128178};
     
    176226static PyMethodDef Py_pvoc_methods[] = {
    177227  {"rdo", (PyCFunction) Py_pvoc_rdo, METH_VARARGS,
    178     "synthesis of spectral grain"},
    179   {"set_window", (PyCFunction) Pyaubio_pvoc_set_window, METH_VARARGS, ""},
     228    "rdo(fftgrain)\n"
     229    "\n"
     230    "Read a new spectral grain and resynthesise the next `hop_s`\n"
     231    "output samples.\n"
     232    "\n"
     233    "Parameters\n"
     234    "----------\n"
     235    "fftgrain : cvec\n"
     236    "    new input `cvec` to synthesize from, should be of size `win_s/2+1`\n"
     237    "\n"
     238    "Returns\n"
     239    "-------\n"
     240    "fvec\n"
     241    "    re-synthesised output of shape `(hop_s,)`\n"
     242    "\n"
     243    "Example\n"
     244    "-------\n"
     245    ">>> pv = aubio.pvoc(2048, 512)\n"
     246    ">>> out = pv.rdo(aubio.cvec(2048))\n"
     247    ">>> out.shape\n"
     248    "(512,)\n"
     249    ""},
     250  {"set_window", (PyCFunction) Pyaubio_pvoc_set_window, METH_VARARGS,
     251    "set_window(window_type)\n"
     252    "\n"
     253    "Set window function\n"
     254    "\n"
     255    "Parameters\n"
     256    "----------\n"
     257    "window_type : str\n"
     258    "    the window type to use for this phase vocoder\n"
     259    "\n"
     260    "Raises\n"
     261    "------\n"
     262    "ValueError\n"
     263    "    If an unknown window type was given.\n"
     264    "\n"
     265    "See Also\n"
     266    "--------\n"
     267    "window : create a window.\n"
     268    ""},
    180269  {NULL}
    181270};
  • python/ext/py-sink.c

    r086a45b rf2f1b10  
    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"Write audio samples to 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 *
     
    126151Py_sink_del (Py_sink *self, PyObject *unused)
    127152{
    128   del_aubio_sink(self->o);
    129   free(self->mwrite_data.data);
     153  if (self->o) {
     154    del_aubio_sink(self->o);
     155    free(self->mwrite_data.data);
     156  }
    130157  if (self->uri) {
    131158    free(self->uri);
     
    189216static PyMemberDef Py_sink_members[] = {
    190217  {"uri", T_STRING, offsetof (Py_sink, uri), READONLY,
    191     "path at which the sink was created"},
     218    "str (read-only): Path at which the sink was created."},
    192219  {"samplerate", T_INT, offsetof (Py_sink, samplerate), READONLY,
    193     "samplerate at which the sink was created"},
     220    "int (read-only): Samplerate at which the sink was created."},
    194221  {"channels", T_INT, offsetof (Py_sink, channels), READONLY,
    195     "number of channels with which the sink was created"},
     222    "int (read-only): Number of channels with which the sink was created."},
    196223  { NULL } // sentinel
    197224};
  • python/ext/py-source.c

    r086a45b rf2f1b10  
    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"Read audio samples from a media file.\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\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 : numpy.ndarray\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 *
     
    189437  aubio_source_do (self->o, &(self->c_read_to), &read);
    190438
     439  if (PyErr_Occurred() != NULL) {
     440    return NULL;
     441  }
     442
    191443  outputs = PyTuple_New(2);
    192444  PyTuple_SetItem( outputs, 0, self->read_to );
     
    210462  aubio_source_do_multi (self->o, &(self->c_mread_to), &read);
    211463
     464  if (PyErr_Occurred() != NULL) {
     465    return NULL;
     466  }
     467
    212468  outputs = PyTuple_New(2);
    213469  PyTuple_SetItem( outputs, 0, self->mread_to);
     
    218474static PyMemberDef Py_source_members[] = {
    219475  {"uri", T_STRING, offsetof (Py_source, uri), READONLY,
    220     "path at which the source was created"},
     476    "str (read-only): pathname or URL"},
    221477  {"samplerate", T_INT, offsetof (Py_source, samplerate), READONLY,
    222     "samplerate at which the source is viewed"},
     478    "int (read-only): sampling rate"},
    223479  {"channels", T_INT, offsetof (Py_source, channels), READONLY,
    224     "number of channels found in the source"},
     480    "int (read-only): number of channels"},
    225481  {"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"},
     482    "int (read-only): number of samples read per iteration"},
    227483  {"duration", T_INT, offsetof (Py_source, duration), READONLY,
    228     "total number of frames in the source (estimated)"},
     484    "int (read-only): total number of frames in the source\n"
     485    "\n"
     486    "Can be estimated, for instance if the opened stream is\n"
     487    "a compressed media or a remote resource.\n"
     488    "\n"
     489    "Example\n"
     490    "-------\n"
     491    ">>> n = 0\n"
     492    ">>> src = aubio.source('track1.mp3')\n"
     493    ">>> for samples in src:\n"
     494    "...     n += samples.shape[-1]\n"
     495    "...\n"
     496    ">>> n, src.duration\n"
     497    "(9638784, 9616561)\n"
     498    ""},
    229499  { NULL } // sentinel
    230500};
     
    312582    } else if (PyLong_AsLong(size) > 0) {
    313583      // short read, return a shorter array
    314       PyArrayObject *shortread = (PyArrayObject*)PyTuple_GetItem(done, 0);
     584      PyObject *vec = PyTuple_GetItem(done, 0);
     585      // take a copy to prevent resizing internal arrays
     586      PyArrayObject *shortread = (PyArrayObject*)PyArray_FROM_OTF(vec,
     587          NPY_NOTYPE, NPY_ARRAY_ENSURECOPY);
    315588      PyArray_Dims newdims;
    316589      PyObject *reshaped;
     
    325598      reshaped = PyArray_Newshape(shortread, &newdims, NPY_CORDER);
    326599      Py_DECREF(shortread);
     600      Py_DECREF(vec);
    327601      return reshaped;
    328602    } else {
  • python/ext/ufuncs.c

    r086a45b rf2f1b10  
    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

    r086a45b rf2f1b10  
    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
     
    830from .slicing import *
    931
     32
    1033class fvec(numpy.ndarray):
    11     """a numpy vector holding audio samples"""
     34    """fvec(input_arg=1024)
     35    A vector holding float samples.
    1236
    13     def __new__(cls, input_arg=1024, **kwargs):
     37    If `input_arg` is an `int`, a 1-dimensional vector of length `input_arg`
     38    will be created and filled with zeros. Otherwise, if `input_arg` is an
     39    `array_like` object, it will be converted to a 1-dimensional vector of
     40    type :data:`float_type`.
     41
     42    Parameters
     43    ----------
     44    input_arg : `int` or `array_like`
     45        Can be a positive integer, or any object that can be converted to
     46        a numpy array with :func:`numpy.array`.
     47
     48    Examples
     49    --------
     50    >>> aubio.fvec(10)
     51    array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)
     52    >>> aubio.fvec([0,1,2])
     53    array([0., 1., 2.], dtype=float32)
     54    >>> a = np.arange(10); type(a), type(aubio.fvec(a))
     55    (<class 'numpy.ndarray'>, <class 'numpy.ndarray'>)
     56    >>> a.dtype, aubio.fvec(a).dtype
     57    (dtype('int64'), dtype('float32'))
     58
     59    Notes
     60    -----
     61
     62    In the Python world, `fvec` is simply a subclass of
     63    :class:`numpy.ndarray`. In practice, any 1-dimensional `numpy.ndarray` of
     64    `dtype` :data:`float_type` may be passed to methods accepting
     65    `fvec` as parameter. For instance, `sink()` or `pvoc()`.
     66
     67    See Also
     68    --------
     69    cvec : a container holding spectral data
     70    numpy.ndarray : parent class of :class:`fvec`
     71    numpy.zeros : create a numpy array filled with zeros
     72    numpy.array : create a numpy array from an existing object
     73    """
     74    def __new__(cls, input_arg=1024):
    1475        if isinstance(input_arg, int):
    1576            if input_arg == 0:
    1677                raise ValueError("vector length of 1 or more expected")
    17             return numpy.zeros(input_arg, dtype=float_type, **kwargs)
     78            return numpy.zeros(input_arg, dtype=float_type, order='C')
    1879        else:
    19             return numpy.array(input_arg, dtype=float_type, **kwargs)
     80            np_input = numpy.array(input_arg, dtype=float_type, order='C')
     81            if len(np_input.shape) != 1:
     82                raise ValueError("input_arg should have shape (n,)")
     83            if np_input.shape[0] == 0:
     84                raise ValueError("vector length of 1 or more expected")
     85            return np_input
  • python/lib/aubio/cmd.py

    r086a45b rf2f1b10  
    1212import sys
    1313import argparse
     14import warnings
    1415import aubio
    1516
     
    102103    subparser.add_input()
    103104    subparser.add_buf_hop_size()
     105    subparser.add_silence()
     106    subparser.add_release_drop()
    104107    subparser.add_time_format()
    105108    subparser.add_verbose_help()
     
    138141
    139142def parser_add_subcommand_cut(subparsers):
    140     # quiet subcommand
     143    # cut subcommand
    141144    subparser = subparsers.add_parser('cut',
    142145            help='slice at timestamps')
     
    167170
    168171    def add_verbose_help(self):
    169         self.add_argument("-v","--verbose",
     172        self.add_argument("-v", "--verbose",
    170173                action="count", dest="verbose", default=1,
    171174                help="make lots of noise [default]")
    172         self.add_argument("-q","--quiet",
     175        self.add_argument("-q", "--quiet",
    173176                action="store_const", dest="verbose", const=0,
    174177                help="be quiet")
     
    179182
    180183    def add_buf_size(self, buf_size=512):
    181         self.add_argument("-B","--bufsize",
     184        self.add_argument("-B", "--bufsize",
    182185                action="store", dest="buf_size", default=buf_size,
    183186                metavar = "<size>", type=int,
     
    185188
    186189    def add_hop_size(self, hop_size=256):
    187         self.add_argument("-H","--hopsize",
     190        self.add_argument("-H", "--hopsize",
    188191                metavar = "<size>", type=int,
    189192                action="store", dest="hop_size", default=hop_size,
     
    191194
    192195    def add_method(self, method='default', helpstr='method'):
    193         self.add_argument("-m","--method",
     196        self.add_argument("-m", "--method",
    194197                metavar = "<method>", type=str,
    195198                action="store", dest="method", default=method,
     
    197200
    198201    def add_threshold(self, default=None):
    199         self.add_argument("-t","--threshold",
     202        self.add_argument("-t", "--threshold",
    200203                metavar = "<threshold>", type=float,
    201204                action="store", dest="threshold", default=default,
     
    207210                action="store", dest="silence", default=-70,
    208211                help="silence threshold")
     212
     213    def add_release_drop(self):
     214        self.add_argument("-d", "--release-drop",
     215                metavar = "<value>", type=float,
     216                action="store", dest="release_drop", default=10,
     217                help="release drop threshold")
    209218
    210219    def add_minioi(self, default="12ms"):
     
    232241
    233242    def add_slicer_options(self):
    234         self.add_argument("-o","--output", type = str,
     243        self.add_argument("-o", "--output", type = str,
    235244                metavar = "<outputdir>",
    236245                action="store", dest="output_directory", default=None,
    237                 help="specify path where slices of the original file should be created")
     246                help="specify path where slices of the original file should"
     247                " be created")
    238248        self.add_argument("--cut-until-nsamples", type = int,
    239249                metavar = "<samples>",
    240250                action = "store", dest = "cut_until_nsamples", default = None,
    241                 help="how many extra samples should be added at the end of each slice")
     251                help="how many extra samples should be added at the end of"
     252                " each slice")
    242253        self.add_argument("--cut-every-nslices", type = int,
    243254                metavar = "<samples>",
     
    247258                metavar = "<slices>",
    248259                action = "store", dest = "cut_until_nslices", default = None,
    249                 help="how many extra slices should be added at the end of each slice")
     260                help="how many extra slices should be added at the end of"
     261                " each slice")
     262        self.add_argument("--create-first",
     263                action = "store_true", dest = "create_first", default = False,
     264                help="always include first slice")
    250265
    251266# some utilities
     
    278293        if args.verbose > 2 and hasattr(self, 'options'):
    279294            name = type(self).__name__.split('_')[1]
    280             optstr = ' '.join(['running', name, 'with options', repr(self.options), '\n'])
     295            optstr = ' '.join(['running', name, 'with options',
     296                repr(self.options), '\n'])
    281297            sys.stderr.write(optstr)
    282298    def flush(self, frames_read, samplerate):
     
    286302    def parse_options(self, args, valid_opts):
    287303        # get any valid options found in a dictionnary of arguments
    288         options = {k :v for k,v in vars(args).items() if k in valid_opts}
     304        options = {k: v for k, v in vars(args).items() if k in valid_opts}
    289305        self.options = options
    290306
     
    367383            outstr = "unknown bpm"
    368384        else:
    369             bpms = 60./ np.diff(self.beat_locations)
     385            bpms = 60. / np.diff(self.beat_locations)
    370386            median_bpm = np.mean(bpms)
    371387            if len(self.beat_locations) < 10:
     
    380396        self.parse_options(args, self.valid_opts)
    381397        self.notes = aubio.notes(**self.options)
     398        if args.silence is not None:
     399            self.notes.set_silence(args.silence)
     400        if args.release_drop is not None:
     401            self.notes.set_release_drop(args.release_drop)
    382402        super(process_notes, self).__init__(args)
    383403    def __call__(self, block):
    384404        return self.notes(block)
    385405    def repr_res(self, res, frames_read, samplerate):
    386         if res[2] != 0: # note off
     406        if res[2] != 0:  # note off
    387407            fmt_out = self.time2string(frames_read, samplerate)
    388408            sys.stdout.write(fmt_out + '\n')
    389         if res[0] != 0: # note on
     409        if res[0] != 0:  # note on
    390410            lastmidi = res[0]
    391411            fmt_out = "%f\t" % lastmidi
    392412            fmt_out += self.time2string(frames_read, samplerate)
    393             sys.stdout.write(fmt_out) # + '\t')
     413            sys.stdout.write(fmt_out)  # + '\t')
    394414    def flush(self, frames_read, samplerate):
    395415        eof = self.time2string(frames_read, samplerate)
     
    458478            if self.wassilence != 1:
    459479                self.wassilence = 1
    460                 return 2 # newly found silence
    461             return 1 # silence again
     480                return 2   # newly found silence
     481            return 1       # silence again
    462482        else:
    463483            if self.wassilence != 0:
    464484                self.wassilence = 0
    465                 return -1 # newly found noise
    466             return 0 # noise again
     485                return -1  # newly found noise
     486            return 0       # noise again
    467487
    468488    def repr_res(self, res, frames_read, samplerate):
     
    484504    def __call__(self, block):
    485505        ret = super(process_cut, self).__call__(block)
    486         if ret: self.slices.append(self.onset.get_last())
     506        if ret:
     507            self.slices.append(self.onset.get_last())
    487508        return ret
    488509
    489510    def flush(self, frames_read, samplerate):
    490         from aubio.cut import _cut_slice
    491511        _cut_slice(self.options, self.slices)
    492         duration = float (frames_read) / float(samplerate)
    493         base_info = '%(source_file)s' % {'source_file': self.options.source_uri}
     512        duration = float(frames_read) / float(samplerate)
     513        base_info = '%(source_file)s' % \
     514                    {'source_file': self.options.source_uri}
    494515        base_info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % \
    495                 {'duration': duration, 'samplerate': samplerate}
     516                     {'duration': duration, 'samplerate': samplerate}
    496517        info = "created %d slices from " % len(self.slices)
    497518        info += base_info
    498519        sys.stderr.write(info)
    499520
     521def _cut_slice(options, timestamps):
     522    # cutting pass
     523    nstamps = len(timestamps)
     524    if nstamps > 0:
     525        # generate output files
     526        timestamps_end = None
     527        if options.cut_every_nslices:
     528            timestamps = timestamps[::options.cut_every_nslices]
     529            nstamps = len(timestamps)
     530        if options.cut_until_nslices and options.cut_until_nsamples:
     531            msg = "using cut_until_nslices, but cut_until_nsamples is set"
     532            warnings.warn(msg)
     533        if options.cut_until_nsamples:
     534            lag = options.cut_until_nsamples
     535            timestamps_end = [t + lag for t in timestamps[1:]]
     536            timestamps_end += [1e120]
     537        if options.cut_until_nslices:
     538            slice_lag = options.cut_until_nslices
     539            timestamps_end = [t for t in timestamps[1 + slice_lag:]]
     540            timestamps_end += [1e120] * (options.cut_until_nslices + 1)
     541        aubio.slice_source_at_stamps(options.source_uri,
     542                timestamps, timestamps_end = timestamps_end,
     543                output_dir = options.output_directory,
     544                samplerate = options.samplerate,
     545                create_first = options.create_first)
     546
    500547def main():
    501548    parser = aubio_parser()
    502     args = parser.parse_args()
     549    if sys.version_info[0] != 3:
     550        # on py2, create a dummy ArgumentParser to workaround the
     551        # optional subcommand issue. See https://bugs.python.org/issue9253
     552        # This ensures that:
     553        #  - version string is shown when only '-V' is passed
     554        #  - help is printed if  '-V' is passed with any other argument
     555        #  - any other argument get forwarded to the real parser
     556        parser_root = argparse.ArgumentParser(add_help=False)
     557        parser_root.add_argument('-V', '--version', help="show version",
     558                action="store_true", dest="show_version")
     559        args, extras = parser_root.parse_known_args()
     560        if not args.show_version:  # no -V, forward to parser
     561            args = parser.parse_args(extras, namespace=args)
     562        elif len(extras) != 0:     # -V with other arguments, print help
     563            parser.print_help()
     564            sys.exit(1)
     565    else:  # in py3, we can simply use parser directly
     566        args = parser.parse_args()
    503567    if 'show_version' in args and args.show_version:
    504568        sys.stdout.write('aubio version ' + aubio.version + '\n')
     
    506570    elif 'verbose' in args and args.verbose > 3:
    507571        sys.stderr.write('aubio version ' + aubio.version + '\n')
    508     if 'command' not in args or args.command is None or args.command in ['help']:
     572    if 'command' not in args or args.command is None \
     573            or args.command in ['help']:
    509574        # no command given, print help and return 1
    510575        parser.print_help()
     
    540605                frames_read += read
    541606                # exit loop at end of file
    542                 if read < a_source.hop_size: break
     607                if read < a_source.hop_size:
     608                    break
    543609            # flush the processor if needed
    544610            processor.flush(frames_read, a_source.samplerate)
     
    548614                fmt_string += " from {:s} at {:d}Hz\n"
    549615                sys.stderr.write(fmt_string.format(
    550                         frames_read/float(a_source.samplerate),
     616                        frames_read / float(a_source.samplerate),
    551617                        frames_read,
    552618                        frames_read // a_source.hop_size + 1,
  • python/lib/aubio/cut.py

    r086a45b rf2f1b10  
    66
    77import sys
    8 from aubio.cmd import AubioArgumentParser
     8from aubio.cmd import AubioArgumentParser, _cut_slice
    99
    1010def aubio_cut_parser():
    1111    parser = AubioArgumentParser()
    1212    parser.add_input()
    13     parser.add_argument("-O","--onset-method",
     13    parser.add_argument("-O", "--onset-method",
    1414            action="store", dest="onset_method", default='default',
    1515            metavar = "<onset_method>",
     
    1717                    complexdomain|hfc|phase|specdiff|energy|kl|mkl")
    1818    # cutting methods
    19     parser.add_argument("-b","--beat",
     19    parser.add_argument("-b", "--beat",
    2020            action="store_true", dest="beat", default=False,
    2121            help="slice at beat locations")
    2222    """
    23     parser.add_argument("-S","--silencecut",
     23    parser.add_argument("-S", "--silencecut",
    2424            action="store_true", dest="silencecut", default=False,
    2525            help="use silence locations")
    26     parser.add_argument("-s","--silence",
     26    parser.add_argument("-s", "--silence",
    2727            metavar = "<value>",
    2828            action="store", dest="silence", default=-70,
     
    3131    # algorithm parameters
    3232    parser.add_buf_hop_size()
    33     parser.add_argument("-t","--threshold", "--onset-threshold",
     33    parser.add_argument("-t", "--threshold", "--onset-threshold",
    3434            metavar = "<threshold>", type=float,
    3535            action="store", dest="threshold", default=0.3,
    3636            help="onset peak picking threshold [default=0.3]")
    37     parser.add_argument("-c","--cut",
     37    parser.add_argument("-c", "--cut",
    3838            action="store_true", dest="cut", default=False,
    3939            help="cut input sound file at detected labels")
     
    4141
    4242    """
    43     parser.add_argument("-D","--delay",
     43    parser.add_argument("-D", "--delay",
    4444            action = "store", dest = "delay", type = float,
    4545            metavar = "<seconds>", default=0,
    4646            help="number of seconds to take back [default=system]\
    4747                    default system delay is 3*hopsize/samplerate")
    48     parser.add_argument("-C","--dcthreshold",
     48    parser.add_argument("-C", "--dcthreshold",
    4949            metavar = "<value>",
    5050            action="store", dest="dcthreshold", default=1.,
    5151            help="onset peak picking DC component [default=1.]")
    52     parser.add_argument("-L","--localmin",
     52    parser.add_argument("-L", "--localmin",
    5353            action="store_true", dest="localmin", default=False,
    5454            help="use local minima after peak detection")
    55     parser.add_argument("-d","--derivate",
     55    parser.add_argument("-d", "--derivate",
    5656            action="store_true", dest="derivate", default=False,
    5757            help="derivate onset detection function")
    58     parser.add_argument("-z","--zerocross",
     58    parser.add_argument("-z", "--zerocross",
    5959            metavar = "<value>",
    6060            action="store", dest="zerothres", default=0.008,
    6161            help="zero-crossing threshold for slicing [default=0.00008]")
    6262    # plotting functions
    63     parser.add_argument("-p","--plot",
     63    parser.add_argument("-p", "--plot",
    6464            action="store_true", dest="plot", default=False,
    6565            help="draw plot")
    66     parser.add_argument("-x","--xsize",
     66    parser.add_argument("-x", "--xsize",
    6767            metavar = "<size>",
    6868            action="store", dest="xsize", default=1.,
    6969            type=float, help="define xsize for plot")
    70     parser.add_argument("-y","--ysize",
     70    parser.add_argument("-y", "--ysize",
    7171            metavar = "<size>",
    7272            action="store", dest="ysize", default=1.,
    7373            type=float, help="define ysize for plot")
    74     parser.add_argument("-f","--function",
     74    parser.add_argument("-f", "--function",
    7575            action="store_true", dest="func", default=False,
    7676            help="print detection function")
    77     parser.add_argument("-n","--no-onsets",
     77    parser.add_argument("-n", "--no-onsets",
    7878            action="store_true", dest="nplot", default=False,
    7979            help="do not plot detected onsets")
    80     parser.add_argument("-O","--outplot",
     80    parser.add_argument("-O", "--outplot",
    8181            metavar = "<output_image>",
    8282            action="store", dest="outplot", default=None,
    8383            help="save plot to output.{ps,png}")
    84     parser.add_argument("-F","--spectrogram",
     84    parser.add_argument("-F", "--spectrogram",
    8585            action="store_true", dest="spectro", default=False,
    8686            help="add spectrogram to the plot")
     
    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
    107107    if options.beat:
    108         o = tempo(options.onset_method, bufsize, hopsize, samplerate=samplerate)
     108        o = tempo(options.onset_method, bufsize, hopsize,
     109                samplerate=samplerate)
    109110    else:
    110         o = onset(options.onset_method, bufsize, hopsize, samplerate=samplerate)
     111        o = onset(options.onset_method, bufsize, hopsize,
     112                samplerate=samplerate)
    111113        if options.minioi:
    112114            if options.minioi.endswith('ms'):
     
    123125        samples, read = s()
    124126        if o(samples):
    125             timestamps.append (o.get_last())
    126             if options.verbose: print ("%.4f" % o.get_last_s())
     127            timestamps.append(o.get_last())
     128            if options.verbose:
     129                print("%.4f" % o.get_last_s())
    127130        total_frames += read
    128         if read < hopsize: break
     131        if read < hopsize:
     132            break
    129133    del s
    130134    return timestamps, total_frames
    131 
    132 def _cut_slice(options, timestamps):
    133     # cutting pass
    134     nstamps = len(timestamps)
    135     if nstamps > 0:
    136         # generate output files
    137         from aubio.slicing import slice_source_at_stamps
    138         timestamps_end = None
    139         if options.cut_every_nslices:
    140             timestamps = timestamps[::options.cut_every_nslices]
    141             nstamps = len(timestamps)
    142         if options.cut_until_nslices and options.cut_until_nsamples:
    143             print ("warning: using cut_until_nslices, but cut_until_nsamples is set")
    144         if options.cut_until_nsamples:
    145             timestamps_end = [t + options.cut_until_nsamples for t in timestamps[1:]]
    146             timestamps_end += [ 1e120 ]
    147         if options.cut_until_nslices:
    148             timestamps_end = [t for t in timestamps[1 + options.cut_until_nslices:]]
    149             timestamps_end += [ 1e120 ] * (options.cut_until_nslices + 1)
    150         slice_source_at_stamps(options.source_uri,
    151                 timestamps, timestamps_end = timestamps_end,
    152                 output_dir = options.output_directory,
    153                 samplerate = options.samplerate)
    154135
    155136def main():
     
    167148
    168149    # print some info
    169     duration = float (total_frames) / float(options.samplerate)
     150    duration = float(total_frames) / float(options.samplerate)
    170151    base_info = '%(source_uri)s' % {'source_uri': options.source_uri}
    171152    base_info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % \
  • python/lib/aubio/midiconv.py

    r086a45b rf2f1b10  
    22""" utilities to convert midi note number to and from note names """
    33
    4 __all__ = ['note2midi', 'midi2note', 'freq2note']
     4import sys
     5from ._aubio import freqtomidi, miditofreq
    56
    6 import sys
     7__all__ = ['note2midi', 'midi2note', 'freq2note', 'note2freq']
     8
    79py3 = sys.version_info[0] == 3
    810if py3:
     
    1315    int_instances = (int, long)
    1416
     17
    1518def note2midi(note):
    16     " convert note name to midi note number, e.g. [C-1, G9] -> [0, 127] "
    17     _valid_notenames = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}
     19    """Convert note name to midi note number.
     20
     21    Input string `note` should be composed of one note root
     22    and one octave, with optionally one modifier in between.
     23
     24    List of valid components:
     25
     26    - note roots: `C`, `D`, `E`, `F`, `G`, `A`, `B`,
     27    - modifiers: `b`, `#`, as well as unicode characters
     28      `𝄫`, `♭`, `♮`, `♯` and `𝄪`,
     29    - octave numbers: `-1` -> `11`.
     30
     31    Parameters
     32    ----------
     33    note : str
     34        note name
     35
     36    Returns
     37    -------
     38    int
     39        corresponding midi note number
     40
     41    Examples
     42    --------
     43    >>> aubio.note2midi('C#4')
     44    61
     45    >>> aubio.note2midi('B♭5')
     46    82
     47
     48    Raises
     49    ------
     50    TypeError
     51        If `note` was not a string.
     52    ValueError
     53        If an error was found while converting `note`.
     54
     55    See Also
     56    --------
     57    midi2note, freqtomidi, miditofreq
     58    """
     59    _valid_notenames = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7,
     60                        'A': 9, 'B': 11}
    1861    _valid_modifiers = {
    19             u'𝄫': -2,                        # double flat
    20             u'♭': -1, 'b': -1, '\u266d': -1, # simple flat
    21             u'♮': 0, '\u266e': 0, None: 0,   # natural
    22             '#': +1, u'♯': +1, '\u266f': +1, # sharp
    23             u'𝄪': +2,                        # double sharp
     62            u'𝄫': -2,                         # double flat
     63            u'♭': -1, 'b': -1, '\u266d': -1,  # simple flat
     64            u'♮': 0, '\u266e': 0, None: 0,    # natural
     65            '#': +1, u'♯': +1, '\u266f': +1,  # sharp
     66            u'𝄪': +2,                         # double sharp
    2467            }
    2568    _valid_octaves = range(-1, 10)
    2669    if not isinstance(note, str_instances):
    27         raise TypeError("a string is required, got %s (%s)" % (note, str(type(note))))
     70        msg = "a string is required, got {:s} ({:s})"
     71        raise TypeError(msg.format(str(type(note)), repr(note)))
    2872    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))
    31     notename, modifier, octave = [None]*3
     73        msg = "string of 2 to 4 characters expected, got {:d} ({:s})"
     74        raise ValueError(msg.format(len(note), note))
     75    notename, modifier, octave = [None] * 3
    3276
    3377    if len(note) == 4:
     
    5296        raise ValueError("%s is not a valid octave" % octave)
    5397
    54     midi = 12 + octave * 12 + _valid_notenames[notename] + _valid_modifiers[modifier]
     98    midi = (octave + 1) * 12 + _valid_notenames[notename] \
     99                             + _valid_modifiers[modifier]
    55100    if midi > 127:
    56101        raise ValueError("%s is outside of the range C-2 to G8" % note)
    57102    return midi
    58103
     104
    59105def midi2note(midi):
    60     " convert midi note number to note name, e.g. [0, 127] -> [C-1, G9] "
     106    """Convert midi note number to note name.
     107
     108    Parameters
     109    ----------
     110    midi : int [0, 128]
     111        input midi note number
     112
     113    Returns
     114    -------
     115    str
     116        note name
     117
     118    Examples
     119    --------
     120    >>> aubio.midi2note(70)
     121    'A#4'
     122    >>> aubio.midi2note(59)
     123    'B3'
     124
     125    Raises
     126    ------
     127    TypeError
     128        If `midi` was not an integer.
     129    ValueError
     130        If `midi` is out of the range `[0, 128]`.
     131
     132    See Also
     133    --------
     134    note2midi, miditofreq, freqtomidi
     135    """
    61136    if not isinstance(midi, int_instances):
    62137        raise TypeError("an integer is required, got %s" % midi)
    63138    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']
     139        msg = "an integer between 0 and 127 is excepted, got {:d}"
     140        raise ValueError(msg.format(midi))
     141    _valid_notenames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#',
     142                        'A', 'A#', 'B']
    66143    return _valid_notenames[midi % 12] + str(int(midi / 12) - 1)
    67144
     145
    68146def 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)))
     147    """Convert frequency in Hz to nearest note name.
     148
     149    Parameters
     150    ----------
     151    freq : float [0, 23000[
     152        input frequency, in Hz
     153
     154    Returns
     155    -------
     156    str
     157        name of the nearest note
     158
     159    Example
     160    -------
     161    >>> aubio.freq2note(440)
     162    'A4'
     163    >>> aubio.freq2note(220.1)
     164    'A3'
     165    """
     166    nearest_note = int(freqtomidi(freq) + .5)
     167    return midi2note(nearest_note)
     168
     169
     170def note2freq(note):
     171    """Convert note name to corresponding frequency, in Hz.
     172
     173    Parameters
     174    ----------
     175    note : str
     176        input note name
     177
     178    Returns
     179    -------
     180    freq : float [0, 23000[
     181        frequency, in Hz
     182
     183    Example
     184    -------
     185    >>> aubio.note2freq('A4')
     186    440
     187    >>> aubio.note2freq('A3')
     188    220.1
     189    """
     190    midi = note2midi(note)
     191    return miditofreq(midi)
  • python/lib/aubio/slicing.py

    r086a45b rf2f1b10  
    66_max_timestamp = 1e120
    77
     8
    89def 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 """
     10                           output_dir=None, samplerate=0, hopsize=256,
     11                           create_first=False):
     12    """Slice a sound file at given timestamps.
    1113
    12     if timestamps is None or len(timestamps) == 0:
     14    This function reads `source_file` and creates slices, new smaller
     15    files each starting at `t` in `timestamps`, a list of integer
     16    corresponding to time locations in `source_file`, in samples.
     17
     18    If `timestamps_end` is unspecified, the slices will end at
     19    `timestamps_end[n] = timestamps[n+1]-1`, or the end of file.
     20    Otherwise, `timestamps_end` should be a list with the same length
     21    as `timestamps` containing the locations of the end of each slice.
     22
     23    If `output_dir` is unspecified, the new slices will be written in
     24    the current directory. If `output_dir` is a string, new slices
     25    will be written in `output_dir`, after creating the directory if
     26    required.
     27
     28    The default `samplerate` is 0, meaning the original sampling rate
     29    of `source_file` will be used. When using a sampling rate
     30    different to the one of the original files, `timestamps` and
     31    `timestamps_end` should be expressed in the re-sampled signal.
     32
     33    The `hopsize` parameter simply tells :class:`source` to use this
     34    hopsize and does not change the output slices.
     35
     36    If `create_first` is True and `timestamps` does not start with `0`, the
     37    first slice from `0` to `timestamps[0] - 1` will be automatically added.
     38
     39    Parameters
     40    ----------
     41    source_file : str
     42        path of the resource to slice
     43    timestamps : :obj:`list` of :obj:`int`
     44        time stamps at which to slice, in samples
     45    timestamps_end : :obj:`list` of :obj:`int` (optional)
     46        time stamps at which to end the slices
     47    output_dir : str (optional)
     48        output directory to write the slices to
     49    samplerate : int (optional)
     50        samplerate to read the file at
     51    hopsize : int (optional)
     52        number of samples read from source per iteration
     53    create_first : bool (optional)
     54        always create the slice at the start of the file
     55
     56    Examples
     57    --------
     58    Create two slices: the first slice starts at the beginning of the
     59    input file `loop.wav` and lasts exactly one second, starting at
     60    sample `0` and ending at sample `44099`; the second slice starts
     61    at sample `44100` and lasts until the end of the input file:
     62
     63    >>> aubio.slice_source_at_stamps('loop.wav', [0, 44100])
     64
     65    Create one slice, from 1 second to 2 seconds:
     66
     67    >>> aubio.slice_source_at_stamps('loop.wav', [44100], [44100 * 2 - 1])
     68
     69    Notes
     70    -----
     71    Slices may be overlapping. If `timestamps_end` is `1` element
     72    shorter than `timestamps`, the last slice will end at the end of
     73    the file.
     74    """
     75
     76    if not timestamps:
    1377        raise ValueError("no timestamps given")
    1478
    15     if timestamps[0] != 0:
     79    if timestamps[0] != 0 and create_first:
    1680        timestamps = [0] + timestamps
    1781        if timestamps_end is not None:
     
    1983
    2084    if timestamps_end is not None:
    21         if len(timestamps_end) != len(timestamps):
     85        if len(timestamps_end) == len(timestamps) - 1:
     86            timestamps_end = timestamps_end + [_max_timestamp]
     87        elif len(timestamps_end) != len(timestamps):
    2288            raise ValueError("len(timestamps_end) != len(timestamps)")
    2389    else:
     
    2591
    2692    regions = list(zip(timestamps, timestamps_end))
    27     #print regions
    2893
    2994    source_base_name, _ = os.path.splitext(os.path.basename(source_file))
     
    3398        source_base_name = os.path.join(output_dir, source_base_name)
    3499
    35     def new_sink_name(source_base_name, timestamp, samplerate):
    36         """ create a sink based on a timestamp in samples, converted in seconds """
     100    def _new_sink_name(source_base_name, timestamp, samplerate):
     101        # create name based on a timestamp in samples, converted in seconds
    37102        timestamp_seconds = timestamp / float(samplerate)
    38103        return source_base_name + "_%011.6f" % timestamp_seconds + '.wav'
     
    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]:
    52             #print "getting", regions[0], "at", total_frames
     116        while regions and total_frames + read >= regions[0][0]:
    53117            # get next region
    54118            start_stamp, end_stamp = regions.pop(0)
    55119            # create a name for the sink
    56             new_sink_path = new_sink_name(source_base_name, start_stamp, samplerate)
     120            new_sink_path = _new_sink_name(source_base_name, start_stamp,
     121                                           samplerate)
    57122            # create its sink
    58123            _sink = sink(new_sink_path, samplerate, _source.channels)
    59124            # create a dictionary containing all this
    60             new_slice = {'start_stamp': start_stamp, 'end_stamp': end_stamp, 'sink': _sink}
     125            new_slice = {'start_stamp': start_stamp, 'end_stamp': end_stamp,
     126                         'sink': _sink}
    61127            # append the dictionary to the current list of slices
    62128            slices.append(new_slice)
     
    70136            # number of samples yet to written be until end of region
    71137            remaining = end_stamp - total_frames + 1
    72             #print current_slice, remaining, start
    73138            # not enough frames remaining, time to split
    74139            if remaining < read:
     
    76141                    # write remaining samples from current region
    77142                    _sink.do_multi(vec[:, start:remaining], remaining - start)
    78                     #print "closing region", "remaining", remaining
    79143                    # close this file
    80144                    _sink.close()
     
    83147                _sink.do_multi(vec[:, start:read], read - start)
    84148        total_frames += read
     149        # remove old slices
     150        slices = list(filter(lambda s: s['end_stamp'] > total_frames,
     151                             slices))
    85152        if read < hopsize:
    86153            break
  • python/lib/gen_code.py

    r086a45b rf2f1b10  
    33    'buf_size': 'Py_default_vector_length',
    44    'win_s': 'Py_default_vector_length',
     5    'size': 'Py_default_vector_length',
    56    # and here too
    67    'hop_size': 'Py_default_vector_length / 2',
     
    8384        'filterbank': 'self->n_filters',
    8485        'tss': 'self->buf_size',
     86        'dct': 'self->size',
    8587        }
    8688
     
    177179        self.do_outputs = get_params_types_names(self.do_proto)[2:]
    178180        struct_output_str = ["PyObject *{0[name]}; {1} c_{0[name]}".format(i, i['type'][:-1]) for i in self.do_outputs]
     181        if len(self.prototypes['rdo']):
     182            rdo_outputs = get_params_types_names(prototypes['rdo'][0])[2:]
     183            struct_output_str += ["PyObject *{0[name]}; {1} c_{0[name]}".format(i, i['type'][:-1]) for i in rdo_outputs]
     184            self.outputs += rdo_outputs
    179185        self.struct_outputs = ";\n    ".join(struct_output_str)
    180186
     
    191197            out += self.gen_del()
    192198            out += self.gen_do()
     199            if len(self.prototypes['rdo']):
     200                self.do_proto = self.prototypes['rdo'][0]
     201                self.do_inputs = [get_params_types_names(self.do_proto)[1]]
     202                self.do_outputs = get_params_types_names(self.do_proto)[2:]
     203                out += self.gen_do(method='rdo')
    193204            out += self.gen_memberdef()
    194205            out += self.gen_set()
     
    221232
    222233    def gen_doc(self):
    223         out = """
    224 // TODO: add documentation
    225 static char Py_{shortname}_doc[] = \"undefined\";
     234        sig = []
     235        for p in self.input_params:
     236            name = p['name']
     237            defval = aubiodefvalue[name].replace('"','\\\"')
     238            sig.append("{name}={defval}".format(defval=defval, name=name))
     239        out = """
     240#ifndef PYAUBIO_{shortname}_doc
     241#define PYAUBIO_{shortname}_doc "{shortname}({sig})"
     242#endif /* PYAUBIO_{shortname}_doc */
     243
     244static char Py_{shortname}_doc[] = ""
     245PYAUBIO_{shortname}_doc
     246"";
    226247"""
    227         return out.format(**self.__dict__)
     248        return out.format(sig=', '.join(sig), **self.__dict__)
    228249
    229250    def gen_new(self):
     
    371392        return out
    372393
    373     def gen_do(self):
     394    def gen_do(self, method = 'do'):
    374395        out = """
    375396// do {shortname}
    376397static PyObject*
    377 Py_{shortname}_do  (Py_{shortname} * self, PyObject * args)
    378 {{""".format(**self.__dict__)
     398Pyaubio_{shortname}_{method}  (Py_{shortname} * self, PyObject * args)
     399{{""".format(method = method, **self.__dict__)
    379400        input_params = self.do_inputs
    380401        output_params = self.do_outputs
     
    452473""".format(**self.__dict__)
    453474        for set_param in self.prototypes['set']:
    454             params = get_params_types_names(set_param)[1]
    455             paramtype = params['type']
     475            params = get_params_types_names(set_param)[1:]
     476            param = self.shortname.split('_set_')[-1]
     477            paramdecls = "".join(["""
     478   {0} {1};""".format(p['type'], p['name']) for p in params])
    456479            method_name = get_name(set_param)
    457480            param = method_name.split('aubio_'+self.shortname+'_set_')[-1]
    458             pyparamtype = pyargparse_chars[paramtype]
     481            refs = ", ".join(["&%s" % p['name'] for p in params])
     482            paramlist = ", ".join(["%s" % p['name'] for p in params])
     483            if len(params):
     484                paramlist = "," + paramlist
     485            pyparamtypes = ''.join([pyargparse_chars[p['type']] for p in params])
    459486            out += """
    460487static PyObject *
     
    462489{{
    463490  uint_t err = 0;
    464   {paramtype} {param};
    465 
    466   if (!PyArg_ParseTuple (args, "{pyparamtype}", &{param})) {{
     491  {paramdecls}
     492""".format(param = param, paramdecls = paramdecls, **self.__dict__)
     493
     494            if len(refs) and len(pyparamtypes):
     495                out += """
     496
     497  if (!PyArg_ParseTuple (args, "{pyparamtypes}", {refs})) {{
    467498    return NULL;
    468499  }}
    469   err = aubio_{shortname}_set_{param} (self->o, {param});
     500""".format(pyparamtypes = pyparamtypes, refs = refs)
     501
     502            out += """
     503  err = aubio_{shortname}_set_{param} (self->o {paramlist});
    470504
    471505  if (err > 0) {{
    472     PyErr_SetString (PyExc_ValueError, "error running aubio_{shortname}_set_{param}");
     506    if (PyErr_Occurred() == NULL) {{
     507      PyErr_SetString (PyExc_ValueError, "error running aubio_{shortname}_set_{param}");
     508    }} else {{
     509      // change the RuntimeError into ValueError
     510      PyObject *type, *value, *traceback;
     511      PyErr_Fetch(&type, &value, &traceback);
     512      PyErr_Restore(PyExc_ValueError, value, traceback);
     513    }}
    473514    return NULL;
    474515  }}
    475516  Py_RETURN_NONE;
    476517}}
    477 """.format(param = param, paramtype = paramtype, pyparamtype = pyparamtype, **self.__dict__)
     518""".format(param = param, refs = refs, paramdecls = paramdecls,
     519        pyparamtypes = pyparamtypes, paramlist = paramlist, **self.__dict__)
    478520        return out
    479521
     
    516558  {{"{shortname}", (PyCFunction) Py{name},
    517559    METH_NOARGS, ""}},""".format(name = name, shortname = shortname)
     560        for m in self.prototypes['rdo']:
     561            name = get_name(m)
     562            shortname = name.replace('aubio_%s_' % self.shortname, '')
     563            out += """
     564  {{"{shortname}", (PyCFunction) Py{name},
     565    METH_VARARGS, ""}},""".format(name = name, shortname = shortname)
    518566        out += """
    519567  {NULL} /* sentinel */
     
    541589  0,
    542590  0,
    543   (ternaryfunc)Py_{shortname}_do,
     591  (ternaryfunc)Pyaubio_{shortname}_do,
    544592  0,
    545593  0,
  • python/lib/gen_external.py

    r086a45b rf2f1b10  
    44import subprocess
    55import glob
     6from distutils.sysconfig import customize_compiler
     7from gen_code import MappedObject
    68
    79header = os.path.join('src', 'aubio.h')
     
    5052def get_preprocessor():
    5153    # findout which compiler to use
    52     from distutils.sysconfig import customize_compiler
    5354    compiler_name = distutils.ccompiler.get_default_compiler()
    5455    compiler = distutils.ccompiler.new_compiler(compiler=compiler_name)
     
    7475        cpp_cmd += ['-E']
    7576
     77    # On win-amd64 (py3.x), the default compiler is cross-compiling, from x86
     78    # to amd64 with %WIN_SDK_ROOT%\x86_amd64\cl.exe, but using this binary as a
     79    # pre-processor generates no output, so we use %WIN_SDK_ROOT%\cl.exe
     80    # instead.
     81    if len(cpp_cmd) > 1 and 'cl.exe' in cpp_cmd[-2]:
     82        plat = os.path.basename(os.path.dirname(cpp_cmd[-2]))
     83        if plat == 'x86_amd64':
     84            print('workaround on win64 to avoid empty pre-processor output')
     85            cpp_cmd[-2] = cpp_cmd[-2].replace('x86_amd64', '')
     86        elif True in ['amd64' in f for f in cpp_cmd]:
     87            print('warning: not using workaround for', cpp_cmd[0], plat)
     88
    7689    if not cpp_cmd:
    7790        print("Warning: could not guess preprocessor, using env's CC")
    7891        cpp_cmd = os.environ.get('CC', 'cc').split()
    7992        cpp_cmd += ['-E']
    80     cpp_cmd += ['-x', 'c']  # force C language (emcc defaults to c++)
     93    if 'emcc' in cpp_cmd:
     94        cpp_cmd += ['-x', 'c'] # emcc defaults to c++, force C language
    8195    return cpp_cmd
    8296
     
    8599    ''' return a dense and preprocessed  string of all c declarations implied by aubio.h
    86100    '''
     101    cpp_output = get_cpp_output(header=header, usedouble=usedouble)
     102    return filter_cpp_output (cpp_output)
     103
     104
     105def get_cpp_output(header=header, usedouble=False):
     106    ''' find and run a C pre-processor on aubio.h '''
    87107    cpp_cmd = get_preprocessor()
    88108
     
    101121    proc = subprocess.Popen(cpp_cmd,
    102122                            stderr=subprocess.PIPE,
    103                             stdout=subprocess.PIPE)
     123                            stdout=subprocess.PIPE,
     124                            universal_newlines=True)
    104125    assert proc, 'Proc was none'
    105126    cpp_output = proc.stdout.read()
    106127    err_output = proc.stderr.read()
     128    if err_output:
     129        print("Warning: preprocessor produced errors or warnings:\n%s" \
     130                % err_output)
    107131    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)
     132        raise_msg = "preprocessor output is empty! Running command " \
     133                + "\"%s\" failed" % " ".join(cpp_cmd)
     134        if err_output:
     135            raise_msg += " with stderr: \"%s\"" % err_output
     136        else:
     137            raise_msg += " with no stdout or stderr"
     138        raise Exception(raise_msg)
    111139    if not isinstance(cpp_output, list):
    112         cpp_output = [l.strip() for l in cpp_output.decode('utf8').split('\n')]
    113 
    114     cpp_output = filter(lambda y: len(y) > 1, cpp_output)
     140        cpp_output = [l.strip() for l in cpp_output.split('\n')]
     141
     142    return cpp_output
     143
     144def filter_cpp_output(cpp_raw_output):
     145    ''' prepare cpp-output for parsing '''
     146    cpp_output = filter(lambda y: len(y) > 1, cpp_raw_output)
    115147    cpp_output = list(filter(lambda y: not y.startswith('#'), cpp_output))
    116148
     
    182214            shortname = o[6:-2]  # without aubio_ prefix and _t suffix
    183215
    184         lib[shortname] = {'struct': [], 'new': [], 'del': [], 'do': [], 'get': [], 'set': [], 'other': []}
     216        lib[shortname] = {'struct': [], 'new': [], 'del': [], 'do': [], 'rdo': [], 'get': [], 'set': [], 'other': []}
    185217        lib[shortname]['longname'] = o
    186218        lib[shortname]['shortname'] = shortname
     
    196228                elif '_do' in fn:
    197229                    lib[shortname]['do'].append(fn)
     230                elif '_rdo' in fn:
     231                    lib[shortname]['rdo'].append(fn)
    198232                elif 'new_' in fn:
    199233                    lib[shortname]['new'].append(fn)
     
    243277
    244278    sources_list = []
    245     try:
    246         from .gen_code import MappedObject
    247     except (SystemError, ValueError):
    248         from gen_code import MappedObject
    249279    for o in lib:
    250280        out = source_header
  • python/lib/moresetuptools.py

    r086a45b rf2f1b10  
    33import sys, os, glob, subprocess
    44import distutils, distutils.command.clean, distutils.dir_util
    5 from .gen_external import generate_external, header, output_path
     5from gen_external import generate_external, header, output_path
    66
    77from this_version import get_aubio_version
     
    6969    for define_macro in ['HAVE_STDLIB_H', 'HAVE_STDIO_H',
    7070                         'HAVE_MATH_H', 'HAVE_STRING_H',
    71                          'HAVE_C99_VARARGS_MACROS',
     71                         'HAVE_ERRNO_H', 'HAVE_C99_VARARGS_MACROS',
    7272                         'HAVE_LIMITS_H', 'HAVE_STDARG_H',
    7373                         'HAVE_MEMCPY_HACKS']:
  • python/tests/test_aubio.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43from numpy.testing import TestCase
    54
     
    1615
    1716if __name__ == '__main__':
     17    from unittest import main
    1818    main()
    19 
  • python/tests/test_aubio_cmd.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
     3from numpy.testing import TestCase
    34import aubio.cmd
    4 from nose2 import main
    5 from numpy.testing import TestCase
    65
    76class aubio_cmd(TestCase):
     
    2019
    2120    def test_samples2seconds(self):
    22         self.assertEqual(aubio.cmd.samples2seconds(3200, 32000), "0.100000\t")
     21        self.assertEqual(aubio.cmd.samples2seconds(3200, 32000),
     22                "0.100000\t")
    2323
    2424    def test_samples2milliseconds(self):
    25         self.assertEqual(aubio.cmd.samples2milliseconds(3200, 32000), "100.000000\t")
     25        self.assertEqual(aubio.cmd.samples2milliseconds(3200, 32000),
     26                "100.000000\t")
    2627
    2728    def test_samples2samples(self):
    28         self.assertEqual(aubio.cmd.samples2samples(3200, 32000), "3200\t")
     29        self.assertEqual(aubio.cmd.samples2samples(3200, 32000),
     30                "3200\t")
    2931
    3032if __name__ == '__main__':
     33    from unittest import main
    3134    main()
  • python/tests/test_aubio_cut.py

    r086a45b rf2f1b10  
    22
    33import aubio.cut
    4 from nose2 import main
    54from numpy.testing import TestCase
    65
     
    1413
    1514if __name__ == '__main__':
     15    from unittest import main
    1616    main()
  • python/tests/test_cvec.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43import numpy as np
    54from numpy.testing import TestCase, assert_equal
     
    142141
    143142if __name__ == '__main__':
     143    from unittest import main
    144144    main()
  • python/tests/test_fft.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43from numpy.testing import TestCase
    54from numpy.testing import assert_equal, assert_almost_equal
     
    143142        assert_almost_equal ( r[1:], 0)
    144143
     144class aubio_fft_odd_sizes(TestCase):
     145
     146    def test_reconstruct_with_odd_size(self):
     147        win_s = 29
     148        self.recontruct(win_s, 'odd sizes not supported')
     149
     150    def test_reconstruct_with_radix15(self):
     151        win_s = 2 ** 4 * 15
     152        self.recontruct(win_s, 'radix 15 supported')
     153
     154    def test_reconstruct_with_radix5(self):
     155        win_s = 2 ** 4 * 5
     156        self.recontruct(win_s, 'radix 5 supported')
     157
     158    def test_reconstruct_with_radix3(self):
     159        win_s = 2 ** 4 * 3
     160        self.recontruct(win_s, 'radix 3 supported')
     161
     162    def recontruct(self, win_s, skipMessage):
     163        try:
     164            f = fft(win_s)
     165        except RuntimeError:
     166            self.skipTest(skipMessage)
     167        input_signal = fvec(win_s)
     168        input_signal[win_s//2] = 1
     169        c = f(input_signal)
     170        output_signal = f.rdo(c)
     171        assert_almost_equal(input_signal, output_signal)
     172
     173class aubio_fft_wrong_params(TestCase):
     174
    145175    def test_large_input_timegrain(self):
    146176        win_s = 1024
     
    170200        with self.assertRaises(ValueError):
    171201            f.rdo(s)
    172 
    173 class aubio_fft_wrong_params(TestCase):
    174202
    175203    def test_wrong_buf_size(self):
     
    177205        with self.assertRaises(ValueError):
    178206            fft(win_s)
    179 
    180     def test_buf_size_not_power_of_two(self):
    181         # when compiled with fftw3, aubio supports non power of two fft sizes
    182         win_s = 320
    183         try:
    184             with self.assertRaises(RuntimeError):
    185                 fft(win_s)
    186         except AssertionError:
    187             self.skipTest('creating aubio.fft with size %d did not fail' % win_s)
    188207
    189208    def test_buf_size_too_small(self):
     
    193212
    194213if __name__ == '__main__':
     214    from unittest import main
    195215    main()
  • python/tests/test_filter.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43from numpy.testing import TestCase, assert_equal, assert_almost_equal
    54from aubio import fvec, digital_filter
    6 from .utils import array_from_text_file
     5from utils import array_from_text_file
    76
    87class aubio_filter_test_case(TestCase):
     
    7877            f.set_biquad(0., 0., 0, 0., 0.)
    7978
     79    def test_all_available_presets(self):
     80        f = digital_filter(7)
     81        for sr in [8000, 11025, 16000, 22050, 24000, 32000,
     82                44100, 48000, 88200, 96000, 192000]:
     83            f.set_a_weighting(sr)
     84        f = digital_filter(5)
     85        for sr in [8000, 11025, 16000, 22050, 24000, 32000,
     86                44100, 48000, 88200, 96000, 192000]:
     87            f.set_c_weighting(sr)
     88
    8089class aubio_filter_wrong_params(TestCase):
    8190
     
    8594
    8695if __name__ == '__main__':
     96    from unittest import main
    8797    main()
  • python/tests/test_filterbank.py

    r086a45b rf2f1b10  
    55
    66from aubio import cvec, filterbank, float_type
    7 from .utils import array_from_text_file
     7from utils import array_from_text_file
    88
    99class aubio_filterbank_test_case(TestCase):
     
    8888
    8989if __name__ == '__main__':
    90     import nose2
    91     nose2.main()
     90    from unittest import main
     91    main()
  • python/tests/test_filterbank_mel.py

    r086a45b rf2f1b10  
    33import numpy as np
    44from numpy.testing import TestCase, assert_equal, assert_almost_equal
     5from _tools import assert_warns
    56
    6 from aubio import cvec, filterbank, float_type
    7 
    8 import warnings
    9 warnings.filterwarnings('ignore', category=UserWarning, append=True)
     7from aubio import fvec, cvec, filterbank, float_type
    108
    119class aubio_filterbank_mel_test_case(TestCase):
     
    4846                    0.02133301, 0.02133301, 0.02133311, 0.02133334, 0.02133345])
    4947
     48    def test_triangle_freqs_with_zeros(self):
     49        """make sure set_triangle_bands works when list starts with 0"""
     50        freq_list = [0, 40, 80]
     51        freqs = np.array(freq_list, dtype = float_type)
     52        f = filterbank(len(freqs)-2, 1024)
     53        f.set_triangle_bands(freqs, 48000)
     54        assert_equal ( f(cvec(1024)), 0)
     55        self.assertIsInstance(f.get_coeffs(), np.ndarray)
     56
     57    def test_triangle_freqs_with_wrong_negative(self):
     58        """make sure set_triangle_bands fails when list contains a negative"""
     59        freq_list = [-10, 0, 80]
     60        f = filterbank(len(freq_list)-2, 1024)
     61        with self.assertRaises(ValueError):
     62            f.set_triangle_bands(fvec(freq_list), 48000)
     63
     64    def test_triangle_freqs_with_wrong_ordering(self):
     65        """make sure set_triangle_bands fails when list not ordered"""
     66        freq_list = [0, 80, 40]
     67        f = filterbank(len(freq_list)-2, 1024)
     68        with self.assertRaises(ValueError):
     69            f.set_triangle_bands(fvec(freq_list), 48000)
     70
     71    def test_triangle_freqs_with_large_freq(self):
     72        """make sure set_triangle_bands warns when freq > nyquist"""
     73        samplerate = 22050
     74        freq_list = [0, samplerate//4, samplerate // 2 + 1]
     75        f = filterbank(len(freq_list)-2, 1024)
     76        with assert_warns(UserWarning):
     77            f.set_triangle_bands(fvec(freq_list), samplerate)
     78
     79    def test_triangle_freqs_with_not_enough_filters(self):
     80        """make sure set_triangle_bands warns when not enough filters"""
     81        samplerate = 22050
     82        freq_list = [0, 100, 1000, 4000, 8000, 10000]
     83        f = filterbank(len(freq_list)-3, 1024)
     84        with assert_warns(UserWarning):
     85            f.set_triangle_bands(fvec(freq_list), samplerate)
     86
     87    def test_triangle_freqs_with_too_many_filters(self):
     88        """make sure set_triangle_bands warns when too many filters"""
     89        samplerate = 22050
     90        freq_list = [0, 100, 1000, 4000, 8000, 10000]
     91        f = filterbank(len(freq_list)-1, 1024)
     92        with assert_warns(UserWarning):
     93            f.set_triangle_bands(fvec(freq_list), samplerate)
     94
     95    def test_triangle_freqs_with_double_value(self):
     96        """make sure set_triangle_bands works with 2 duplicate freqs"""
     97        samplerate = 22050
     98        freq_list = [0, 100, 1000, 4000, 4000, 4000, 10000]
     99        f = filterbank(len(freq_list)-2, 1024)
     100        with assert_warns(UserWarning):
     101            f.set_triangle_bands(fvec(freq_list), samplerate)
     102
     103    def test_triangle_freqs_with_triple(self):
     104        """make sure set_triangle_bands works with 3 duplicate freqs"""
     105        samplerate = 22050
     106        freq_list = [0, 100, 1000, 4000, 4000, 4000, 10000]
     107        f = filterbank(len(freq_list)-2, 1024)
     108        with assert_warns(UserWarning):
     109            f.set_triangle_bands(fvec(freq_list), samplerate)
     110
     111
     112    def test_triangle_freqs_without_norm(self):
     113        """make sure set_triangle_bands works without """
     114        samplerate = 22050
     115        freq_list = fvec([0, 100, 1000, 10000])
     116        f = filterbank(len(freq_list) - 2, 1024)
     117        f.set_norm(0)
     118        f.set_triangle_bands(freq_list, samplerate)
     119        expected = f.get_coeffs()
     120        f.set_norm(1)
     121        f.set_triangle_bands(fvec(freq_list), samplerate)
     122        assert_almost_equal(f.get_coeffs().T,
     123                expected.T * 2. / (freq_list[2:] - freq_list[:-2]))
     124
     125    def test_triangle_freqs_wrong_norm(self):
     126        f = filterbank(10, 1024)
     127        with self.assertRaises(ValueError):
     128            f.set_norm(-1)
     129
     130    def test_triangle_freqs_with_power(self):
     131        f = filterbank(9, 1024)
     132        freqs = fvec([40, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 15000,
     133            24000])
     134        f.set_power(2)
     135        f.set_triangle_bands(freqs, 48000)
     136        spec = cvec(1024)
     137        spec.norm[:] = .1
     138        expected = fvec([0.02070313, 0.02138672, 0.02127604, 0.02135417,
     139            0.02133301, 0.02133301, 0.02133311, 0.02133334, 0.02133345])
     140        expected /= 100.
     141        assert_almost_equal(f(spec), expected)
     142
     143    def test_mel_coeffs(self):
     144        f = filterbank(40, 1024)
     145        f.set_mel_coeffs(44100, 0, 44100 / 2)
     146
     147    def test_zero_fmax(self):
     148        f = filterbank(40, 1024)
     149        f.set_mel_coeffs(44100, 0, 0)
     150
     151    def test_wrong_mel_coeffs(self):
     152        f = filterbank(40, 1024)
     153        with self.assertRaises(ValueError):
     154            f.set_mel_coeffs_slaney(0)
     155        with self.assertRaises(ValueError):
     156            f.set_mel_coeffs(44100, 0, -44100 / 2)
     157        with self.assertRaises(ValueError):
     158            f.set_mel_coeffs(44100, -0.1, 44100 / 2)
     159        with self.assertRaises(ValueError):
     160            f.set_mel_coeffs(-44100, 0.1, 44100 / 2)
     161        with self.assertRaises(ValueError):
     162            f.set_mel_coeffs_htk(-1, 0, 0)
     163
     164    def test_mel_coeffs_htk(self):
     165        f = filterbank(40, 1024)
     166        f.set_mel_coeffs_htk(44100, 0, 44100 / 2)
     167
     168
    50169if __name__ == '__main__':
    51     import nose2
    52     nose2.main()
     170    from unittest import main
     171    main()
  • python/tests/test_fvec.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43import numpy as np
    54from numpy.testing import TestCase, assert_equal, assert_almost_equal
     
    6059        self.assertRaises(IndexError, a.__getitem__, 3)
    6160        self.assertRaises(IndexError, a.__getitem__, 2)
     61
     62    def test_wrong_dimensions(self):
     63        a = np.array([[[1, 2], [3, 4]]], dtype=float_type)
     64        self.assertRaises(ValueError, fvec, a)
     65
     66    def test_wrong_size(self):
     67        a = np.ndarray([0,], dtype=float_type)
     68        self.assertRaises(ValueError, fvec, a)
    6269
    6370class aubio_wrong_fvec_input(TestCase):
     
    141148
    142149if __name__ == '__main__':
     150    from unittest import main
    143151    main()
  • python/tests/test_mathutils.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43from numpy.testing import TestCase, assert_equal
    54from numpy import array, arange, isnan, isinf
     
    102101
    103102if __name__ == '__main__':
     103    from unittest import main
    104104    main()
  • python/tests/test_mfcc.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from nose2 import main
    4 from nose2.tools import params
     3from _tools import parametrize, assert_raises
    54from numpy import random, count_nonzero
    65from numpy.testing import TestCase
     
    1615new_deflts = [1024, 40, 13, 44100]
    1716
    18 class aubio_mfcc(TestCase):
     17class Test_aubio_mfcc(object):
    1918
    20     def setUp(self):
    21         self.o = mfcc()
     19    members_args = 'name'
    2220
    23     def test_default_creation(self):
    24         pass
    25 
    26     def test_delete(self):
    27         del self.o
    28 
    29     @params(*new_params)
     21    @parametrize(members_args, new_params)
    3022    def test_read_only_member(self, name):
    31         o = self.o
    32         with self.assertRaises((TypeError, AttributeError)):
     23        o = mfcc()
     24        with assert_raises((TypeError, AttributeError)):
    3325            setattr(o, name, 0)
    3426
    35     @params(*zip(new_params, new_deflts))
     27    @parametrize('name, expected', zip(new_params, new_deflts))
    3628    def test_default_param(self, name, expected):
    3729        """ test mfcc.{:s} = {:d} """.format(name, expected)
    38         o = self.o
    39         self.assertEqual( getattr(o, name), expected)
     30        o = mfcc()
     31        assert getattr(o, name) == expected
    4032
    4133class aubio_mfcc_wrong_params(TestCase):
     
    8375
    8476
    85 class aubio_mfcc_all_parameters(TestCase):
     77class Test_aubio_mfcc_all_parameters(object):
    8678
    87     @params(
     79    run_values = [
    8880            (2048, 40, 13, 44100),
    8981            (1024, 40, 13, 44100),
     
    10193            (1024, 40, 40, 44100),
    10294            (1024, 40, 3, 44100),
    103             )
     95            ]
     96    run_args = ['buf_size', 'n_filters', 'n_coeffs', 'samplerate']
     97
     98    @parametrize(run_args, run_values)
    10499    def test_run_with_params(self, buf_size, n_filters, n_coeffs, samplerate):
    105100        " check mfcc can run with reasonable parameters "
     
    111106        #print coeffs
    112107
     108
     109class aubio_mfcc_fb_params(TestCase):
     110
     111    def test_set_scale(self):
     112        buf_size, n_filters, n_coeffs, samplerate = 512, 20, 10, 16000
     113        m = mfcc(buf_size, n_filters, n_coeffs, samplerate)
     114        m.set_scale(10.5)
     115        assert m.get_scale() == 10.5
     116        m(cvec(buf_size))
     117
     118    def test_set_power(self):
     119        buf_size, n_filters, n_coeffs, samplerate = 512, 20, 10, 16000
     120        m = mfcc(buf_size, n_filters, n_coeffs, samplerate)
     121        m.set_power(2.5)
     122        assert m.get_power() == 2.5
     123        m(cvec(buf_size))
     124
     125    def test_set_mel_coeffs(self):
     126        buf_size, n_filters, n_coeffs, samplerate = 512, 20, 10, 16000
     127        m = mfcc(buf_size, n_filters, n_coeffs, samplerate)
     128        m.set_mel_coeffs(0., samplerate/2.)
     129        m(cvec(buf_size))
     130
     131    def test_set_mel_coeffs_htk(self):
     132        buf_size, n_filters, n_coeffs, samplerate = 512, 20, 10, 16000
     133        m = mfcc(buf_size, n_filters, n_coeffs, samplerate)
     134        m.set_mel_coeffs_htk(0., samplerate/2.)
     135        m(cvec(buf_size))
     136
     137    def test_set_mel_coeffs_slaney(self):
     138        buf_size, n_filters, n_coeffs, samplerate = 512, 40, 10, 16000
     139        m = mfcc(buf_size, n_filters, n_coeffs, samplerate)
     140        m.set_mel_coeffs_slaney()
     141        m(cvec(buf_size))
     142        assert m.get_power() == 1
     143        assert m.get_scale() == 1
     144
    113145if __name__ == '__main__':
    114     main()
     146    from _tools import run_module_suite
     147    run_module_suite()
  • python/tests/test_midi2note.py

    r086a45b rf2f1b10  
    33
    44from aubio import midi2note
    5 from nose2.tools import params
    6 import unittest
     5from _tools import parametrize, assert_raises
    76
    87list_of_known_midis = (
     
    1615        )
    1716
    18 class midi2note_good_values(unittest.TestCase):
     17class Test_midi2note_good_values(object):
    1918
    20     @params(*list_of_known_midis)
     19    @parametrize('midi, note', list_of_known_midis)
    2120    def test_midi2note_known_values(self, midi, note):
    2221        " known values are correctly converted "
    23         self.assertEqual ( midi2note(midi), note )
     22        assert midi2note(midi) == (note)
    2423
    25 class midi2note_wrong_values(unittest.TestCase):
     24class Test_midi2note_wrong_values(object):
    2625
    2726    def test_midi2note_negative_value(self):
    2827        " fails when passed a negative value "
    29         self.assertRaises(ValueError, midi2note, -2)
     28        assert_raises(ValueError, midi2note, -2)
    3029
    3130    def test_midi2note_large(self):
    3231        " fails when passed a value greater than 127 "
    33         self.assertRaises(ValueError, midi2note, 128)
     32        assert_raises(ValueError, midi2note, 128)
    3433
    3534    def test_midi2note_floating_value(self):
    3635        " fails when passed a floating point "
    37         self.assertRaises(TypeError, midi2note, 69.2)
     36        assert_raises(TypeError, midi2note, 69.2)
    3837
    3938    def test_midi2note_character_value(self):
    4039        " fails when passed a value that can not be transformed to integer "
    41         self.assertRaises(TypeError, midi2note, "a")
     40        assert_raises(TypeError, midi2note, "a")
    4241
    4342if __name__ == '__main__':
    44     import nose2
    45     nose2.main()
     43    from _tools import run_module_suite
     44    run_module_suite()
  • python/tests/test_musicutils.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43import numpy as np
    54from numpy.testing import TestCase
    6 from numpy.testing.utils import assert_equal, assert_almost_equal
     5from numpy.testing import assert_equal, assert_almost_equal
    76from aubio import window, level_lin, db_spl, silence_detection, level_detection
    87from aubio import fvec, float_type
     
    8685
    8786if __name__ == '__main__':
     87    from unittest import main
    8888    main()
  • python/tests/test_note2midi.py

    r086a45b rf2f1b10  
    44from __future__ import unicode_literals
    55
    6 from aubio import note2midi, freq2note
    7 from nose2.tools import params
    8 import unittest
     6from aubio import note2midi, freq2note, note2freq, float_type
     7from numpy.testing import TestCase
     8from _tools import parametrize, assert_raises, skipTest
    99
    1010list_of_known_notes = (
     
    4545        )
    4646
    47 class note2midi_good_values(unittest.TestCase):
     47class Test_note2midi_good_values(object):
    4848
    49     @params(*list_of_known_notes)
     49    @parametrize('note, midi', list_of_known_notes)
    5050    def test_note2midi_known_values(self, note, midi):
    5151        " known values are correctly converted "
    52         self.assertEqual ( note2midi(note), midi )
     52        assert note2midi(note) == midi
    5353
    54     @params(*list_of_known_notes_with_unicode_issues)
     54    @parametrize('note, midi', list_of_known_notes_with_unicode_issues)
    5555    def test_note2midi_known_values_with_unicode_issues(self, note, midi):
    56         " known values are correctly converted, unless decoding is expected to fail"
     56        " difficult values are correctly converted unless expected failure "
    5757        try:
    58             self.assertEqual ( note2midi(note), midi )
     58            assert note2midi(note) == midi
    5959        except UnicodeEncodeError as e:
     60            # platforms with decoding failures include:
     61            # - osx: python <= 2.7.10
     62            # - win: python <= 2.7.12
    6063            import sys
    61             strfmt = "len(u'\\U0001D12A') != 1, excpected decoding failure | {:s} | {:s} {:s}"
    62             strres = strfmt.format(e, sys.platform, sys.version)
    63             # happens with: darwin 2.7.10, windows 2.7.12
     64            strmsg = "len(u'\\U0001D12A') != 1, expected decoding failure"
     65            strmsg += " | upgrade to Python 3 to fix"
     66            strmsg += " | {:s} | {:s} {:s}"
    6467            if len('\U0001D12A') != 1 and sys.version[0] == '2':
    65                 self.skipTest(strres + " | upgrade to Python 3 to fix")
     68                skipTest(strmsg.format(repr(e), sys.platform, sys.version))
    6669            else:
    6770                raise
    6871
    69 class note2midi_wrong_values(unittest.TestCase):
     72class note2midi_wrong_values(TestCase):
    7073
    7174    def test_note2midi_missing_octave(self):
     
    105108        self.assertRaises(ValueError, note2midi, 'CB+-3')
    106109
    107     @params(*list_of_unknown_notes)
     110class Test_note2midi_unknown_values(object):
     111
     112    @parametrize('note', list_of_unknown_notes)
    108113    def test_note2midi_unknown_values(self, note):
    109114        " unknown values throw out an error "
    110         self.assertRaises(ValueError, note2midi, note)
     115        assert_raises(ValueError, note2midi, note)
    111116
    112 class freq2note_simple_test(unittest.TestCase):
     117class freq2note_simple_test(TestCase):
    113118
    114     def test_freq2note(self):
     119    def test_freq2note_above(self):
    115120        " make sure freq2note(441) == A4 "
    116121        self.assertEqual("A4", freq2note(441))
    117122
     123    def test_freq2note_under(self):
     124        " make sure freq2note(439) == A4 "
     125        self.assertEqual("A4", freq2note(439))
     126
     127class note2freq_simple_test(TestCase):
     128
     129    def test_note2freq(self):
     130        " make sure note2freq('A3') == 220"
     131        self.assertEqual(220, note2freq("A3"))
     132
     133    def test_note2freq_under(self):
     134        " make sure note2freq(A4) == 440"
     135        if float_type == 'float32':
     136            self.assertEqual(440, note2freq("A4"))
     137        else:
     138            self.assertLess(abs(note2freq("A4")-440), 1.e-12)
     139
    118140if __name__ == '__main__':
    119     import nose2
    120     nose2.main()
     141    from _tools import run_module_suite
     142    run_module_suite()
  • python/tests/test_notes.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43from numpy.testing import TestCase, assert_equal, assert_almost_equal
    5 from aubio import notes
     4from aubio import notes, source
     5import numpy as np
     6from utils import list_all_sounds
     7
     8list_of_sounds = list_all_sounds('sounds')
    69
    710AUBIO_DEFAULT_NOTES_SILENCE = -70.
     11AUBIO_DEFAULT_NOTES_RELEASE_DROP = 10.
    812AUBIO_DEFAULT_NOTES_MINIOI_MS = 30.
    913
     
    3943        assert_equal (self.o.get_silence(), val)
    4044
    41 from .utils import list_all_sounds
    42 list_of_sounds = list_all_sounds('sounds')
     45    def test_get_release_drop(self):
     46        assert_equal (self.o.get_release_drop(), AUBIO_DEFAULT_NOTES_RELEASE_DROP)
     47
     48    def test_set_release_drop(self):
     49        val = 50
     50        self.o.set_release_drop(val)
     51        assert_equal (self.o.get_release_drop(), val)
     52
     53    def test_set_release_drop_wrong(self):
     54        val = -10
     55        with self.assertRaises(ValueError):
     56            self.o.set_release_drop(val)
    4357
    4458class aubio_notes_sinewave(TestCase):
    4559
    4660    def analyze_file(self, filepath, samplerate=0):
    47         from aubio import source
    48         import numpy as np
    4961        win_s = 512 # fft size
    5062        hop_s = 256 # hop size
     
    7991
    8092if __name__ == '__main__':
     93    from unittest import main
    8194    main()
  • python/tests/test_onset.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43from numpy.testing import TestCase, assert_equal, assert_almost_equal
    5 from aubio import onset
     4from aubio import onset, fvec
    65
    76class aubio_onset_default(TestCase):
     
    8483    samplerate = 8000
    8584
     85class aubio_onset_coverate(TestCase):
     86    # extra tests to execute the C routines and improve coverage
     87
     88    def test_all_methods(self):
     89        for method in ['default', 'energy', 'hfc', 'complexdomain', 'complex',
     90                'phase', 'wphase', 'mkl', 'kl', 'specflux', 'specdiff',
     91                'old_default']:
     92            o = onset(method=method, buf_size=512, hop_size=256)
     93            o(fvec(256))
     94
     95    def test_get_methods(self):
     96        o = onset(method='default', buf_size=512, hop_size=256)
     97
     98        assert o.get_silence() == -70
     99        o.set_silence(-20)
     100        assert_almost_equal(o.get_silence(), -20)
     101
     102        assert o.get_compression() == 1
     103        o.set_compression(.99)
     104        assert_almost_equal(o.get_compression(), .99)
     105
     106        assert o.get_awhitening() == 0
     107        o.set_awhitening(1)
     108        assert o.get_awhitening() == 1
     109
     110        o.get_last()
     111        o.get_last_ms()
     112        o.get_last_s()
     113        o.get_descriptor()
     114        o.get_thresholded_descriptor()
     115
     116
    86117if __name__ == '__main__':
     118    from unittest import main
    87119    main()
  • python/tests/test_phasevoc.py

    r086a45b rf2f1b10  
    22
    33from numpy.testing import TestCase, assert_equal, assert_array_less
     4from _tools import parametrize
    45from aubio import fvec, cvec, pvoc, float_type
    5 from nose2 import main
    6 from nose2.tools import params
    76import numpy as np
    87
     
    1918    return np.random.rand(hop_s).astype(float_type) * 2. - 1.
    2019
    21 class aubio_pvoc_test_case(TestCase):
     20class Test_aubio_pvoc_test_case(object):
    2221    """ pvoc object test case """
    2322
     
    5756            assert_equal ( r, 0.)
    5857
    59     @params(
     58    def test_no_overlap(self):
     59        win_s, hop_s = 1024, 1024
     60        f = pvoc (win_s, hop_s)
     61        t = fvec (hop_s)
     62        for _ in range(4):
     63            s = f(t)
     64            r = f.rdo(s)
     65            assert_equal ( t, 0.)
     66
     67    resynth_noise_args = "hop_s, ratio"
     68    resynth_noise_values = [
    6069            ( 256, 8),
    6170            ( 256, 4),
     
    7988            (8192, 4),
    8089            (8192, 2),
    81             )
     90            ]
     91
     92    @parametrize(resynth_noise_args, resynth_noise_values)
    8293    def test_resynth_steps_noise(self, hop_s, ratio):
    8394        """ check the resynthesis of a random signal is correct """
     
    8596        self.reconstruction(sigin, hop_s, ratio)
    8697
    87     @params(
     98    resynth_sine_args = "samplerate, hop_s, ratio, freq"
     99    resynth_sine_values = [
    88100            (44100,  256, 8,   441),
    89101            (44100,  256, 4,  1203),
     
    100112            (96000, 1024, 8, 47000),
    101113            (96000, 1024, 8,    20),
    102             )
     114            ]
     115
     116    @parametrize(resynth_sine_args, resynth_sine_values)
    103117    def test_resynth_steps_sine(self, samplerate, hop_s, ratio, freq):
    104118        """ check the resynthesis of a sine is correct """
     
    191205
    192206if __name__ == '__main__':
     207    from unittest import main
    193208    main()
    194 
  • python/tests/test_pitch.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import TestCase, main
    4 from numpy.testing import assert_equal
     3from numpy.testing import TestCase, assert_equal
    54from numpy import sin, arange, mean, median, isnan, pi
    65from aubio import fvec, pitch, freqtomidi, float_type
     
    117116for algo in pitch_algorithms:
    118117    for mode in signal_modes:
    119         test_method = create_test (algo, mode)
    120         test_method.__name__ = 'test_pitch_%s_%d_%d_%dHz_sin_%.0f' % ( algo,
     118        _test_method = create_test (algo, mode)
     119        _test_method.__name__ = 'test_pitch_%s_%d_%d_%dHz_sin_%.0f' % ( algo,
    121120                mode[0], mode[1], mode[2], mode[3] )
    122         setattr (aubio_pitch_Sinusoid, test_method.__name__, test_method)
     121        setattr (aubio_pitch_Sinusoid, _test_method.__name__, _test_method)
    123122
    124123if __name__ == '__main__':
     124    from unittest import main
    125125    main()
  • python/tests/test_sink.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from nose2 import main
    4 from nose2.tools import params
    53from numpy.testing import TestCase
    64from aubio import fvec, source, sink
    7 from .utils import list_all_sounds, get_tmp_sink_path, del_tmp_sink_path
    8 
    9 import warnings
    10 warnings.filterwarnings('ignore', category=UserWarning, append=True)
     5from utils import list_all_sounds, get_tmp_sink_path, del_tmp_sink_path
     6from utils import parse_file_samplerate
     7from _tools import parametrize, skipTest, assert_raises, assert_warns
    118
    129list_of_sounds = list_all_sounds('sounds')
     
    2421            all_params.append((hop_size, samplerate, soundfile))
    2522
    26 class aubio_sink_test_case(TestCase):
    27 
    28     def setUp(self):
    29         if not len(list_of_sounds):
    30             self.skipTest('add some sound files in \'python/tests/sounds\'')
     23class Test_aubio_sink(object):
    3124
    3225    def test_wrong_filename(self):
    33         with self.assertRaises(RuntimeError):
     26        with assert_raises(RuntimeError):
    3427            sink('')
    3528
    3629    def test_wrong_samplerate(self):
    37         with self.assertRaises(RuntimeError):
     30        with assert_raises(RuntimeError):
    3831            sink(get_tmp_sink_path(), -1)
    3932
    4033    def test_wrong_samplerate_too_large(self):
    41         with self.assertRaises(RuntimeError):
     34        with assert_raises(RuntimeError):
    4235            sink(get_tmp_sink_path(), 1536001, 2)
    4336
    4437    def test_wrong_channels(self):
    45         with self.assertRaises(RuntimeError):
     38        with assert_raises(RuntimeError):
    4639            sink(get_tmp_sink_path(), 44100, -1)
    4740
    4841    def test_wrong_channels_too_large(self):
    49         with self.assertRaises(RuntimeError):
     42        with assert_raises(RuntimeError):
    5043            sink(get_tmp_sink_path(), 44100, 202020)
    5144
     
    6760        shutil.rmtree(tmpdir)
    6861
    69     @params(*all_params)
     62    @parametrize('hop_size, samplerate, path', all_params)
    7063    def test_read_and_write(self, hop_size, samplerate, path):
    71 
     64        orig_samplerate = parse_file_samplerate(soundfile)
    7265        try:
    73             f = source(path, samplerate, hop_size)
     66            if orig_samplerate is not None and orig_samplerate < samplerate:
     67                # upsampling should emit a warning
     68                with assert_warns(UserWarning):
     69                    f = source(soundfile, samplerate, hop_size)
     70            else:
     71                f = source(soundfile, samplerate, hop_size)
    7472        except RuntimeError as e:
    75             self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
     73            err_msg = '{:s} (hop_s = {:d}, samplerate = {:d})'
     74            skipTest(err_msg.format(str(e), hop_size, samplerate))
    7675        if samplerate == 0: samplerate = f.samplerate
    7776        sink_path = get_tmp_sink_path()
     
    8584        del_tmp_sink_path(sink_path)
    8685
    87     @params(*all_params)
     86    @parametrize('hop_size, samplerate, path', all_params)
    8887    def test_read_and_write_multi(self, hop_size, samplerate, path):
     88        orig_samplerate = parse_file_samplerate(soundfile)
    8989        try:
    90             f = source(path, samplerate, hop_size)
     90            if orig_samplerate is not None and orig_samplerate < samplerate:
     91                # upsampling should emit a warning
     92                with assert_warns(UserWarning):
     93                    f = source(soundfile, samplerate, hop_size)
     94            else:
     95                f = source(soundfile, samplerate, hop_size)
    9196        except RuntimeError as e:
    92             self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
     97            err_msg = '{:s} (hop_s = {:d}, samplerate = {:d})'
     98            skipTest(err_msg.format(str(e), hop_size, samplerate))
    9399        if samplerate == 0: samplerate = f.samplerate
    94100        sink_path = get_tmp_sink_path()
     
    126132
    127133if __name__ == '__main__':
    128     main()
     134    from _tools import run_module_suite
     135    run_module_suite()
  • python/tests/test_slicing.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43from numpy.testing import TestCase, assert_equal
    54from aubio import slice_source_at_stamps
    6 from .utils import count_files_in_directory, get_default_test_sound
    7 from .utils import count_samples_in_directory, count_samples_in_file
     5from utils import count_files_in_directory, get_default_test_sound
     6from utils import count_samples_in_directory, count_samples_in_file
    87
    98import tempfile
     
    2423    def test_slice_start_only_no_zero(self):
    2524        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)
     25        slice_source_at_stamps(self.source_file, regions_start,
     26                output_dir = self.output_dir, create_first=True)
    2727
    2828    def test_slice_start_beyond_end(self):
    2929        regions_start = [i*1000 for i in range(1, n_slices)]
    3030        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)
     31        slice_source_at_stamps(self.source_file, regions_start,
     32                output_dir = self.output_dir, create_first=True)
    3233
    3334    def test_slice_start_every_blocksize(self):
    3435        hopsize = 200
    35         regions_start = [i*hopsize for i in range(1, n_slices)]
     36        regions_start = [i*hopsize for i in range(0, n_slices)]
    3637        slice_source_at_stamps(self.source_file, regions_start, output_dir = self.output_dir,
    3738                hopsize = 200)
     39
     40    def test_slice_start_every_half_blocksize(self):
     41        hopsize = 200
     42        regions_start = [i*hopsize//2 for i in range(0, n_slices)]
     43        slice_source_at_stamps(self.source_file, regions_start,
     44                output_dir = self.output_dir, hopsize = 200)
    3845
    3946    def tearDown(self):
     
    9299            "number of samples written different from number of original samples")
    93100
     101    def test_slice_start_and_ends_with_missing_end(self):
     102        regions_start = [i*1000 for i in range(n_slices)]
     103        regions_ends = [r-1 for r in regions_start[1:]]
     104        slice_source_at_stamps(self.source_file, regions_start, regions_ends,
     105                output_dir = self.output_dir)
     106        written_samples = count_samples_in_directory(self.output_dir)
     107        original_samples = count_samples_in_file(self.source_file)
     108        total_files = count_files_in_directory(self.output_dir)
     109        assert_equal(n_slices, total_files,
     110            "number of slices created different from expected")
     111        assert_equal(written_samples, original_samples,
     112            "number of samples written different from number of original samples")
     113
    94114    def tearDown(self):
    95115        shutil.rmtree(self.output_dir)
     
    134154        regions_end = None
    135155        slice_source_at_stamps (self.source_file, regions_start, regions_end,
    136                 output_dir = self.output_dir)
     156                output_dir = self.output_dir, create_first=True)
    137157        total_files = count_files_in_directory(self.output_dir)
    138158        assert_equal(n_slices, total_files,
     
    147167
    148168if __name__ == '__main__':
     169    from unittest import main
    149170    main()
  • python/tests/test_source.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from nose2 import main
    4 from nose2.tools import params
     3
    54from numpy.testing import TestCase, assert_equal
    65from aubio import source
    7 from .utils import list_all_sounds
    8 
    9 import warnings
    10 warnings.filterwarnings('ignore', category=UserWarning, append=True)
     6from utils import list_all_sounds, parse_file_samplerate
     7import unittest
     8from _tools import assert_raises, assert_equal, assert_warns
     9from _tools import parametrize, skipTest
    1110
    1211list_of_sounds = list_all_sounds('sounds')
     
    1413hop_sizes = [512, 1024, 64]
    1514
    16 path = None
     15default_test_sound = len(list_of_sounds) and list_of_sounds[0] or None
    1716
    1817all_params = []
     
    2221            all_params.append((hop_size, samplerate, soundfile))
    2322
    24 
    25 class aubio_source_test_case_base(TestCase):
     23no_sounds_msg = "no test sounds, add some in 'python/tests/sounds/'!"
     24
     25_debug = False
     26
     27
     28class Test_aubio_source_test_case(TestCase):
    2629
    2730    def setUp(self):
    28         if not len(list_of_sounds):
    29             self.skipTest('add some sound files in \'python/tests/sounds\'')
    30         self.default_test_sound = list_of_sounds[0]
    31 
    32 class aubio_source_test_case(aubio_source_test_case_base):
    33 
    34     @params(*list_of_sounds)
    35     def test_close_file(self, filename):
     31        if not default_test_sound:
     32            skipTest(no_sounds_msg)
     33
     34    def test_close_file(self):
    3635        samplerate = 0 # use native samplerate
    3736        hop_size = 256
    38         f = source(filename, samplerate, hop_size)
    39         f.close()
    40 
    41     @params(*list_of_sounds)
    42     def test_close_file_twice(self, filename):
     37        f = source(default_test_sound, samplerate, hop_size)
     38        f.close()
     39
     40    def test_close_file_twice(self):
    4341        samplerate = 0 # use native samplerate
    4442        hop_size = 256
    45         f = source(filename, samplerate, hop_size)
    46         f.close()
    47         f.close()
    48 
    49 class aubio_source_read_test_case(aubio_source_test_case_base):
     43        f = source(default_test_sound, samplerate, hop_size)
     44        f.close()
     45        f.close()
     46
     47    def test_read_after_close(self):
     48        samplerate = 0 # use native samplerate
     49        hop_size = 256
     50        f = source(default_test_sound, samplerate, hop_size)
     51        read, frames = f()
     52        f.close()
     53        with assert_raises(RuntimeError):
     54            read, frames = f()
     55        with assert_raises(RuntimeError):
     56            read, frames = f.do_multi()
     57
     58
     59class Test_aubio_source_read(object):
    5060
    5161    def read_from_source(self, f):
     
    5767                assert_equal(samples[read:], 0)
    5868                break
    59         #result_str = "read {:.2f}s ({:d} frames in {:d} blocks at {:d}Hz) from {:s}"
    60         #result_params = total_frames / float(f.samplerate), total_frames, total_frames//f.hop_size, f.samplerate, f.uri
    61         #print (result_str.format(*result_params))
     69        if _debug:
     70            result_str = "read {:.2f}s ({:d} frames"
     71            result_str += " in {:d} blocks at {:d}Hz) from {:s}"
     72            result_params = total_frames / float(f.samplerate), total_frames, \
     73                    total_frames//f.hop_size, f.samplerate, f.uri
     74            print (result_str.format(*result_params))
    6275        return total_frames
    6376
    64     @params(*all_params)
     77    @parametrize('hop_size, samplerate, soundfile', all_params)
    6578    def test_samplerate_hopsize(self, hop_size, samplerate, soundfile):
     79        orig_samplerate = parse_file_samplerate(soundfile)
    6680        try:
    67             f = source(soundfile, samplerate, hop_size)
     81            if orig_samplerate is not None and orig_samplerate < samplerate:
     82                # upsampling should emit a warning
     83                with assert_warns(UserWarning):
     84                    f = source(soundfile, samplerate, hop_size)
     85            else:
     86                f = source(soundfile, samplerate, hop_size)
    6887        except RuntimeError as e:
    69             self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
     88            err_msg = 'failed opening with hop_s={:d}, samplerate={:d} ({:s})'
     89            skipTest(err_msg.format(hop_size, samplerate, str(e)))
    7090        assert f.samplerate != 0
    7191        read_frames = self.read_from_source(f)
    7292        if 'f_' in soundfile and samplerate == 0:
    7393            import re
    74             f = re.compile('.*_\([0:9]*f\)_.*')
     94            f = re.compile(r'.*_\([0:9]*f\)_.*')
    7595            match_f = re.findall('([0-9]*)f_', soundfile)
    7696            if len(match_f) == 1:
    7797                expected_frames = int(match_f[0])
    78                 self.assertEqual(expected_frames, read_frames)
    79 
    80     @params(*list_of_sounds)
     98                assert_equal(expected_frames, read_frames)
     99
     100    @parametrize('p', list_of_sounds)
    81101    def test_samplerate_none(self, p):
    82102        f = source(p)
     
    84104        self.read_from_source(f)
    85105
    86     @params(*list_of_sounds)
     106    @parametrize('p', list_of_sounds)
    87107    def test_samplerate_0(self, p):
    88108        f = source(p, 0)
     
    90110        self.read_from_source(f)
    91111
    92     @params(*list_of_sounds)
     112    @parametrize('p', list_of_sounds)
    93113    def test_zero_hop_size(self, p):
    94114        f = source(p, 0, 0)
     
    97117        self.read_from_source(f)
    98118
    99     @params(*list_of_sounds)
     119    @parametrize('p', list_of_sounds)
    100120    def test_seek_to_half(self, p):
    101121        from random import randint
     
    109129        assert a == b + c
    110130
    111     @params(*list_of_sounds)
     131    @parametrize('p', list_of_sounds)
    112132    def test_duration(self, p):
    113133        total_frames = 0
     
    118138            total_frames += read
    119139            if read < f.hop_size: break
    120         self.assertEqual(duration, total_frames)
    121 
    122 
    123 class aubio_source_test_wrong_params(TestCase):
     140        assert_equal (duration, total_frames)
     141
     142
     143class Test_aubio_source_wrong_params(object):
    124144
    125145    def test_wrong_file(self):
    126         with self.assertRaises(RuntimeError):
     146        with assert_raises(RuntimeError):
    127147            source('path_to/unexisting file.mp3')
    128148
    129 class aubio_source_test_wrong_params_with_file(aubio_source_test_case_base):
     149@unittest.skipIf(default_test_sound is None, no_sounds_msg)
     150class Test_aubio_source_wrong_params_with_file(TestCase):
    130151
    131152    def test_wrong_samplerate(self):
    132         with self.assertRaises(ValueError):
    133             source(self.default_test_sound, -1)
     153        with assert_raises(ValueError):
     154            source(default_test_sound, -1)
    134155
    135156    def test_wrong_hop_size(self):
    136         with self.assertRaises(ValueError):
    137             source(self.default_test_sound, 0, -1)
     157        with assert_raises(ValueError):
     158            source(default_test_sound, 0, -1)
    138159
    139160    def test_wrong_channels(self):
    140         with self.assertRaises(ValueError):
    141             source(self.default_test_sound, 0, 0, -1)
     161        with assert_raises(ValueError):
     162            source(default_test_sound, 0, 0, -1)
    142163
    143164    def test_wrong_seek(self):
    144         f = source(self.default_test_sound)
    145         with self.assertRaises(ValueError):
     165        f = source(default_test_sound)
     166        with assert_raises(ValueError):
    146167            f.seek(-1)
    147168
    148169    def test_wrong_seek_too_large(self):
    149         f = source(self.default_test_sound)
     170        f = source(default_test_sound)
    150171        try:
    151             with self.assertRaises(ValueError):
     172            with assert_raises(ValueError):
    152173                f.seek(f.duration + f.samplerate * 10)
    153         except AssertionError:
    154             self.skipTest('seeking after end of stream failed raising ValueError')
    155 
    156 class aubio_source_readmulti_test_case(aubio_source_read_test_case):
     174        except:
     175            skipTest('seeking after end of stream failed raising ValueError')
     176
     177class Test_aubio_source_readmulti(Test_aubio_source_read):
    157178
    158179    def read_from_source(self, f):
     
    164185                assert_equal(samples[:,read:], 0)
    165186                break
    166         #result_str = "read {:.2f}s ({:d} frames in {:d} channels and {:d} blocks at {:d}Hz) from {:s}"
    167         #result_params = total_frames / float(f.samplerate), total_frames, f.channels, int(total_frames/f.hop_size), f.samplerate, f.uri
    168         #print (result_str.format(*result_params))
     187        if _debug:
     188            result_str = "read {:.2f}s ({:d} frames in {:d} channels"
     189            result_str += " and {:d} blocks at {:d}Hz) from {:s}"
     190            result_params = total_frames / float(f.samplerate), total_frames, \
     191                    f.channels, int(total_frames/f.hop_size), \
     192                    f.samplerate, f.uri
     193            print (result_str.format(*result_params))
    169194        return total_frames
    170195
    171 class aubio_source_with(aubio_source_test_case_base):
    172 
    173     #@params(*list_of_sounds)
    174     @params(*list_of_sounds)
     196class Test_aubio_source_with(object):
     197
     198    @parametrize('filename', list_of_sounds)
    175199    def test_read_from_mono(self, filename):
    176200        total_frames = 0
     
    186210
    187211if __name__ == '__main__':
    188     main()
     212    from _tools import run_module_suite
     213    run_module_suite()
  • python/tests/test_specdesc.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43from numpy.testing import TestCase, assert_equal, assert_almost_equal
    54from numpy import random, arange, log, zeros
     
    230229
    231230if __name__ == '__main__':
     231    from unittest import main
    232232    main()
  • python/tests/test_zero_crossing_rate.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 from unittest import main
    43from numpy.testing import TestCase
    54from aubio import fvec, zero_crossing_rate
     
    4443
    4544if __name__ == '__main__':
     45    from unittest import main
    4646    main()
  • python/tests/utils.py

    r086a45b rf2f1b10  
    22
    33import os
     4import re
    45import glob
    56import numpy as np
     
    910
    1011def array_from_text_file(filename, dtype = 'float'):
    11     filename = os.path.join(os.path.dirname(__file__), filename)
    12     with open(filename) as f:
    13         lines = f.readlines()
    14     return np.array([line.split() for line in lines],
    15             dtype = dtype)
     12    realpathname = os.path.join(os.path.dirname(__file__), filename)
     13    return np.loadtxt(realpathname, dtype = dtype)
    1614
    1715def list_all_sounds(rel_dir):
     
    3937        os.unlink(path)
    4038    except WindowsError as e:
    41         print("deleting {:s} failed ({:s}), reopening".format(path, repr(e)))
    42         with open(path, 'wb') as f:
    43             f.close()
    44         try:
    45             os.unlink(path)
    46         except WindowsError as f:
    47             print("deleting {:s} failed ({:s}), aborting".format(path, repr(e)))
     39        # removing the temporary directory sometimes fails on windows
     40        import warnings
     41        errmsg = "failed deleting temporary file {:s} ({:s})"
     42        warnings.warn(UserWarning(errmsg.format(path, repr(e))))
    4843
    4944def array_from_yaml_file(filename):
     
    8479                    total_files += 1
    8580    return total_files
     81
     82def parse_file_samplerate(soundfile):
     83    samplerate = None
     84    # parse samplerate
     85    re_sr = re.compile(r'/([0-9]{4,})Hz_.*')
     86    match_samplerate = re_sr.findall(soundfile)
     87    if match_samplerate:
     88        samplerate = int(match_samplerate[0])
     89    else:
     90        import warnings
     91        warnings.warn(UserWarning("could not parse samplerate for {:s}"
     92            .format(soundfile)))
     93    return samplerate
  • requirements.txt

    r086a45b rf2f1b10  
    11numpy
    2 nose2
     2pytest
  • scripts/build_apple_frameworks

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

    r086a45b rf2f1b10  
    22
    33set -e
    4 set -x
     4#set -x
    55
    6 WAFVERSION=2.0.1
     6WAFVERSION=2.0.14
    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
  • setup.py

    r086a45b rf2f1b10  
    11#! /usr/bin/env python
    22
    3 import sys, os.path, glob
     3import sys
     4import os.path
     5import glob
    46from setuptools import setup, Extension
    5 from python.lib.moresetuptools import build_ext, CleanGenerated
     7
     8# add ./python/lib to current path
     9sys.path.append(os.path.join('python', 'lib'))  # noqa
     10from moresetuptools import build_ext, CleanGenerated
     11
    612# function to generate gen/*.{c,h}
    713from this_version import get_aubio_version, get_aubio_pyversion
     
    1521extra_link_args = []
    1622
    17 include_dirs += [ 'python/ext' ]
     23include_dirs += ['python/ext']
    1824try:
    1925    import numpy
    20     include_dirs += [ numpy.get_include() ]
     26    include_dirs += [numpy.get_include()]
    2127except ImportError:
    2228    pass
    2329
    2430if sys.platform.startswith('darwin'):
    25     extra_link_args += ['-framework','CoreFoundation', '-framework','AudioToolbox']
     31    extra_link_args += ['-framework', 'CoreFoundation',
     32            '-framework', 'AudioToolbox']
    2633
    2734sources = sorted(glob.glob(os.path.join('python', 'ext', '*.c')))
     
    3441    define_macros = define_macros)
    3542
    36 if os.path.isfile('src/aubio.h'):
    37     if not os.path.isdir(os.path.join('build','src')):
    38         pass
    39         #__version__ += 'a2' # python only version
     43# TODO: find a way to track if package is built against libaubio
     44# if os.path.isfile('src/aubio.h'):
     45#     if not os.path.isdir(os.path.join('build','src')):
     46#         pass
     47#         #__version__ += 'a2' # python only version
    4048
    4149classifiers = [
     
    5159    'Programming Language :: C',
    5260    'Programming Language :: Python',
    53     'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
     61    'License :: OSI Approved :: '
     62    'GNU General Public License v3 or later (GPLv3+)',
    5463    ]
     64
     65thisdir = os.path.abspath(os.path.dirname(__file__))
     66py_readme_file = os.path.join(thisdir, 'python', 'README.md')
     67with open(py_readme_file, 'r') as fp:
     68    long_description = ''.join(fp.readlines()[3:])
    5569
    5670distrib = setup(name='aubio',
    5771    version = __version__,
    5872    packages = ['aubio'],
    59     package_dir = {'aubio':'python/lib/aubio'},
     73    package_dir = {'aubio': 'python/lib/aubio'},
    6074    ext_modules = [aubio_extension],
    6175    description = 'a collection of tools for music analysis',
    62     long_description = 'a collection of tools for music analysis',
     76    long_description = long_description,
     77    long_description_content_type = 'text/markdown',
    6378    license = 'GNU/GPL version 3',
    6479    author = 'Paul Brossier',
     
    8196        ],
    8297    },
    83     test_suite = 'nose2.collector.collector',
    84     extras_require = {
    85         'tests': ['numpy'],
    86         },
    8798    )
  • src/aubio.h

    r086a45b rf2f1b10  
    183183#include "temporal/c_weighting.h"
    184184#include "spectral/fft.h"
     185#include "spectral/dct.h"
    185186#include "spectral/phasevoc.h"
    186187#include "spectral/filterbank.h"
  • src/aubio_priv.h

    r086a45b rf2f1b10  
    6363#endif
    6464
     65#ifdef HAVE_ERRNO_H
     66#include <errno.h>
     67#endif
     68
    6569#ifdef HAVE_LIMITS_H
    6670#include <limits.h> // for CHAR_BIT, in C99 standard
     
    7175#endif
    7276
    73 #ifdef HAVE_ACCELERATE
    74 #define HAVE_ATLAS 1
    75 #include <Accelerate/Accelerate.h>
    76 #elif defined(HAVE_ATLAS_CBLAS_H)
     77#if defined(HAVE_BLAS) // --enable-blas=true
     78// check which cblas header we found
     79#if defined(HAVE_ATLAS_CBLAS_H)
    7780#define HAVE_ATLAS 1
    7881#include <atlas/cblas.h>
    79 #else
    80 #undef HAVE_ATLAS
    81 #endif
    82 
    83 #ifdef HAVE_ACCELERATE
     82#elif defined(HAVE_OPENBLAS_CBLAS_H)
     83#include <openblas/cblas.h>
     84#elif defined(HAVE_CBLAS_H)
     85#include <cblas.h>
     86#elif !defined(HAVE_ACCELERATE)
     87#error "HAVE_BLAS was defined, but no blas header was found"
     88#endif /* end of cblas includes */
     89#endif
     90
     91#if defined(HAVE_ACCELERATE)
     92// include accelerate framework after blas
     93#define HAVE_ATLAS 1
     94#define HAVE_BLAS 1
    8495#include <Accelerate/Accelerate.h>
     96
    8597#ifndef HAVE_AUBIO_DOUBLE
    8698#define aubio_vDSP_mmov       vDSP_mmov
    8799#define aubio_vDSP_vmul       vDSP_vmul
     100#define aubio_vDSP_vsmul      vDSP_vsmul
     101#define aubio_vDSP_vsadd      vDSP_vsadd
    88102#define aubio_vDSP_vfill      vDSP_vfill
    89103#define aubio_vDSP_meanv      vDSP_meanv
     
    98112#define aubio_vDSP_mmov       vDSP_mmovD
    99113#define aubio_vDSP_vmul       vDSP_vmulD
     114#define aubio_vDSP_vsmul      vDSP_vsmulD
     115#define aubio_vDSP_vsadd      vDSP_vsaddD
    100116#define aubio_vDSP_vfill      vDSP_vfillD
    101117#define aubio_vDSP_meanv      vDSP_meanvD
     
    110126#endif /* HAVE_ACCELERATE */
    111127
     128#if defined(HAVE_BLAS)
     129#ifndef HAVE_AUBIO_DOUBLE
    112130#ifdef HAVE_ATLAS
    113 #ifndef HAVE_AUBIO_DOUBLE
    114131#define aubio_catlas_set      catlas_sset
     132#endif /* HAVE_ATLAS */
    115133#define aubio_cblas_copy      cblas_scopy
    116134#define aubio_cblas_swap      cblas_sswap
    117135#define aubio_cblas_dot       cblas_sdot
    118136#else /* HAVE_AUBIO_DOUBLE */
     137#ifdef HAVE_ATLAS
    119138#define aubio_catlas_set      catlas_dset
     139#endif /* HAVE_ATLAS */
    120140#define aubio_cblas_copy      cblas_dcopy
    121141#define aubio_cblas_swap      cblas_dswap
    122142#define aubio_cblas_dot       cblas_ddot
    123143#endif /* HAVE_AUBIO_DOUBLE */
    124 #endif /* HAVE_ATLAS */
     144#endif /* HAVE_BLAS */
    125145
    126146#if defined HAVE_INTEL_IPP
     
    157177#if !defined(HAVE_MEMCPY_HACKS) && !defined(HAVE_ACCELERATE) && !defined(HAVE_ATLAS) && !defined(HAVE_INTEL_IPP)
    158178#define HAVE_NOOPT 1
    159 #else
    160 #undef HAVE_NOOPT
    161179#endif
    162180
     
    313331#endif
    314332
     333#if !defined(_MSC_VER)
     334#define AUBIO_STRERROR(errno,buf,len) strerror_r(errno, buf, len)
     335#else
     336#define AUBIO_STRERROR(errno,buf,len) strerror_s(buf, len, errno)
     337#endif
     338
     339#ifdef HAVE_C99_VARARGS_MACROS
     340#define AUBIO_STRERR(...)            \
     341    char errorstr[256]; \
     342    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr)); \
     343    AUBIO_ERR(__VA_ARGS__)
     344#else
     345#define AUBIO_STRERR(format, args...)   \
     346    char errorstr[256]; \
     347    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr)); \
     348    AUBIO_ERR(format, ##args)
     349#endif
     350
    315351/* handy shortcuts */
    316352#define DB2LIN(g) (POW(10.0,(g)*0.05f))
     
    356392#endif /* __STRICT_ANSI__ */
    357393
     394#if defined(DEBUG)
     395#include <assert.h>
     396#define AUBIO_ASSERT(x) assert(x)
     397#else
     398#define AUBIO_ASSERT(x)
     399#endif /* DEBUG */
     400
    358401#endif /* AUBIO_PRIV_H */
  • src/fmat.c

    r086a45b rf2f1b10  
    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

    r086a45b rf2f1b10  
    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/ioutils.c

    r086a45b rf2f1b10  
    2020
    2121#include "aubio_priv.h"
     22#include "fmat.h"
    2223
    2324uint_t
     
    5253  return AUBIO_OK;
    5354}
     55
     56uint_t
     57aubio_source_validate_input_length(const char_t *kind, const char_t *path,
     58    uint_t hop_size, uint_t read_data_length)
     59{
     60  uint_t length = hop_size;
     61  if (hop_size < read_data_length) {
     62    AUBIO_WRN("%s: partial read from %s, trying to read %d frames, but"
     63        " hop_size is %d\n", kind, path, read_data_length, hop_size);
     64  } else if (hop_size > read_data_length) {
     65    AUBIO_WRN("%s: partial read from %s, trying to read %d frames into"
     66        " a buffer of length %d\n", kind, path, hop_size, read_data_length);
     67    length = read_data_length;
     68  }
     69  return length;
     70}
     71
     72uint_t
     73aubio_source_validate_input_channels(const char_t *kind, const char_t *path,
     74    uint_t source_channels, uint_t read_data_height)
     75{
     76  uint_t channels = source_channels;
     77  if (read_data_height < source_channels) {
     78    AUBIO_WRN("%s: partial read from %s, trying to read %d channels,"
     79        " but found output of height %d\n", kind, path, source_channels,
     80        read_data_height);
     81    channels = read_data_height;
     82  } else if (read_data_height > source_channels) {
     83    // do not show a warning when trying to read into more channels than
     84    // the input source.
     85#if 0
     86    AUBIO_WRN("%s: partial read from %s, trying to read %d channels,"
     87        " but found output of height %d\n", kind, path, source_channels,
     88        read_data_height);
     89#endif
     90    channels = source_channels;
     91  }
     92  return channels;
     93}
     94
     95void
     96aubio_source_pad_output (fvec_t *read_data, uint_t source_read)
     97{
     98  if (source_read < read_data->length) {
     99    AUBIO_MEMSET(read_data->data + source_read, 0,
     100        (read_data->length - source_read) * sizeof(smpl_t));
     101  }
     102}
     103
     104void
     105aubio_source_pad_multi_output (fmat_t *read_data,
     106    uint_t source_channels, uint_t source_read) {
     107  uint_t i;
     108  if (source_read < read_data->length) {
     109    for (i = 0; i < read_data->height; i++) {
     110      AUBIO_MEMSET(read_data->data[i] + source_read, 0,
     111          (read_data->length - source_read) * sizeof(smpl_t));
     112    }
     113  }
     114
     115  // destination matrix has more channels than the file
     116  // copy channels from the source to extra output channels
     117  if (read_data->height > source_channels) {
     118    for (i = source_channels; i < read_data->height; i++) {
     119      AUBIO_MEMCPY(read_data->data[i], read_data->data[i % source_channels],
     120          sizeof(smpl_t) * read_data->length);
     121    }
     122  }
     123}
     124
     125uint_t
     126aubio_sink_validate_input_length(const char_t *kind, const char_t *path,
     127    uint_t max_size, uint_t write_data_length, uint_t write)
     128{
     129  uint_t can_write = write;
     130
     131  if (write > max_size) {
     132    AUBIO_WRN("%s: partial write to %s, trying to write %d frames,"
     133        " at most %d can be written at once\n", kind, path, write, max_size);
     134    can_write = max_size;
     135  }
     136
     137  if (can_write > write_data_length) {
     138    AUBIO_WRN("%s: partial write to %s, trying to write %d frames,"
     139        " but found input of length %d\n", kind, path, write,
     140        write_data_length);
     141    can_write = write_data_length;
     142  }
     143
     144  return can_write;
     145}
     146
     147uint_t
     148aubio_sink_validate_input_channels(const char_t *kind, const char_t *path,
     149    uint_t sink_channels, uint_t write_data_height)
     150{
     151  uint_t channels = sink_channels;
     152  if (write_data_height < sink_channels) {
     153    AUBIO_WRN("%s: partial write to %s, trying to write %d channels,"
     154        " but found input of height %d\n", kind, path, sink_channels,
     155        write_data_height);
     156    channels = write_data_height;
     157  }
     158  return channels;
     159}
  • src/io/ioutils.h

    r086a45b rf2f1b10  
    5454    uint_t channels);
    5555
     56/** validate length of source output
     57
     58  \param kind       the object kind to report on
     59  \param path       the path to report on
     60  \param hop_size   number of frames to be read
     61  \param read_data_length actual length of input
     62
     63  \return hop_size or the maximum number of frames that can be written
     64*/
     65uint_t
     66aubio_source_validate_input_length(const char_t *kind, const char_t *path,
     67    uint_t hop_size, uint_t read_data_length);
     68
     69/** validate height of source output
     70
     71  \param kind       the object kind to report on
     72  \param path       the path to report on
     73  \param source_channels maximum number of channels that can be written
     74  \param read_data_height actual height of input
     75
     76  \return write_data_height or the maximum number of channels
     77*/
     78uint_t
     79aubio_source_validate_input_channels(const char_t *kind, const char_t *path,
     80    uint_t source_channels, uint_t read_data_height);
     81
     82/** pad end of source output vector with zeroes
     83
     84  \param read_data   output vector to pad
     85  \param source_read number of frames read
     86
     87*/
     88void
     89aubio_source_pad_output (fvec_t *read_data, uint_t source_read);
     90
     91/** pad end of source output matrix with zeroes
     92
     93  \param read_data   output matrix to pad
     94  \param source_channels number of channels in the source
     95  \param source_read number of frames read
     96
     97*/
     98void
     99aubio_source_pad_multi_output (fmat_t *read_data, uint_t source_channels,
     100        uint_t source_read);
     101
     102/** validate length of sink input
     103
     104  \param kind       the object kind to report on
     105  \param path       the path to report on
     106  \param max_size   maximum number of frames that can be written
     107  \param write_data_length actual length of input
     108  \param write number of samples asked
     109
     110  \return write or the maximum number of frames that can be written
     111*/
     112uint_t
     113aubio_sink_validate_input_length(const char_t *kind, const char_t *path,
     114    uint_t max_size, uint_t write_data_length, uint_t write);
     115
     116/** validate height of sink input
     117
     118  \param kind       the object kind to report on
     119  \param path       the path to report on
     120  \param sink_channels maximum number of channels that can be written
     121  \param write_data_height actual height of input matrix
     122
     123  \return write_data_height or the maximum number of channels
     124*/
     125uint_t
     126aubio_sink_validate_input_channels(const char_t *kind, const char_t *path,
     127    uint_t sink_channels, uint_t write_data_height);
     128
    56129#ifdef __cplusplus
    57130}
  • src/io/sink.c

    r086a45b rf2f1b10  
    103103  AUBIO_ERROR("sink: failed creating '%s' at %dHz (no sink built-in)\n", uri, samplerate);
    104104#endif
    105   AUBIO_FREE(s);
     105  del_aubio_sink(s);
    106106  return NULL;
    107107}
     
    136136
    137137void del_aubio_sink(aubio_sink_t * s) {
    138   if (!s) return;
    139   s->s_del((void *)s->sink);
     138  //AUBIO_ASSERT(s);
     139  if (s && s->s_del && s->sink)
     140    s->s_del((void *)s->sink);
    140141  AUBIO_FREE(s);
    141   return;
    142142}
  • src/io/sink_apple_audio.c

    r086a45b rf2f1b10  
    3232#include <AudioToolbox/AudioToolbox.h>
    3333
    34 #define FLOAT_TO_SHORT(x) (short)(x * 32768)
    35 
    36 extern int createAubioBufferList(AudioBufferList *bufferList, int channels, int segmentSize);
     34extern int createAudioBufferList(AudioBufferList *bufferList, int channels, int segmentSize);
    3735extern void freeAudioBufferList(AudioBufferList *bufferList);
    3836extern CFURLRef createURLFromPath(const char * path);
     
    6260  s->async = false;
    6361
    64   if ( (uri == NULL) || (strlen(uri) < 1) ) {
     62  if ( (uri == NULL) || (strnlen(uri, PATH_MAX) < 1) ) {
    6563    AUBIO_ERROR("sink_apple_audio: Aborted opening null path\n");
    6664    goto beach;
    6765  }
    68   if (s->path != NULL) AUBIO_FREE(s->path);
     66
    6967  s->path = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX) + 1);
    7068  strncpy(s->path, uri, strnlen(uri, PATH_MAX) + 1);
     
    7775    return s;
    7876  }
     77
    7978  // invalid samplerate given, abort
    8079  if (aubio_io_validate_samplerate("sink_apple_audio", s->path, samplerate)) {
     
    9291  return s;
    9392beach:
    94   AUBIO_FREE(s);
     93  del_aubio_sink_apple_audio(s);
    9594  return NULL;
    9695}
     
    103102  s->samplerate = samplerate;
    104103  // automatically open when both samplerate and channels have been set
    105   if (s->samplerate != 0 && s->channels != 0) {
     104  if (/* s->samplerate != 0 && */ s->channels != 0) {
    106105    return aubio_sink_apple_audio_open(s);
    107106  }
     
    116115  s->channels = channels;
    117116  // automatically open when both samplerate and channels have been set
    118   if (s->samplerate != 0 && s->channels != 0) {
     117  if (s->samplerate != 0 /* && s->channels != 0 */) {
    119118    return aubio_sink_apple_audio_open(s);
    120119  }
     
    151150  CFURLRef fileURL = createURLFromPath(s->path);
    152151  bool overwrite = true;
     152
     153  // set the in-memory format
     154  AudioStreamBasicDescription inputFormat;
     155  memset(&inputFormat, 0, sizeof(AudioStreamBasicDescription));
     156  inputFormat.mFormatID         = kAudioFormatLinearPCM;
     157  inputFormat.mSampleRate       = (Float64)(s->samplerate);
     158  inputFormat.mFormatFlags      = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked;
     159  inputFormat.mChannelsPerFrame = s->channels;
     160  inputFormat.mBitsPerChannel   = sizeof(smpl_t) * 8;
     161  inputFormat.mFramesPerPacket  = 1;
     162  inputFormat.mBytesPerFrame    = inputFormat.mBitsPerChannel * inputFormat.mChannelsPerFrame / 8;
     163  inputFormat.mBytesPerPacket   = inputFormat.mFramesPerPacket * inputFormat.mBytesPerFrame;
    153164  OSStatus err = noErr;
    154165  err = ExtAudioFileCreateWithURL(fileURL, fileType, &clientFormat, NULL,
     
    162173    goto beach;
    163174  }
    164   if (createAubioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) {
     175
     176  err = ExtAudioFileSetProperty(s->audioFile,
     177      kExtAudioFileProperty_ClientDataFormat,
     178      sizeof(AudioStreamBasicDescription), &inputFormat);
     179  if (err) {
     180    char_t errorstr[20];
     181    AUBIO_ERR("sink_apple_audio: error when trying to set output format on %s "
     182        "(%s)\n", s->path, getPrintableOSStatusError(errorstr, err));
     183    goto beach;
     184  }
     185
     186  if (createAudioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) {
    165187    AUBIO_ERR("sink_apple_audio: error when creating buffer list for %s, "
    166188        "out of memory? \n", s->path);
     
    175197void aubio_sink_apple_audio_do(aubio_sink_apple_audio_t * s, fvec_t * write_data, uint_t write) {
    176198  UInt32 c, v;
    177   short *data = (short*)s->bufferList.mBuffers[0].mData;
    178   if (write > s->max_frames) {
    179     AUBIO_WRN("sink_apple_audio: trying to write %d frames, max %d\n", write, s->max_frames);
    180     write = s->max_frames;
    181   }
    182   smpl_t *buf = write_data->data;
    183 
    184   if (buf) {
    185       for (c = 0; c < s->channels; c++) {
    186           for (v = 0; v < write; v++) {
    187               data[v * s->channels + c] =
    188                   FLOAT_TO_SHORT(buf[ v * s->channels + c]);
    189           }
    190       }
    191   }
    192   aubio_sink_apple_audio_write(s, write);
     199  smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
     200  uint_t length = aubio_sink_validate_input_length("sink_apple_audio", s->path,
     201      s->max_frames, write_data->length, write);
     202
     203  for (c = 0; c < s->channels; c++) {
     204    for (v = 0; v < length; v++) {
     205      data[v * s->channels + c] = write_data->data[v];
     206    }
     207  }
     208
     209  aubio_sink_apple_audio_write(s, length);
    193210}
    194211
    195212void aubio_sink_apple_audio_do_multi(aubio_sink_apple_audio_t * s, fmat_t * write_data, uint_t write) {
    196213  UInt32 c, v;
    197   short *data = (short*)s->bufferList.mBuffers[0].mData;
    198   if (write > s->max_frames) {
    199     AUBIO_WRN("sink_apple_audio: trying to write %d frames, max %d\n", write, s->max_frames);
    200     write = s->max_frames;
    201   }
    202   smpl_t **buf = write_data->data;
    203 
    204   if (buf) {
    205       for (c = 0; c < s->channels; c++) {
    206           for (v = 0; v < write; v++) {
    207               data[v * s->channels + c] =
    208                   FLOAT_TO_SHORT(buf[c][v]);
    209           }
    210       }
    211   }
    212   aubio_sink_apple_audio_write(s, write);
     214  smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
     215  uint_t channels = aubio_sink_validate_input_channels("sink_apple_audio",
     216      s->path, s->channels, write_data->height);
     217  uint_t length = aubio_sink_validate_input_length("sink_apple_audio", s->path,
     218      s->max_frames, write_data->length, write);
     219
     220  for (c = 0; c < channels; c++) {
     221    for (v = 0; v < length; v++) {
     222      data[v * s->channels + c] = write_data->data[c][v];
     223    }
     224  }
     225
     226  aubio_sink_apple_audio_write(s, length);
    213227}
    214228
    215229void aubio_sink_apple_audio_write(aubio_sink_apple_audio_t *s, uint_t write) {
    216230  OSStatus err = noErr;
     231  // set mDataByteSize to match the number of frames to be written
     232  // see https://www.mail-archive.com/coreaudio-api@lists.apple.com/msg01109.html
     233  s->bufferList.mBuffers[0].mDataByteSize = write * s->channels
     234    * sizeof(smpl_t);
    217235  if (s->async) {
    218236    err = ExtAudioFileWriteAsync(s->audioFile, write, &s->bufferList);
     
    258276
    259277void del_aubio_sink_apple_audio(aubio_sink_apple_audio_t * s) {
    260   if (s->audioFile) aubio_sink_apple_audio_close (s);
    261   if (s->path) AUBIO_FREE(s->path);
     278  AUBIO_ASSERT(s);
     279  if (s->audioFile)
     280    aubio_sink_apple_audio_close (s);
     281  if (s->path)
     282    AUBIO_FREE(s->path);
    262283  freeAudioBufferList(&s->bufferList);
    263284  AUBIO_FREE(s);
    264   return;
    265285}
    266286
  • src/io/sink_sndfile.c

    r086a45b rf2f1b10  
    5959  if (path == NULL) {
    6060    AUBIO_ERR("sink_sndfile: Aborted opening null path\n");
    61     return NULL;
    62   }
    63 
    64   if (s->path) AUBIO_FREE(s->path);
     61    goto beach;
     62  }
     63
    6564  s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
    6665  strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
     
    9897  s->samplerate = samplerate;
    9998  // automatically open when both samplerate and channels have been set
    100   if (s->samplerate != 0 && s->channels != 0) {
     99  if (/* s->samplerate != 0 && */ s->channels != 0) {
    101100    return aubio_sink_sndfile_open(s);
    102101  }
     
    111110  s->channels = channels;
    112111  // automatically open when both samplerate and channels have been set
    113   if (s->samplerate != 0 && s->channels != 0) {
     112  if (s->samplerate != 0 /* && s->channels != 0 */) {
    114113    return aubio_sink_sndfile_open(s);
    115114  }
     
    148147  /* allocate data for de/interleaving reallocated when needed. */
    149148  if (s->scratch_size >= MAX_SIZE * AUBIO_MAX_CHANNELS) {
    150     abort();
    151     AUBIO_ERR("sink_sndfile: %d x %d exceeds maximum aubio_sink_sndfile buffer size %d\n",
     149    AUBIO_ERR("sink_sndfile: %d x %d exceeds maximum buffer size %d\n",
    152150        s->max_size, s->channels, MAX_SIZE * AUBIO_MAX_CHANNELS);
    153151    return AUBIO_FAIL;
     
    159157
    160158void aubio_sink_sndfile_do(aubio_sink_sndfile_t *s, fvec_t * write_data, uint_t write){
    161   uint_t i, j, channels = s->channels;
    162   int nsamples = 0;
    163   smpl_t *pwrite;
     159  uint_t i, j;
    164160  sf_count_t written_frames;
    165 
    166   if (write > s->max_size) {
    167     AUBIO_WRN("sink_sndfile: trying to write %d frames, but only %d can be written at a time\n",
    168       write, s->max_size);
    169     write = s->max_size;
    170   }
    171 
    172   nsamples = channels * write;
     161  uint_t channels = s->channels;
     162  uint_t length = aubio_sink_validate_input_length("sink_sndfile", s->path,
     163      s->max_size, write_data->length, write);
     164  int nsamples = channels * length;
    173165
    174166  /* interleaving data  */
    175167  for ( i = 0; i < channels; i++) {
    176     pwrite = (smpl_t *)write_data->data;
    177     for (j = 0; j < write; j++) {
    178       s->scratch_data[channels*j+i] = pwrite[j];
     168    for (j = 0; j < length; j++) {
     169      s->scratch_data[channels*j+i] = write_data->data[j];
    179170    }
    180171  }
     
    189180
    190181void aubio_sink_sndfile_do_multi(aubio_sink_sndfile_t *s, fmat_t * write_data, uint_t write){
    191   uint_t i, j, channels = s->channels;
    192   int nsamples = 0;
    193   smpl_t *pwrite;
     182  uint_t i, j;
    194183  sf_count_t written_frames;
    195 
    196   if (write > s->max_size) {
    197     AUBIO_WRN("sink_sndfile: trying to write %d frames, but only %d can be written at a time\n",
    198       write, s->max_size);
    199     write = s->max_size;
    200   }
    201 
    202   nsamples = channels * write;
     184  uint_t channels = aubio_sink_validate_input_channels("sink_sndfile", s->path,
     185      s->channels, write_data->height);
     186  uint_t length = aubio_sink_validate_input_length("sink_sndfile", s->path,
     187      s->max_size, write_data->length, write);
     188  int nsamples = channels * length;
    203189
    204190  /* interleaving data  */
    205   for ( i = 0; i < write_data->height; i++) {
    206     pwrite = (smpl_t *)write_data->data[i];
    207     for (j = 0; j < write; j++) {
    208       s->scratch_data[channels*j+i] = pwrite[j];
     191  for ( i = 0; i < channels; i++) {
     192    for (j = 0; j < length; j++) {
     193      s->scratch_data[channels*j+i] = write_data->data[i][j];
    209194    }
    210195  }
     
    231216
    232217void del_aubio_sink_sndfile(aubio_sink_sndfile_t * s){
    233   if (!s) return;
    234   if (s->path) AUBIO_FREE(s->path);
    235   aubio_sink_sndfile_close(s);
    236   AUBIO_FREE(s->scratch_data);
     218  AUBIO_ASSERT(s);
     219  if (s->handle)
     220    aubio_sink_sndfile_close(s);
     221  if (s->path)
     222    AUBIO_FREE(s->path);
     223  if (s->scratch_data)
     224    AUBIO_FREE(s->scratch_data);
    237225  AUBIO_FREE(s);
    238226}
  • src/io/sink_wavwrite.c

    r086a45b rf2f1b10  
    2828#include "io/sink_wavwrite.h"
    2929#include "io/ioutils.h"
    30 
    31 #include <errno.h>
    3230
    3331#define MAX_SIZE 4096
     
    8886    goto beach;
    8987  }
    90   if ((sint_t)samplerate < 0) {
    91     AUBIO_ERR("sink_wavwrite: Can not create %s with samplerate %d\n", path, samplerate);
    92     goto beach;
    93   }
    94 
    95   if (s->path) AUBIO_FREE(s->path);
     88
    9689  s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
    9790  strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
     
    136129  s->samplerate = samplerate;
    137130  // automatically open when both samplerate and channels have been set
    138   if (s->samplerate != 0 && s->channels != 0) {
     131  if (/* s->samplerate != 0 && */ s->channels != 0) {
    139132    return aubio_sink_wavwrite_open(s);
    140133  }
     
    149142  s->channels = channels;
    150143  // automatically open when both samplerate and channels have been set
    151   if (s->samplerate != 0 && s->channels != 0) {
     144  if (s->samplerate != 0 /* && s->channels != 0 */) {
    152145    return aubio_sink_wavwrite_open(s);
    153146  }
     
    168161  unsigned char buf[5];
    169162  uint_t byterate, blockalign;
     163  size_t written = 0;
    170164
    171165  /* open output file */
    172166  s->fid = fopen((const char *)s->path, "wb");
    173167  if (!s->fid) {
    174     AUBIO_ERR("sink_wavwrite: could not open %s (%s)\n", s->path, strerror(errno));
     168    AUBIO_STRERR("sink_wavwrite: could not open %s (%s)\n", s->path, errorstr);
    175169    goto beach;
    176170  }
    177171
    178172  // ChunkID
    179   fwrite("RIFF", 4, 1, s->fid);
     173  written += fwrite("RIFF", 4, 1, s->fid);
    180174
    181175  // ChunkSize (0 for now, actual size will be written in _close)
    182   fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
     176  written += fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
    183177
    184178  // Format
    185   fwrite("WAVE", 4, 1, s->fid);
     179  written += fwrite("WAVE", 4, 1, s->fid);
    186180
    187181  // Subchunk1ID
    188   fwrite("fmt ", 4, 1, s->fid);
     182  written += fwrite("fmt ", 4, 1, s->fid);
    189183
    190184  // Subchunk1Size
    191   fwrite(write_little_endian(16, buf, 4), 4, 1, s->fid);
     185  written += fwrite(write_little_endian(16, buf, 4), 4, 1, s->fid);
    192186
    193187  // AudioFormat
    194   fwrite(write_little_endian(1, buf, 2), 2, 1, s->fid);
     188  written += fwrite(write_little_endian(1, buf, 2), 2, 1, s->fid);
    195189
    196190  // NumChannels
    197   fwrite(write_little_endian(s->channels, buf, 2), 2, 1, s->fid);
     191  written += fwrite(write_little_endian(s->channels, buf, 2), 2, 1, s->fid);
    198192
    199193  // SampleRate
    200   fwrite(write_little_endian(s->samplerate, buf, 4), 4, 1, s->fid);
     194  written += fwrite(write_little_endian(s->samplerate, buf, 4), 4, 1, s->fid);
    201195
    202196  // ByteRate
    203197  byterate = s->samplerate * s->channels * s->bitspersample / 8;
    204   fwrite(write_little_endian(byterate, buf, 4), 4, 1, s->fid);
     198  written += fwrite(write_little_endian(byterate, buf, 4), 4, 1, s->fid);
    205199
    206200  // BlockAlign
    207201  blockalign = s->channels * s->bitspersample / 8;
    208   fwrite(write_little_endian(blockalign, buf, 2), 2, 1, s->fid);
     202  written += fwrite(write_little_endian(blockalign, buf, 2), 2, 1, s->fid);
    209203
    210204  // BitsPerSample
    211   fwrite(write_little_endian(s->bitspersample, buf, 2), 2, 1, s->fid);
     205  written += fwrite(write_little_endian(s->bitspersample, buf, 2), 2, 1, s->fid);
    212206
    213207  // Subchunk2ID
    214   fwrite("data", 4, 1, s->fid);
     208  written += fwrite("data", 4, 1, s->fid);
    215209
    216210  // Subchunk1Size (0 for now, actual size will be written in _close)
    217   fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
     211  written += fwrite(write_little_endian(0, buf, 4), 4, 1, s->fid);
     212
     213  // fwrite(*, *, 1, s->fid) was called 13 times, check success
     214  if (written != 13 || fflush(s->fid)) {
     215    AUBIO_STRERR("sink_wavwrite: writing header to %s failed"
     216        " (wrote %d/%d, %s)\n", s->path, written, 13, errorstr);
     217    fclose(s->fid);
     218    s->fid = NULL;
     219    return AUBIO_FAIL;
     220  }
    218221
    219222  s->scratch_size = s->max_size * s->channels;
     
    232235}
    233236
     237static
     238void aubio_sink_wavwrite_write_frames(aubio_sink_wavwrite_t *s, uint_t write)
     239{
     240  uint_t written_frames = 0;
     241
     242  written_frames = fwrite(s->scratch_data, 2 * s->channels, write, s->fid);
     243
     244  if (written_frames != write) {
     245    AUBIO_STRERR("sink_wavwrite: trying to write %d frames to %s, but only %d"
     246        " could be written (%s)\n", write, s->path, written_frames, errorstr);
     247  }
     248  s->total_frames_written += written_frames;
     249}
    234250
    235251void aubio_sink_wavwrite_do(aubio_sink_wavwrite_t *s, fvec_t * write_data, uint_t write){
    236   uint_t i = 0, written_frames = 0;
    237 
    238   if (write > s->max_size) {
    239     AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, "
    240         "but only %d can be written at a time\n", write, s->path, s->max_size);
    241     write = s->max_size;
    242   }
    243 
    244   for (i = 0; i < write; i++) {
    245     s->scratch_data[i] = HTOLES(FLOAT_TO_SHORT(write_data->data[i]));
    246   }
    247   written_frames = fwrite(s->scratch_data, 2, write, s->fid);
    248 
    249   if (written_frames != write) {
    250     AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, "
    251         "but only %d could be written\n", write, s->path, written_frames);
    252   }
    253   s->total_frames_written += written_frames;
    254   return;
     252  uint_t c = 0, i = 0;
     253  uint_t length = aubio_sink_validate_input_length("sink_wavwrite", s->path,
     254      s->max_size, write_data->length, write);
     255
     256  for (c = 0; c < s->channels; c++) {
     257    for (i = 0; i < length; i++) {
     258      s->scratch_data[i * s->channels + c] = HTOLES(FLOAT_TO_SHORT(write_data->data[i]));
     259    }
     260  }
     261
     262  aubio_sink_wavwrite_write_frames(s, length);
    255263}
    256264
    257265void aubio_sink_wavwrite_do_multi(aubio_sink_wavwrite_t *s, fmat_t * write_data, uint_t write){
    258   uint_t c = 0, i = 0, written_frames = 0;
    259 
    260   if (write > s->max_size) {
    261     AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, "
    262         "but only %d can be written at a time\n", write, s->path, s->max_size);
    263     write = s->max_size;
    264   }
    265 
    266   for (c = 0; c < s->channels; c++) {
    267     for (i = 0; i < write; i++) {
     266  uint_t c = 0, i = 0;
     267
     268  uint_t channels = aubio_sink_validate_input_channels("sink_wavwrite", s->path,
     269      s->channels, write_data->height);
     270  uint_t length = aubio_sink_validate_input_length("sink_wavwrite", s->path,
     271      s->max_size, write_data->length, write);
     272
     273  for (c = 0; c < channels; c++) {
     274    for (i = 0; i < length; i++) {
    268275      s->scratch_data[i * s->channels + c] = HTOLES(FLOAT_TO_SHORT(write_data->data[c][i]));
    269276    }
    270277  }
    271   written_frames = fwrite(s->scratch_data, 2, write * s->channels, s->fid);
    272 
    273   if (written_frames != write * s->channels) {
    274     AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, "
    275         "but only %d could be written\n", write, s->path, written_frames / s->channels);
    276   }
    277   s->total_frames_written += written_frames;
    278   return;
     278
     279  aubio_sink_wavwrite_write_frames(s, length);
    279280}
    280281
     
    282283  uint_t data_size = s->total_frames_written * s->bitspersample * s->channels / 8;
    283284  unsigned char buf[5];
     285  size_t written = 0, err = 0;
    284286  if (!s->fid) return AUBIO_FAIL;
    285287  // ChunkSize
    286   fseek(s->fid, 4, SEEK_SET);
    287   fwrite(write_little_endian(data_size + 36, buf, 4), 4, 1, s->fid);
     288  err += fseek(s->fid, 4, SEEK_SET);
     289  written += fwrite(write_little_endian(data_size + 36, buf, 4), 4, 1, s->fid);
    288290  // Subchunk2Size
    289   fseek(s->fid, 40, SEEK_SET);
    290   fwrite(write_little_endian(data_size, buf, 4), 4, 1, s->fid);
     291  err += fseek(s->fid, 40, SEEK_SET);
     292  written += fwrite(write_little_endian(data_size, buf, 4), 4, 1, s->fid);
     293  if (written != 2 || err != 0) {
     294    AUBIO_STRERR("sink_wavwrite: updating header of %s failed, expected %d"
     295        " write but got only %d (%s)\n", s->path, 2, written, errorstr);
     296  }
    291297  // close file
    292298  if (fclose(s->fid)) {
    293     AUBIO_ERR("sink_wavwrite: Error closing file %s (%s)\n", s->path, strerror(errno));
     299    AUBIO_STRERR("sink_wavwrite: Error closing file %s (%s)\n", s->path, errorstr);
    294300  }
    295301  s->fid = NULL;
     
    298304
    299305void del_aubio_sink_wavwrite(aubio_sink_wavwrite_t * s){
    300   if (!s) return;
    301   aubio_sink_wavwrite_close(s);
    302   if (s->path) AUBIO_FREE(s->path);
    303   AUBIO_FREE(s->scratch_data);
     306  AUBIO_ASSERT(s);
     307  if (s->fid)
     308    aubio_sink_wavwrite_close(s);
     309  if (s->path)
     310    AUBIO_FREE(s->path);
     311  if (s->scratch_data)
     312    AUBIO_FREE(s->scratch_data);
    304313  AUBIO_FREE(s);
    305314}
  • src/io/source.c

    r086a45b rf2f1b10  
    122122     " (no source built-in)\n", uri, samplerate, hop_size);
    123123#endif
    124   AUBIO_FREE(s);
     124  del_aubio_source(s);
    125125  return NULL;
    126126}
     
    139139
    140140void del_aubio_source(aubio_source_t * s) {
    141   if (!s) return;
    142   s->s_del((void *)s->source);
     141  //AUBIO_ASSERT(s);
     142  if (s && s->s_del && s->source)
     143    s->s_del((void *)s->source);
    143144  AUBIO_FREE(s);
    144145}
  • src/io/source.h

    r086a45b rf2f1b10  
    6060
    6161  \example io/test-source.c
    62   \example io/test-source_multi.c
    6362
    6463*/
  • src/io/source_apple_audio.c

    r086a45b rf2f1b10  
    2525#include "fvec.h"
    2626#include "fmat.h"
     27#include "ioutils.h"
    2728#include "io/source_apple_audio.h"
    2829
     
    3435#define RT_BYTE3( a )      ( ((a) >> 16) & 0xff )
    3536#define RT_BYTE4( a )      ( ((a) >> 24) & 0xff )
    36 
    37 #define SHORT_TO_FLOAT(x) (smpl_t)(x * 3.0517578125e-05)
    3837
    3938struct _aubio_source_apple_audio_t {
     
    4948};
    5049
    51 extern int createAubioBufferList(AudioBufferList *bufferList, int channels, int max_source_samples);
     50extern int createAudioBufferList(AudioBufferList *bufferList, int channels, int max_source_samples);
    5251extern void freeAudioBufferList(AudioBufferList *bufferList);
    5352extern CFURLRef createURLFromPath(const char * path);
     
    6059  aubio_source_apple_audio_t * s = AUBIO_NEW(aubio_source_apple_audio_t);
    6160
    62   if (path == NULL) {
     61  if (path == NULL || strnlen(path, PATH_MAX) < 1) {
    6362    AUBIO_ERROR("source_apple_audio: Aborted opening null path\n");
    6463    goto beach;
     
    8685
    8786beach:
    88   AUBIO_FREE(s);
     87  del_aubio_source_apple_audio(s);
    8988  return NULL;
    9089}
     
    9594  UInt32 propSize;
    9695
    97   if (s->path) AUBIO_FREE(s->path);
    9896  s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
    9997  strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
     
    140138
    141139  AudioStreamBasicDescription clientFormat;
    142   propSize = sizeof(clientFormat);
     140  propSize = sizeof(AudioStreamBasicDescription);
    143141  memset(&clientFormat, 0, sizeof(AudioStreamBasicDescription));
    144142  clientFormat.mFormatID         = kAudioFormatLinearPCM;
    145143  clientFormat.mSampleRate       = (Float64)(s->samplerate);
    146   clientFormat.mFormatFlags      = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
     144  clientFormat.mFormatFlags      = kAudioFormatFlagIsFloat;
    147145  clientFormat.mChannelsPerFrame = s->channels;
    148   clientFormat.mBitsPerChannel   = sizeof(short) * 8;
     146  clientFormat.mBitsPerChannel   = sizeof(smpl_t) * 8;
    149147  clientFormat.mFramesPerPacket  = 1;
    150148  clientFormat.mBytesPerFrame    = clientFormat.mBitsPerChannel * clientFormat.mChannelsPerFrame / 8;
    151149  clientFormat.mBytesPerPacket   = clientFormat.mFramesPerPacket * clientFormat.mBytesPerFrame;
    152   clientFormat.mReserved         = 0;
    153150
    154151  // set the client format description
     
    188185  // allocate the AudioBufferList
    189186  freeAudioBufferList(&s->bufferList);
    190   if (createAubioBufferList(&s->bufferList, s->channels, s->block_size * s->channels)) {
     187  if (createAudioBufferList(&s->bufferList, s->channels, s->block_size * s->channels)) {
    191188    AUBIO_ERR("source_apple_audio: failed creating bufferList\n");
    192189    goto beach;
     
    197194}
    198195
    199 void aubio_source_apple_audio_do(aubio_source_apple_audio_t *s, fvec_t * read_to, uint_t * read) {
    200   UInt32 c, v, loadedPackets = s->block_size;
     196static UInt32 aubio_source_apple_audio_read_frame(aubio_source_apple_audio_t *s)
     197{
     198  UInt32 loadedPackets = s->block_size;
    201199  OSStatus err = ExtAudioFileRead(s->audioFile, &loadedPackets, &s->bufferList);
    202200  if (err) {
     
    205203        "with ExtAudioFileRead (%s)\n", s->path,
    206204        getPrintableOSStatusError(errorstr, err));
    207     goto beach;
    208   }
    209 
    210   short *data = (short*)s->bufferList.mBuffers[0].mData;
    211 
    212   smpl_t *buf = read_to->data;
    213 
    214   for (v = 0; v < loadedPackets; v++) {
    215     buf[v] = 0.;
     205  }
     206  return loadedPackets;
     207}
     208
     209void aubio_source_apple_audio_do(aubio_source_apple_audio_t *s, fvec_t * read_to,
     210    uint_t * read) {
     211  uint_t c, v;
     212  UInt32 loadedPackets = aubio_source_apple_audio_read_frame(s);
     213  uint_t length = aubio_source_validate_input_length("source_apple_audio",
     214      s->path, s->block_size, read_to->length);
     215  smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
     216
     217  length = MIN(loadedPackets, length);
     218
     219  for (v = 0; v < length; v++) {
     220    read_to->data[v] = 0.;
    216221    for (c = 0; c < s->channels; c++) {
    217       buf[v] += SHORT_TO_FLOAT(data[ v * s->channels + c]);
     222      read_to->data[v] += data[ v * s->channels + c];
    218223    }
    219     buf[v] /= (smpl_t)s->channels;
     224    read_to->data[v] /= (smpl_t)s->channels;
    220225  }
    221226  // short read, fill with zeros
    222   if (loadedPackets < s->block_size) {
    223     for (v = loadedPackets; v < s->block_size; v++) {
    224       buf[v] = 0.;
     227  aubio_source_pad_output(read_to, length);
     228
     229  *read = (uint_t)length;
     230}
     231
     232void aubio_source_apple_audio_do_multi(aubio_source_apple_audio_t *s, fmat_t * read_to, uint_t * read) {
     233  uint_t c, v;
     234  uint_t length = aubio_source_validate_input_length("source_apple_audio",
     235      s->path, s->block_size, read_to->length);
     236  uint_t channels = aubio_source_validate_input_channels("source_apple_audio",
     237      s->path, s->channels, read_to->height);
     238  UInt32 loadedPackets = aubio_source_apple_audio_read_frame(s);
     239  smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
     240
     241  length = MIN(loadedPackets, length);
     242
     243  for (v = 0; v < length; v++) {
     244    for (c = 0; c < channels; c++) {
     245      read_to->data[c][v] = data[ v * s->channels + c];
    225246    }
    226247  }
    227248
    228   *read = (uint_t)loadedPackets;
    229   return;
    230 beach:
    231   *read = 0;
    232   return;
    233 }
    234 
    235 void aubio_source_apple_audio_do_multi(aubio_source_apple_audio_t *s, fmat_t * read_to, uint_t * read) {
    236   UInt32 c, v, loadedPackets = s->block_size;
    237   OSStatus err = ExtAudioFileRead(s->audioFile, &loadedPackets, &s->bufferList);
    238   if (err) {
    239     char_t errorstr[20];
    240     AUBIO_ERROR("source_apple_audio: error while reading %s "
    241         "with ExtAudioFileRead (%s)\n", s->path,
    242         getPrintableOSStatusError(errorstr, err));
    243     goto beach;
    244   }
    245 
    246   short *data = (short*)s->bufferList.mBuffers[0].mData;
    247 
    248   smpl_t **buf = read_to->data;
    249 
    250   for (v = 0; v < loadedPackets; v++) {
    251     for (c = 0; c < read_to->height; c++) {
    252       buf[c][v] = SHORT_TO_FLOAT(data[ v * s->channels + c]);
    253     }
    254   }
    255   // if read_data has more channels than the file
    256   if (read_to->height > s->channels) {
    257     // copy last channel to all additional channels
    258     for (v = 0; v < loadedPackets; v++) {
    259       for (c = s->channels; c < read_to->height; c++) {
    260         buf[c][v] = SHORT_TO_FLOAT(data[ v * s->channels + (s->channels - 1)]);
    261       }
    262     }
    263   }
    264   // short read, fill with zeros
    265   if (loadedPackets < s->block_size) {
    266     for (v = loadedPackets; v < s->block_size; v++) {
    267       for (c = 0; c < read_to->height; c++) {
    268         buf[c][v] = 0.;
    269       }
    270     }
    271   }
    272   *read = (uint_t)loadedPackets;
    273   return;
    274 beach:
    275   *read = 0;
    276   return;
     249  aubio_source_pad_multi_output(read_to, s->channels, (uint_t)length);
     250
     251  *read = (uint_t)length;
    277252}
    278253
     
    294269
    295270void del_aubio_source_apple_audio(aubio_source_apple_audio_t * s){
     271  AUBIO_ASSERT(s);
    296272  aubio_source_apple_audio_close (s);
    297273  if (s->path) AUBIO_FREE(s->path);
    298274  freeAudioBufferList(&s->bufferList);
    299275  AUBIO_FREE(s);
    300   return;
    301276}
    302277
     
    324299  // after a short read, the bufferList size needs to resetted to prepare for a full read
    325300  AudioBufferList *bufferList = &s->bufferList;
    326   bufferList->mBuffers[0].mDataByteSize = s->block_size * s->channels * sizeof (short);
     301  bufferList->mBuffers[0].mDataByteSize = s->block_size * s->channels * sizeof (smpl_t);
    327302  // do the actual seek
    328303  err = ExtAudioFileSeek(s->audioFile, resampled_pos);
     
    370345        "error in ExtAudioFileGetProperty (%s)\n", s->path,
    371346        getPrintableOSStatusError(errorstr, err));
    372     return err;
     347    return 0;
    373348  }
    374349  return (uint_t)fileLengthFrames;
  • src/io/source_avcodec.c

    r086a45b rf2f1b10  
    3131#endif
    3232#include <libavutil/opt.h>
    33 #include <stdlib.h>
    3433
    3534// determine whether we use libavformat from ffmpeg or from libav
    3635#define FFMPEG_LIBAVFORMAT (LIBAVFORMAT_VERSION_MICRO > 99 )
    37 // max_analyze_duration2 was used from ffmpeg libavformat 55.43.100 through 57.2.100
     36// max_analyze_duration2 was used from ffmpeg libavformat 55.43.100 -> 57.2.100
    3837#define FFMPEG_LIBAVFORMAT_MAX_DUR2 FFMPEG_LIBAVFORMAT && ( \
    3938      (LIBAVFORMAT_VERSION_MAJOR == 55 && LIBAVFORMAT_VERSION_MINOR >= 43) \
     
    4746#endif
    4847
     48#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,3,102)
     49#define HAVE_AUBIO_LIBAVCODEC_TIMEBASE_FIX 1
     50#endif
     51
    4952#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
    5053#warning "libavcodec < 56 is deprecated"
     
    5760#include "fvec.h"
    5861#include "fmat.h"
     62#include "ioutils.h"
    5963#include "source_avcodec.h"
    6064
     65#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56, 56, 0)
    6166#define AUBIO_AVCODEC_MAX_BUFFER_SIZE FF_MIN_BUFFER_SIZE
     67#else
     68#define AUBIO_AVCODEC_MAX_BUFFER_SIZE AV_INPUT_BUFFER_MIN_SIZE
     69#endif
    6270
    6371struct _aubio_source_avcodec_t {
     
    8694  sint_t selected_stream;
    8795  uint_t eof;
    88   uint_t multi;
    8996};
    9097
    91 // hack to create or re-create the context the first time _do or _do_multi is called
    92 void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi);
    93 void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_samples);
     98// create or re-create the context when _do or _do_multi is called
     99void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s);
     100// actually read a frame
     101void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s,
     102    uint_t * read_samples);
    94103
    95104uint_t aubio_source_avcodec_has_network_url(aubio_source_avcodec_t *s);
     
    108117
    109118
    110 aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path, uint_t samplerate, uint_t hop_size) {
     119aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path,
     120    uint_t samplerate, uint_t hop_size) {
    111121  aubio_source_avcodec_t * s = AUBIO_NEW(aubio_source_avcodec_t);
    112   AVFormatContext *avFormatCtx = s->avFormatCtx;
    113   AVCodecContext *avCodecCtx = s->avCodecCtx;
    114   AVFrame *avFrame = s->avFrame;
     122  AVFormatContext *avFormatCtx = NULL;
     123  AVCodecContext *avCodecCtx = NULL;
     124  AVFrame *avFrame = NULL;
    115125  sint_t selected_stream = -1;
    116126#if FF_API_LAVF_AVCTX
     
    125135  }
    126136  if ((sint_t)samplerate < 0) {
    127     AUBIO_ERR("source_avcodec: Can not open %s with samplerate %d\n", path, samplerate);
     137    AUBIO_ERR("source_avcodec: Can not open %s with samplerate %d\n",
     138        path, samplerate);
    128139    goto beach;
    129140  }
    130141  if ((sint_t)hop_size <= 0) {
    131     AUBIO_ERR("source_avcodec: Can not open %s with hop_size %d\n", path, hop_size);
     142    AUBIO_ERR("source_avcodec: Can not open %s with hop_size %d\n",
     143        path, hop_size);
    132144    goto beach;
    133145  }
     
    136148  s->channels = 1;
    137149
    138   if (s->path) AUBIO_FREE(s->path);
    139150  s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
    140151  strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
    141152
     153#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58,0,0)
    142154  // register all formats and codecs
    143155  av_register_all();
     156#endif
    144157
    145158  if (aubio_source_avcodec_has_network_url(s)) {
     
    167180    char errorstr[256];
    168181    av_strerror (err, errorstr, sizeof(errorstr));
    169     AUBIO_ERR("source_avcodec: Could not find stream information " "for %s (%s)\n", s->path,
    170         errorstr);
     182    AUBIO_ERR("source_avcodec: Could not find stream information "
     183        "for %s (%s)\n", s->path, errorstr);
    171184    goto beach;
    172185  }
     
    208221  avCodecCtx = avcodec_alloc_context3(codec);
    209222  if (!avCodecCtx) {
    210     AUBIO_ERR("source_avcodec: Failed to allocate the %s codec context for path %s\n",
    211         av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path);
     223    AUBIO_ERR("source_avcodec: Failed to allocate the %s codec context "
     224        "for path %s\n", av_get_media_type_string(AVMEDIA_TYPE_AUDIO),
     225        s->path);
    212226    goto beach;
    213227  }
     
    224238  /* Copy codec parameters from input stream to output codec context */
    225239  if ((err = avcodec_parameters_to_context(avCodecCtx, codecpar)) < 0) {
    226     AUBIO_ERR("source_avcodec: Failed to copy %s codec parameters to decoder context for %s\n",
    227        av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path);
    228     goto beach;
    229   }
     240    AUBIO_ERR("source_avcodec: Failed to copy %s codec parameters to "
     241        "decoder context for %s\n",
     242        av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path);
     243    goto beach;
     244  }
     245#if HAVE_AUBIO_LIBAVCODEC_TIMEBASE_FIX
     246  // avoids 'skipped frames warning' with avecodec < 58, deprecated after
     247  av_codec_set_pkt_timebase(avCodecCtx,
     248      avFormatCtx->streams[selected_stream]->time_base);
     249#endif
    230250#endif
    231251
     
    233253    char errorstr[256];
    234254    av_strerror (err, errorstr, sizeof(errorstr));
    235     AUBIO_ERR("source_avcodec: Could not load codec for %s (%s)\n", s->path, errorstr);
     255    AUBIO_ERR("source_avcodec: Could not load codec for %s (%s)\n", s->path,
     256        errorstr);
    236257    goto beach;
    237258  }
     
    260281
    261282  /* allocate output for avr */
    262   s->output = (smpl_t *)av_malloc(AUBIO_AVCODEC_MAX_BUFFER_SIZE * sizeof(smpl_t));
     283  s->output = (smpl_t *)av_malloc(AUBIO_AVCODEC_MAX_BUFFER_SIZE
     284      * sizeof(smpl_t));
    263285
    264286  s->read_samples = 0;
     
    269291  s->avFrame = avFrame;
    270292
    271   // default to mono output
    272   aubio_source_avcodec_reset_resampler(s, 0);
     293  aubio_source_avcodec_reset_resampler(s);
     294
     295  if (s->avr == NULL) goto beach;
    273296
    274297  s->eof = 0;
    275   s->multi = 0;
    276298
    277299  //av_log_set_level(AV_LOG_QUIET);
     
    286308}
    287309
    288 void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s, uint_t multi) {
     310void aubio_source_avcodec_reset_resampler(aubio_source_avcodec_t * s)
     311{
    289312  // create or reset resampler to/from mono/multi-channel
    290   if ( (multi != s->multi) || (s->avr == NULL) ) {
     313  if ( s->avr == NULL ) {
    291314    int err;
    292315    int64_t input_layout = av_get_default_channel_layout(s->input_channels);
    293     uint_t output_channels = multi ? s->input_channels : 1;
    294     int64_t output_layout = av_get_default_channel_layout(output_channels);
     316    int64_t output_layout = av_get_default_channel_layout(s->input_channels);
    295317#ifdef HAVE_AVRESAMPLE
    296318    AVAudioResampleContext *avr = avresample_alloc_context();
    297     AVAudioResampleContext *oldavr = s->avr;
    298319#elif defined(HAVE_SWRESAMPLE)
    299320    SwrContext *avr = swr_alloc();
    300     SwrContext *oldavr = s->avr;
    301321#endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
    302322
    303     av_opt_set_int(avr, "in_channel_layout",  input_layout,           0);
    304     av_opt_set_int(avr, "out_channel_layout", output_layout,          0);
    305     av_opt_set_int(avr, "in_sample_rate",     s->input_samplerate,    0);
    306     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);
    307327    av_opt_set_int(avr, "in_sample_fmt",      s->avCodecCtx->sample_fmt, 0);
    308328#if HAVE_AUBIO_DOUBLE
    309     av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_DBL,      0);
    310 #else
    311     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);
    312332#endif
    313333    // TODO: use planar?
     
    321341      char errorstr[256];
    322342      av_strerror (err, errorstr, sizeof(errorstr));
    323       AUBIO_ERR("source_avcodec: Could not open resampling context for %s (%s)\n",
    324           s->path, errorstr);
     343      AUBIO_ERR("source_avcodec: Could not open resampling context"
     344         " for %s (%s)\n", s->path, errorstr);
    325345      return;
    326346    }
    327347    s->avr = avr;
    328     if (oldavr != NULL) {
    329 #ifdef HAVE_AVRESAMPLE
    330       avresample_close( oldavr );
    331 #elif defined(HAVE_SWRESAMPLE)
    332       swr_close ( oldavr );
    333 #endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
    334       av_free ( oldavr );
    335       oldavr = NULL;
    336     }
    337     s->multi = multi;
    338   }
    339 }
    340 
    341 void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s, uint_t * read_samples) {
     348  }
     349}
     350
     351void aubio_source_avcodec_readframe(aubio_source_avcodec_t *s,
     352    uint_t * read_samples)
     353{
    342354  AVFormatContext *avFormatCtx = s->avFormatCtx;
    343355  AVCodecContext *avCodecCtx = s->avCodecCtx;
     
    380392      char errorstr[256];
    381393      av_strerror (err, errorstr, sizeof(errorstr));
    382       AUBIO_ERR("source_avcodec: could not read frame in %s (%s)\n", s->path, errorstr);
     394      AUBIO_ERR("source_avcodec: could not read frame in %s (%s)\n",
     395          s->path, errorstr);
    383396      s->eof = 1;
    384397      goto beach;
     
    398411  if (ret < 0) {
    399412    if (ret == AVERROR(EAGAIN)) {
    400       //AUBIO_WRN("source_avcodec: output is not available right now - user must try to send new input\n");
     413      //AUBIO_WRN("source_avcodec: output is not available right now - "
     414      //    "user must try to send new input\n");
    401415      goto beach;
    402416    } else if (ret == AVERROR_EOF) {
    403       AUBIO_WRN("source_avcodec: the decoder has been fully flushed, and there will be no more output frames\n");
     417      AUBIO_WRN("source_avcodec: the decoder has been fully flushed, "
     418          "and there will be no more output frames\n");
    404419    } else {
    405420      AUBIO_ERR("source_avcodec: decoding errors on %s\n", s->path);
     
    416431#endif
    417432  if (got_frame == 0) {
    418     AUBIO_WRN("source_avcodec: did not get a frame when reading %s\n", s->path);
    419     goto beach;
    420   }
     433    AUBIO_WRN("source_avcodec: did not get a frame when reading %s\n",
     434        s->path);
     435    goto beach;
     436  }
     437
     438#if LIBAVUTIL_VERSION_MAJOR > 52
     439  if (avFrame->channels != (sint_t)s->input_channels) {
     440    AUBIO_WRN ("source_avcodec: trying to read from %d channel(s),"
     441        "but configured for %d; is '%s' corrupt?\n",
     442        avFrame->channels, s->input_channels, s->path);
     443    goto beach;
     444  }
     445#else
     446#warning "avutil < 53 is deprecated, crashes might occur on corrupt files"
     447#endif
    421448
    422449#ifdef HAVE_AVRESAMPLE
     
    437464      (const uint8_t **)avFrame->data, in_samples);
    438465#endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
    439   if (out_samples <= 0) {
    440     AUBIO_WRN("source_avcodec: no sample found while converting frame (%s)\n", s->path);
     466  if (out_samples < 0) {
     467    AUBIO_WRN("source_avcodec: error while resampling %s (%d)\n",
     468        s->path, out_samples);
    441469    goto beach;
    442470  }
     
    445473
    446474beach:
    447   s->avFormatCtx = avFormatCtx;
    448   s->avCodecCtx = avCodecCtx;
    449   s->avFrame = avFrame;
    450 #if defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)
    451   s->avr = avr;
    452 #endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
    453   s->output = output;
    454 
    455475  av_packet_unref(&avPacket);
    456476}
    457477
    458 void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data, uint_t * read){
    459   uint_t i;
     478void aubio_source_avcodec_do(aubio_source_avcodec_t * s, fvec_t * read_data,
     479    uint_t * read) {
     480  uint_t i, j;
    460481  uint_t end = 0;
    461482  uint_t total_wrote = 0;
    462   // switch from multi
    463   if (s->multi == 1) aubio_source_avcodec_reset_resampler(s, 0);
    464   while (total_wrote < s->hop_size) {
    465     end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
     483  uint_t length = aubio_source_validate_input_length("source_avcodec", s->path,
     484      s->hop_size, read_data->length);
     485  if (!s->avr || !s->avFormatCtx || !s->avCodecCtx) {
     486    AUBIO_ERR("source_avcodec: could not read from %s (file was closed)\n",
     487        s->path);
     488    *read= 0;
     489    return;
     490  }
     491  while (total_wrote < length) {
     492    end = MIN(s->read_samples - s->read_index, length - total_wrote);
    466493    for (i = 0; i < end; i++) {
    467       read_data->data[i + total_wrote] = s->output[i + s->read_index];
     494      read_data->data[i + total_wrote] = 0.;
     495      for (j = 0; j < s->input_channels; j++) {
     496        read_data->data[i + total_wrote] +=
     497          s->output[(i + s->read_index) * s->input_channels + j];
     498      }
     499      read_data->data[i + total_wrote] *= 1./s->input_channels;
    468500    }
    469501    total_wrote += end;
    470     if (total_wrote < s->hop_size) {
     502    if (total_wrote < length) {
    471503      uint_t avcodec_read = 0;
    472504      aubio_source_avcodec_readframe(s, &avcodec_read);
     
    480512    }
    481513  }
    482   if (total_wrote < s->hop_size) {
    483     for (i = total_wrote; i < s->hop_size; i++) {
    484       read_data->data[i] = 0.;
    485     }
    486   }
     514
     515  aubio_source_pad_output(read_data, total_wrote);
     516
    487517  *read = total_wrote;
    488518}
    489519
    490 void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s, fmat_t * read_data, uint_t * read){
     520void aubio_source_avcodec_do_multi(aubio_source_avcodec_t * s,
     521    fmat_t * read_data, uint_t * read) {
    491522  uint_t i,j;
    492523  uint_t end = 0;
    493524  uint_t total_wrote = 0;
    494   // switch from mono
    495   if (s->multi == 0) aubio_source_avcodec_reset_resampler(s, 1);
    496   while (total_wrote < s->hop_size) {
    497     end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
    498     for (j = 0; j < read_data->height; j++) {
     525  uint_t length = aubio_source_validate_input_length("source_avcodec", s->path,
     526      s->hop_size, read_data->length);
     527  uint_t channels = aubio_source_validate_input_channels("source_avcodec",
     528      s->path, s->input_channels, read_data->height);
     529  if (!s->avr || !s->avFormatCtx || !s->avCodecCtx) {
     530    AUBIO_ERR("source_avcodec: could not read from %s (file was closed)\n",
     531        s->path);
     532    *read= 0;
     533    return;
     534  }
     535  while (total_wrote < length) {
     536    end = MIN(s->read_samples - s->read_index, length - total_wrote);
     537    for (j = 0; j < channels; j++) {
    499538      for (i = 0; i < end; i++) {
    500539        read_data->data[j][i + total_wrote] =
     
    503542    }
    504543    total_wrote += end;
    505     if (total_wrote < s->hop_size) {
     544    if (total_wrote < length) {
    506545      uint_t avcodec_read = 0;
    507546      aubio_source_avcodec_readframe(s, &avcodec_read);
     
    515554    }
    516555  }
    517   if (total_wrote < s->hop_size) {
    518     for (j = 0; j < read_data->height; j++) {
    519       for (i = total_wrote; i < s->hop_size; i++) {
    520         read_data->data[j][i] = 0.;
    521       }
    522     }
    523   }
     556
     557  aubio_source_pad_multi_output(read_data, s->input_channels, total_wrote);
     558
    524559  *read = total_wrote;
    525560}
     
    534569
    535570uint_t aubio_source_avcodec_seek (aubio_source_avcodec_t * s, uint_t pos) {
    536   int64_t resampled_pos = (uint_t)ROUND(pos * (s->input_samplerate * 1. / s->samplerate));
     571  int64_t resampled_pos =
     572    (uint_t)ROUND(pos * (s->input_samplerate * 1. / s->samplerate));
    537573  int64_t min_ts = MAX(resampled_pos - 2000, 0);
    538574  int64_t max_ts = MIN(resampled_pos + 2000, INT64_MAX);
     
    542578    ret = AUBIO_OK;
    543579  } else {
    544     AUBIO_ERR("source_avcodec: failed seeking in %s (file not opened?)", s->path);
     580    AUBIO_ERR("source_avcodec: failed seeking in %s (file not opened?)",
     581        s->path);
    545582    return ret;
    546583  }
     
    553590      min_ts, resampled_pos, max_ts, seek_flags);
    554591  if (ret < 0) {
    555     AUBIO_ERR("source_avcodec: failed seeking to %d in file %s", pos, s->path);
     592    AUBIO_ERR("source_avcodec: failed seeking to %d in file %s",
     593        pos, s->path);
    556594  }
    557595  // reset read status
     
    582620#ifdef HAVE_AVRESAMPLE
    583621    avresample_close( s->avr );
     622    av_free ( s->avr );
    584623#elif defined(HAVE_SWRESAMPLE)
    585624    swr_close ( s->avr );
    586 #endif
    587     av_free ( s->avr );
     625    swr_free ( &s->avr );
     626#endif
    588627  }
    589628  s->avr = NULL;
     
    605644
    606645void del_aubio_source_avcodec(aubio_source_avcodec_t * s){
    607   if (!s) return;
     646  AUBIO_ASSERT(s);
    608647  aubio_source_avcodec_close(s);
    609648  if (s->output != NULL) {
  • src/io/source_sndfile.c

    r086a45b rf2f1b10  
    2727#include "fvec.h"
    2828#include "fmat.h"
     29#include "ioutils.h"
    2930#include "source_sndfile.h"
    3031
     
    8788  s->channels = 1;
    8889
    89   if (s->path) AUBIO_FREE(s->path);
    9090  s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
    9191  strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
     
    171171  uint_t i,j, input_channels = s->input_channels;
    172172  /* read from file into scratch_data */
    173   sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data, s->scratch_size);
     173  uint_t length = aubio_source_validate_input_length("source_sndfile", s->path,
     174      s->hop_size, read_data->length);
     175  sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data,
     176      s->scratch_size);
     177  uint_t read_length = read_samples / s->input_channels;
    174178
    175179  /* where to store de-interleaved data */
    176180  smpl_t *ptr_data;
     181
     182  if (!s->handle) {
     183    AUBIO_ERR("source_sndfile: could not read from %s (file was closed)\n",
     184        s->path);
     185    *read = 0;
     186    return;
     187  }
     188
    177189#ifdef HAVE_SAMPLERATE
    178190  if (s->ratio != 1) {
     
    181193#endif /* HAVE_SAMPLERATE */
    182194  {
     195    read_length = MIN(length, read_length);
    183196    ptr_data = read_data->data;
    184197  }
    185198
    186199  /* de-interleaving and down-mixing data  */
    187   for (j = 0; j < read_samples / input_channels; j++) {
     200  for (j = 0; j < read_length; j++) {
    188201    ptr_data[j] = 0;
    189202    for (i = 0; i < input_channels; i++) {
     
    199212#endif /* HAVE_SAMPLERATE */
    200213
    201   *read = (int)FLOOR(s->ratio * read_samples / input_channels + .5);
    202 
    203   if (*read < s->hop_size) {
    204     for (j = *read; j < s->hop_size; j++) {
    205       read_data->data[j] = 0;
    206     }
    207   }
     214  *read = MIN(length, (uint_t)FLOOR(s->ratio * read_length + .5));
     215
     216  aubio_source_pad_output (read_data, *read);
    208217
    209218}
     
    212221  uint_t i,j, input_channels = s->input_channels;
    213222  /* do actual reading */
    214   sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data, s->scratch_size);
     223  uint_t length = aubio_source_validate_input_length("source_sndfile", s->path,
     224      s->hop_size, read_data->length);
     225  uint_t channels = aubio_source_validate_input_channels("source_sndfile",
     226      s->path, s->input_channels, read_data->height);
     227  sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data,
     228      s->scratch_size);
     229  uint_t read_length = read_samples / s->input_channels;
    215230
    216231  /* where to store de-interleaved data */
    217232  smpl_t **ptr_data;
     233
     234  if (!s->handle) {
     235    AUBIO_ERR("source_sndfile: could not read from %s (file was closed)\n",
     236        s->path);
     237    *read = 0;
     238    return;
     239  }
     240
    218241#ifdef HAVE_SAMPLERATE
    219242  if (s->ratio != 1) {
     
    222245#endif /* HAVE_SAMPLERATE */
    223246  {
     247    read_length = MIN(read_length, length);
    224248    ptr_data = read_data->data;
    225249  }
    226250
    227   if (read_data->height < input_channels) {
    228     // destination matrix has less channels than the file; copy only first
    229     // channels of the file, de-interleaving data
    230     for (j = 0; j < read_samples / input_channels; j++) {
    231       for (i = 0; i < read_data->height; i++) {
    232         ptr_data[i][j] = s->scratch_data[j * input_channels + i];
    233       }
    234     }
    235   } else {
    236     // destination matrix has as many or more channels than the file; copy each
    237     // channel from the file to the destination matrix, de-interleaving data
    238     for (j = 0; j < read_samples / input_channels; j++) {
    239       for (i = 0; i < input_channels; i++) {
    240         ptr_data[i][j] = s->scratch_data[j * input_channels + i];
    241       }
    242     }
    243   }
    244 
    245   if (read_data->height > input_channels) {
    246     // destination matrix has more channels than the file; copy last channel
    247     // of the file to each additional channels, de-interleaving data
    248     for (j = 0; j < read_samples / input_channels; j++) {
    249       for (i = input_channels; i < read_data->height; i++) {
    250         ptr_data[i][j] = s->scratch_data[j * input_channels + (input_channels - 1)];
    251       }
     251  for (j = 0; j < read_length; j++) {
     252    for (i = 0; i < channels; i++) {
     253      ptr_data[i][j] = s->scratch_data[j * input_channels + i];
    252254    }
    253255  }
     
    266268#endif /* HAVE_SAMPLERATE */
    267269
    268   *read = (int)FLOOR(s->ratio * read_samples / input_channels + .5);
    269 
    270   if (*read < s->hop_size) {
    271     for (i = 0; i < read_data->height; i++) {
    272       for (j = *read; j < s->hop_size; j++) {
    273         read_data->data[i][j] = 0.;
    274       }
    275     }
    276   }
    277 
     270  *read = MIN(length, (uint_t)FLOOR(s->ratio * read_length + .5));
     271
     272  aubio_source_pad_multi_output(read_data, input_channels, *read);
    278273}
    279274
     
    332327
    333328void del_aubio_source_sndfile(aubio_source_sndfile_t * s){
    334   if (!s) return;
     329  AUBIO_ASSERT(s);
    335330  aubio_source_sndfile_close(s);
    336331#ifdef HAVE_SAMPLERATE
  • src/io/source_wavread.c

    r086a45b rf2f1b10  
    2525#include "fvec.h"
    2626#include "fmat.h"
     27#include "ioutils.h"
    2728#include "source_wavread.h"
    2829
    29 #include <errno.h>
    30 
    3130#define AUBIO_WAVREAD_BUFSIZE 1024
    3231
    33 #define SHORT_TO_FLOAT(x) (smpl_t)(x * 3.0517578125e-05)
     32//#define SHORT_TO_FLOAT(x) (smpl_t)(x * 3.0517578125e-05)
    3433
    3534struct _aubio_source_wavread_t {
     
    9291  }
    9392
    94   if (s->path) AUBIO_FREE(s->path);
    9593  s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
    9694  strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
     
    10199  s->fid = fopen((const char *)path, "rb");
    102100  if (!s->fid) {
    103     AUBIO_ERR("source_wavread: Failed opening %s (System error: %s)\n", s->path, strerror(errno));
     101    AUBIO_STRERR("source_wavread: Failed opening %s (%s)\n", s->path, errorstr);
    104102    goto beach;
    105103  }
     
    134132    bytes_junk += read_little_endian(buf, 4);
    135133    if (fseek(s->fid, bytes_read + bytes_junk, SEEK_SET) != 0) {
    136       AUBIO_ERR("source_wavread: Failed opening %s (could not seek past JUNK Chunk: %s)\n",
    137           s->path, strerror(errno));
     134      AUBIO_STRERR("source_wavread: Failed opening %s (could not seek past JUNK Chunk: %s)\n",
     135          s->path, errorstr);
    138136      goto beach;
    139137    }
     
    190188  bytes_read += fread(buf, 1, 2, s->fid);
    191189  bitspersample = read_little_endian(buf, 2);
     190
     191  if ( channels == 0 ) {
     192    AUBIO_ERR("source_wavread: Failed opening %s (number of channels can not be 0)\n", s->path);
     193    goto beach;
     194  }
     195
     196  if ( (sint_t)sr <= 0 ) {
     197    AUBIO_ERR("source_wavread: Failed opening %s (samplerate can not be <= 0)\n", s->path);
     198    goto beach;
     199  }
     200
     201  if ( byterate == 0 ) {
     202    AUBIO_ERR("source_wavread: Failed opening %s (byterate can not be 0)\n", s->path);
     203    goto beach;
     204  }
     205
     206  if ( bitspersample == 0 ) {
     207    AUBIO_ERR("source_wavread: Failed opening %s (bitspersample can not be 0)\n", s->path);
     208    goto beach;
     209  }
    192210#if 0
    193211  if ( bitspersample != 16 ) {
     
    242260    bytes_junk += read_little_endian(buf, 4);
    243261    if (fseek(s->fid, bytes_read + bytes_junk, SEEK_SET) != 0) {
    244       AUBIO_ERR("source_wavread: could not seek past unknown chunk in %s (%s)\n",
    245           s->path, strerror(errno));
     262      AUBIO_STRERR("source_wavread: could not seek past unknown chunk in %s (%s)\n",
     263          s->path, errorstr);
    246264      goto beach;
    247265    }
     
    329347  uint_t end = 0;
    330348  uint_t total_wrote = 0;
     349  uint_t length = aubio_source_validate_input_length("source_wavread", s->path,
     350      s->hop_size, read_data->length);
    331351  if (s->fid == NULL) {
    332352    AUBIO_ERR("source_wavread: could not read from %s (file not opened)\n",
     
    334354    return;
    335355  }
    336   while (total_wrote < s->hop_size) {
    337     end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
     356  while (total_wrote < length) {
     357    end = MIN(s->read_samples - s->read_index, length - total_wrote);
    338358    for (i = 0; i < end; i++) {
    339359      read_data->data[i + total_wrote] = 0;
     
    344364    }
    345365    total_wrote += end;
    346     if (total_wrote < s->hop_size) {
     366    if (total_wrote < length) {
    347367      uint_t wavread_read = 0;
    348368      aubio_source_wavread_readframe(s, &wavread_read);
     
    356376    }
    357377  }
    358   if (total_wrote < s->hop_size) {
    359     for (i = end; i < s->hop_size; i++) {
    360       read_data->data[i] = 0.;
    361     }
    362   }
     378
     379  aubio_source_pad_output (read_data, total_wrote);
     380
    363381  *read = total_wrote;
    364382}
     
    368386  uint_t end = 0;
    369387  uint_t total_wrote = 0;
     388  uint_t length = aubio_source_validate_input_length("source_wavread", s->path,
     389      s->hop_size, read_data->length);
     390  uint_t channels = aubio_source_validate_input_channels("source_wavread",
     391      s->path, s->input_channels, read_data->height);
    370392  if (s->fid == NULL) {
    371393    AUBIO_ERR("source_wavread: could not read from %s (file not opened)\n",
     
    373395    return;
    374396  }
    375   while (total_wrote < s->hop_size) {
    376     end = MIN(s->read_samples - s->read_index, s->hop_size - total_wrote);
    377     for (j = 0; j < read_data->height; j++) {
     397  while (total_wrote < length) {
     398    end = MIN(s->read_samples - s->read_index, length - total_wrote);
     399    for (j = 0; j < channels; j++) {
    378400      for (i = 0; i < end; i++) {
    379401        read_data->data[j][i + total_wrote] = s->output->data[j][i];
     
    381403    }
    382404    total_wrote += end;
    383     if (total_wrote < s->hop_size) {
     405    if (total_wrote < length) {
    384406      uint_t wavread_read = 0;
    385407      aubio_source_wavread_readframe(s, &wavread_read);
     
    393415    }
    394416  }
    395   if (total_wrote < s->hop_size) {
    396     for (j = 0; j < read_data->height; j++) {
    397       for (i = end; i < s->hop_size; i++) {
    398         read_data->data[j][i] = 0.;
    399       }
    400     }
    401   }
     417
     418  aubio_source_pad_multi_output(read_data, s->input_channels, total_wrote);
     419
    402420  *read = total_wrote;
    403421}
     
    423441  ret = fseek(s->fid, s->seek_start + pos * s->blockalign, SEEK_SET);
    424442  if (ret != 0) {
    425     AUBIO_ERR("source_wavread: could not seek %s at %d (%s)\n", s->path, pos, strerror(errno));
     443    AUBIO_STRERR("source_wavread: could not seek %s at %d (%s)\n", s->path, pos, errorstr);
    426444    return AUBIO_FAIL;
    427445  }
     
    444462  }
    445463  if (fclose(s->fid)) {
    446     AUBIO_ERR("source_wavread: could not close %s (%s)\n", s->path, strerror(errno));
     464    AUBIO_STRERR("source_wavread: could not close %s (%s)\n", s->path, errorstr);
    447465    return AUBIO_FAIL;
    448466  }
     
    452470
    453471void del_aubio_source_wavread(aubio_source_wavread_t * s) {
    454   if (!s) return;
     472  AUBIO_ASSERT(s);
    455473  aubio_source_wavread_close(s);
    456474  if (s->short_output) AUBIO_FREE(s->short_output);
  • src/io/utils_apple_audio.c

    r086a45b rf2f1b10  
    1313char_t *getPrintableOSStatusError(char_t *str, OSStatus error);
    1414
    15 int createAubioBufferList(AudioBufferList * bufferList, int channels, int max_source_samples) {
     15int createAudioBufferList(AudioBufferList * bufferList, int channels,
     16    int max_source_samples) {
    1617  bufferList->mNumberBuffers = 1;
    1718  bufferList->mBuffers[0].mNumberChannels = channels;
    18   bufferList->mBuffers[0].mData = AUBIO_ARRAY(short, max_source_samples);
    19   bufferList->mBuffers[0].mDataByteSize = max_source_samples * sizeof(short);
     19  bufferList->mBuffers[0].mData = AUBIO_ARRAY(smpl_t, max_source_samples);
     20  bufferList->mBuffers[0].mDataByteSize = max_source_samples * sizeof(smpl_t);
    2021  return 0;
    2122}
  • src/mathutils.c

    r086a45b rf2f1b10  
    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++) {
     
    385385  for (j = 0; j < o->length; j++) {
    386386    o->data[j] += val;
     387  }
     388}
     389
     390void
     391fvec_mul (fvec_t *o, smpl_t val)
     392{
     393  uint_t j;
     394  for (j = 0; j < o->length; j++) {
     395    o->data[j] *= val;
    387396  }
    388397}
     
    523532  /* log(freq/A-2)/log(2) */
    524533  midi = freq / 6.875;
    525   midi = LOG (midi) / 0.69314718055995;
     534  midi = LOG (midi) / 0.6931471805599453;
    526535  midi *= 12;
    527536  midi -= 3;
     
    535544  if (midi > 140.) return 0.; // avoid infs
    536545  freq = (midi + 3.) / 12.;
    537   freq = EXP (freq * 0.69314718055995);
     546  freq = EXP (freq * 0.6931471805599453);
    538547  freq *= 6.875;
    539548  return freq;
  • src/mathutils.h

    r086a45b rf2f1b10  
    193193*/
    194194void fvec_add (fvec_t * v, smpl_t c);
     195
     196/** multiply each elements of a vector by a scalar
     197
     198  \param v vector to add constant to
     199  \param s constant to scale v with
     200
     201*/
     202void fvec_mul (fvec_t * v, smpl_t s);
    195203
    196204/** remove the minimum value of the vector to each elements
  • src/musicutils.h

    r086a45b rf2f1b10  
    8787smpl_t aubio_freqtobin (smpl_t freq, smpl_t samplerate, smpl_t fftsize);
    8888
     89/** convert frequency (Hz) to mel
     90
     91  \param freq input frequency, in Hz
     92
     93  \return output mel
     94
     95  Converts a scalar from the frequency domain to the mel scale using Slaney
     96  Auditory Toolbox's implementation:
     97
     98  If \f$ f < 1000 \f$, \f$ m = 3 f / 200 \f$.
     99
     100  If \f$ f >= 1000 \f$, \f$ m = 1000 + 27 \frac{{ln}(f) - ln(1000))}
     101  {{ln}(6400) - ln(1000)}
     102  \f$
     103
     104  See also
     105  --------
     106
     107  aubio_meltohz(), aubio_hztomel_htk().
     108
     109*/
     110smpl_t aubio_hztomel (smpl_t freq);
     111
     112/** convert mel to frequency (Hz)
     113
     114  \param mel input mel
     115
     116  \return output frequency, in Hz
     117
     118  Converts a scalar from the mel scale to the frequency domain using Slaney
     119  Auditory Toolbox's implementation:
     120
     121  If \f$ f < 1000 \f$, \f$ f = 200 m/3 \f$.
     122
     123  If \f$ f \geq 1000 \f$, \f$ f = 1000 + \left(\frac{6400}{1000}\right)
     124  ^{\frac{m - 1000}{27}} \f$
     125
     126  See also
     127  --------
     128
     129  aubio_hztomel(), aubio_meltohz_htk().
     130
     131  References
     132  ----------
     133
     134  Malcolm Slaney, *Auditory Toolbox Version 2, Technical Report #1998-010*
     135  https://engineering.purdue.edu/~malcolm/interval/1998-010/
     136
     137*/
     138smpl_t aubio_meltohz (smpl_t mel);
     139
     140/** convert frequency (Hz) to mel
     141
     142  \param freq input frequency, in Hz
     143
     144  \return output mel
     145
     146  Converts a scalar from the frequency domain to the mel scale, using the
     147  equation defined by O'Shaughnessy, as implemented in the HTK speech
     148  recognition toolkit:
     149
     150  \f$ m = 1127 + ln(1 + \frac{f}{700}) \f$
     151
     152  See also
     153  --------
     154
     155  aubio_meltohz_htk(), aubio_hztomel().
     156
     157  References
     158  ----------
     159
     160  Douglas O'Shaughnessy (1987). *Speech communication: human and machine*.
     161  Addison-Wesley. p. 150. ISBN 978-0-201-16520-3.
     162
     163  HTK Speech Recognition Toolkit: http://htk.eng.cam.ac.uk/
     164
     165 */
     166smpl_t aubio_hztomel_htk (smpl_t freq);
     167
     168/** convert mel to frequency (Hz)
     169
     170  \param mel input mel
     171
     172  \return output frequency, in Hz
     173
     174  Converts a scalar from the mel scale to the frequency domain, using the
     175  equation defined by O'Shaughnessy, as implemented in the HTK speech
     176  recognition toolkit:
     177
     178  \f$ f = 700 * {e}^\left(\frac{f}{1127} - 1\right) \f$
     179
     180  See also
     181  --------
     182
     183  aubio_hztomel_htk(), aubio_meltohz().
     184
     185*/
     186smpl_t aubio_meltohz_htk (smpl_t mel);
     187
    89188/** convert frequency (Hz) to midi value (0-128) */
    90189smpl_t aubio_freqtomidi (smpl_t freq);
  • src/notes/notes.c

    r086a45b rf2f1b10  
    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
     
    8084
    8185  o->onset = new_aubio_onset (onset_method, o->onset_buf_size, o->hop_size, o->samplerate);
     86  if (o->onset == NULL) goto fail;
    8287  if (o->onset_threshold != 0.) aubio_onset_set_threshold (o->onset, o->onset_threshold);
    8388  o->onset_output = new_fvec (1);
    8489
    8590  o->pitch = new_aubio_pitch (pitch_method, o->pitch_buf_size, o->hop_size, o->samplerate);
     91  if (o->pitch == NULL) goto fail;
    8692  if (o->pitch_tolerance != 0.) aubio_pitch_set_tolerance (o->pitch, o->pitch_tolerance);
    8793  aubio_pitch_set_unit (o->pitch, "midi");
     
    95101  o->note_buffer2 = new_fvec(o->median);
    96102
     103  if (!o->onset_output || !o->pitch_output ||
     104      !o->note_buffer || !o->note_buffer2) goto fail;
     105
    97106  o->curnote = -1.;
    98107  o->newnote = 0.;
     
    100109  aubio_notes_set_silence(o, AUBIO_DEFAULT_NOTES_SILENCE);
    101110  aubio_notes_set_minioi_ms (o, AUBIO_DEFAULT_NOTES_MINIOI_MS);
     111
     112  o->last_onset_level = AUBIO_DEFAULT_NOTES_SILENCE;
     113  o->release_drop_level = AUBIO_DEFAULT_NOTES_RELEASE_DROP;
    102114
    103115  return o;
     
    138150{
    139151  return aubio_onset_get_minioi_ms(o->onset);
     152}
     153
     154uint_t aubio_notes_set_release_drop(aubio_notes_t *o, smpl_t release_drop_level)
     155{
     156  uint_t err = AUBIO_OK;
     157  if (release_drop_level <= 0.) {
     158    AUBIO_ERR("notes: release_drop should be >= 0, got %f\n", release_drop_level);
     159    err = AUBIO_FAIL;
     160  } else {
     161    o->release_drop_level = release_drop_level;
     162  }
     163  return err;
     164}
     165
     166smpl_t aubio_notes_get_release_drop(const aubio_notes_t *o)
     167{
     168  return o->release_drop_level;
    140169}
    141170
     
    184213      //notes->data[0] = o->curnote;
    185214      //notes->data[1] = 0.;
     215      //AUBIO_WRN("notes: sending note-off at onset, not enough level\n");
    186216      notes->data[2] = o->curnote;
    187217    } else {
     
    191221        /* kill old note */
    192222        //send_noteon(o->curnote,0, o->samplerate);
     223        //AUBIO_WRN("notes: sending note-off at onset, new onset detected\n");
    193224        notes->data[2] = o->curnote;
    194225        /* get and send new one */
     
    198229        o->curnote = new_pitch;
    199230      }
     231      o->last_onset_level = curlevel;
    200232    }
    201233  } else {
    202     if (o->median) {
     234    if (curlevel < o->last_onset_level - o->release_drop_level)
     235    {
     236      // send note off
     237      //AUBIO_WRN("notes: sending note-off, release detected\n");
     238      notes->data[0] = 0;
     239      notes->data[1] = 0;
     240      notes->data[2] = o->curnote;
     241      // reset last_onset_level to silence_threshold
     242      o->last_onset_level = o->silence_threshold;
     243      o->curnote = 0;
     244    }
     245    else if (o->median)
     246    {
    203247      if (o->isready > 0)
    204248        o->isready++;
     
    207251        /* kill old note */
    208252        //send_noteon(curnote,0);
    209         notes->data[2] = o->curnote;
     253        if (o->curnote != 0)
     254        {
     255          //AUBIO_WRN("notes: sending note-off, new note detected\n");
     256          notes->data[2] = o->curnote;
     257        }
    210258        o->newnote = aubio_notes_get_latest_note(o);
    211259        o->curnote = o->newnote;
  • src/notes/notes.h

    r086a45b rf2f1b10  
    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/onset/onset.c

    r086a45b rf2f1b10  
    257257  o->pp = new_aubio_peakpicker();
    258258  o->od = new_aubio_specdesc(onset_mode,buf_size);
    259   if (o->od == NULL) goto beach_specdesc;
    260259  o->fftgrain = new_cvec(buf_size);
    261260  o->desc = new_fvec(1);
    262261  o->spectral_whitening = new_aubio_spectral_whitening(buf_size, hop_size, samplerate);
    263262
     263  if (!o->pv || !o->pp || !o->od || !o->fftgrain
     264      || !o->desc || !o->spectral_whitening)
     265    goto beach;
     266
    264267  /* initialize internal variables */
    265268  aubio_onset_set_default_parameters (o, onset_mode);
     
    268271  return o;
    269272
    270 beach_specdesc:
    271   del_aubio_peakpicker(o->pp);
    272   del_aubio_pvoc(o->pv);
    273273beach:
    274   AUBIO_FREE(o);
     274  del_aubio_onset(o);
    275275  return NULL;
    276276}
     
    308308    o->apply_compression = 0;
    309309    aubio_onset_set_awhitening (o, 0);
     310  } else if (strcmp (onset_mode, "wphase") == 0) {
     311    // use defaults for now
    310312  } else if (strcmp (onset_mode, "mkl") == 0) {
    311313    aubio_onset_set_threshold (o, 0.05);
     
    338340void del_aubio_onset (aubio_onset_t *o)
    339341{
    340   del_aubio_spectral_whitening(o->spectral_whitening);
    341   del_aubio_specdesc(o->od);
    342   del_aubio_peakpicker(o->pp);
    343   del_aubio_pvoc(o->pv);
    344   del_fvec(o->desc);
    345   del_cvec(o->fftgrain);
     342  if (o->spectral_whitening)
     343    del_aubio_spectral_whitening(o->spectral_whitening);
     344  if (o->od)
     345    del_aubio_specdesc(o->od);
     346  if (o->pp)
     347    del_aubio_peakpicker(o->pp);
     348  if (o->pv)
     349    del_aubio_pvoc(o->pv);
     350  if (o->desc)
     351    del_fvec(o->desc);
     352  if (o->fftgrain)
     353    del_cvec(o->fftgrain);
    346354  AUBIO_FREE(o);
    347355}
  • src/pitch/pitchmcomb.c

    r086a45b rf2f1b10  
    3838 * sort_pitchpeak(peaks, length);
    3939 */
     40#if 0
    4041/** spectral_peak comparison function (must return signed int) */
    4142static sint_t aubio_pitchmcomb_sort_peak_comp (const void *x, const void *y);
     
    4546uint_t aubio_pitch_cands (aubio_pitchmcomb_t * p, const cvec_t * fftgrain,
    4647    smpl_t * cands);
     48#endif
    4749
    4850/** sort spectral_candidate against their comb ene */
    4951void aubio_pitchmcomb_sort_cand_ene (aubio_spectralcandidate_t ** candidates,
    5052    uint_t nbins);
     53#if 0
    5154/** sort spectral_candidate against their frequency */
    5255void aubio_pitchmcomb_sort_cand_freq (aubio_spectralcandidate_t ** candidates,
    5356    uint_t nbins);
     57#endif
    5458
    5559struct _aubio_pitchmcomb_t
     
    134138}
    135139
     140#if 0
    136141uint_t
    137142aubio_pitch_cands (aubio_pitchmcomb_t * p, const cvec_t * fftgrain, smpl_t * cands)
     
    164169  }
    165170}
     171#endif
    166172
    167173void
     
    314320}
    315321
     322#if 0
    316323void
    317324aubio_pitchmcomb_sort_peak (aubio_spectralpeak_t * peaks, uint_t nbins)
     
    343350}
    344351
    345 
    346352void
    347353aubio_pitchmcomb_sort_cand_freq (aubio_spectralcandidate_t ** candidates,
     
    357363  }
    358364}
     365#endif
    359366
    360367aubio_pitchmcomb_t *
  • src/pitch/pitchspecacf.c

    r086a45b rf2f1b10  
    9393  del_fvec (p->sqrmag);
    9494  del_fvec (p->fftout);
     95  del_fvec (p->acf);
    9596  AUBIO_FREE (p);
    9697}
  • src/pitch/pitchyin.c

    r086a45b rf2f1b10  
    4040};
    4141
     42#if 0
    4243/** compute difference function
    4344
     
    6162*/
    6263uint_t aubio_pitchyin_getpitch (const fvec_t * yinbuf);
     64#endif
    6365
    6466aubio_pitchyin_t *
     
    7981}
    8082
     83#if 0
    8184/* outputs the difference function */
    8285void
     
    128131  return 0;
    129132}
     133#endif
    130134
    131135/* all the above in one */
  • src/pitch/pitchyinfast.c

    r086a45b rf2f1b10  
    5959  o->kernel_fft = new_fvec (bufsize);
    6060  o->fft = new_aubio_fft (bufsize);
     61  if (!o->yin || !o->tmpdata || !o->tmpdata || !o->sqdiff
     62      || !o->kernel || !o->samples_fft || !o->kernel || !o->fft)
     63  {
     64    del_aubio_pitchyinfast(o);
     65    return NULL;
     66  }
    6167  o->tol = 0.15;
    6268  o->peak_pos = 0;
     
    6773del_aubio_pitchyinfast (aubio_pitchyinfast_t * o)
    6874{
    69   del_fvec (o->yin);
    70   del_fvec (o->tmpdata);
    71   del_fvec (o->sqdiff);
    72   del_fvec (o->kernel);
    73   del_fvec (o->samples_fft);
    74   del_fvec (o->kernel_fft);
    75   del_aubio_fft (o->fft);
     75  if (o->yin)
     76    del_fvec (o->yin);
     77  if (o->tmpdata)
     78    del_fvec (o->tmpdata);
     79  if (o->sqdiff)
     80    del_fvec (o->sqdiff);
     81  if (o->kernel)
     82    del_fvec (o->kernel);
     83  if (o->samples_fft)
     84    del_fvec (o->samples_fft);
     85  if (o->kernel_fft)
     86    del_fvec (o->kernel_fft);
     87  if (o->fft)
     88    del_aubio_fft (o->fft);
    7689  AUBIO_FREE (o);
    7790}
  • src/pitch/pitchyinfft.c

    r086a45b rf2f1b10  
    4545   160.,   200.,   250.,   315.,   400.,   500.,   630.,   800.,  1000.,  1250.,
    4646  1600.,  2000.,  2500.,  3150.,  4000.,  5000.,  6300.,  8000.,  9000., 10000.,
    47  12500., 15000., 20000., 25100
     47 12500., 15000., 20000., 25100., -1.
    4848};
    4949
     
    7373  for (i = 0; i < p->weight->length; i++) {
    7474    freq = (smpl_t) i / (smpl_t) bufsize *(smpl_t) samplerate;
    75     while (freq > freqs[j]) {
     75    while (freq > freqs[j] && freqs[j] > 0) {
     76      //AUBIO_DBG("freq %3.5f > %3.5f \tsamplerate %d (Hz) \t"
     77      //    "(weight length %d, bufsize %d) %d %d\n", freq, freqs[j],
     78      //    samplerate, p->weight->length, bufsize, i, j);
    7679      j += 1;
    7780    }
  • src/spectral/awhitening.c

    r086a45b rf2f1b10  
    4444{
    4545  uint_t i = 0;
    46   for (i = 0; i < o->peak_values->length; i++) {
     46  uint_t length = MIN(fftgrain->length, o->peak_values->length);
     47  for (i = 0; i < length; i++) {
    4748    smpl_t tmp = MAX(o->r_decay * o->peak_values->data[i], o->floor);
    4849    o->peak_values->data[i] = MAX(fftgrain->norm[i], tmp);
  • src/spectral/fft.c

    r086a45b rf2f1b10  
    9090#define aubio_vDSP_vsadd               vDSP_vsadd
    9191#define aubio_vDSP_vsmul               vDSP_vsmul
    92 #define aubio_vDSP_create_fftsetup     vDSP_create_fftsetup
    93 #define aubio_vDSP_destroy_fftsetup    vDSP_destroy_fftsetup
    9492#define aubio_DSPComplex               DSPComplex
    9593#define aubio_DSPSplitComplex          DSPSplitComplex
    96 #define aubio_FFTSetup                 FFTSetup
     94#define aubio_vDSP_DFT_Setup           vDSP_DFT_Setup
     95#define aubio_vDSP_DFT_zrop_CreateSetup vDSP_DFT_zrop_CreateSetup
     96#define aubio_vDSP_DFT_Execute         vDSP_DFT_Execute
     97#define aubio_vDSP_DFT_DestroySetup    vDSP_DFT_DestroySetup
    9798#define aubio_vvsqrt                   vvsqrtf
    9899#else
     
    104105#define aubio_vDSP_vsadd               vDSP_vsaddD
    105106#define aubio_vDSP_vsmul               vDSP_vsmulD
    106 #define aubio_vDSP_create_fftsetup     vDSP_create_fftsetupD
    107 #define aubio_vDSP_destroy_fftsetup    vDSP_destroy_fftsetupD
    108107#define aubio_DSPComplex               DSPDoubleComplex
    109108#define aubio_DSPSplitComplex          DSPDoubleSplitComplex
    110 #define aubio_FFTSetup                 FFTSetupD
     109#define aubio_vDSP_DFT_Setup           vDSP_DFT_SetupD
     110#define aubio_vDSP_DFT_zrop_CreateSetup vDSP_DFT_zrop_CreateSetupD
     111#define aubio_vDSP_DFT_Execute         vDSP_DFT_ExecuteD
     112#define aubio_vDSP_DFT_DestroySetup    vDSP_DFT_DestroySetupD
    111113#define aubio_vvsqrt                   vvsqrt
    112114#endif /* HAVE_AUBIO_DOUBLE */
     
    153155
    154156#elif defined HAVE_ACCELERATE  // using ACCELERATE
    155   int log2fftsize;
    156   aubio_FFTSetup fftSetup;
     157  aubio_vDSP_DFT_Setup fftSetupFwd;
     158  aubio_vDSP_DFT_Setup fftSetupBwd;
    157159  aubio_DSPSplitComplex spec;
    158160  smpl_t *in, *out;
     
    211213
    212214#elif defined HAVE_ACCELERATE  // using ACCELERATE
     215  {
     216    uint_t radix = winsize;
     217    uint_t order = 0;
     218    while ((radix / 2) * 2 == radix) {
     219      radix /= 2;
     220      order++;
     221    }
     222    if (order < 4 || (radix != 1 && radix != 3 && radix != 5 && radix != 15)) {
     223      AUBIO_ERR("fft: vDSP/Accelerate supports FFT with sizes = "
     224          "f * 2 ** n, where n > 4 and f in [1, 3, 5, 15], but requested %d. "
     225          "Use the closest power of two, or try recompiling aubio with "
     226          "--enable-fftw3.\n", winsize);
     227      goto beach;
     228    }
     229  }
    213230  s->winsize = winsize;
    214231  s->fft_size = winsize;
    215232  s->compspec = new_fvec(winsize);
    216   s->log2fftsize = aubio_power_of_two_order(s->fft_size);
    217233  s->in = AUBIO_ARRAY(smpl_t, s->fft_size);
    218234  s->out = AUBIO_ARRAY(smpl_t, s->fft_size);
    219235  s->spec.realp = AUBIO_ARRAY(smpl_t, s->fft_size/2);
    220236  s->spec.imagp = AUBIO_ARRAY(smpl_t, s->fft_size/2);
    221   s->fftSetup = aubio_vDSP_create_fftsetup(s->log2fftsize, FFT_RADIX2);
     237  s->fftSetupFwd = aubio_vDSP_DFT_zrop_CreateSetup(NULL,
     238      s->fft_size, vDSP_DFT_FORWARD);
     239  s->fftSetupBwd = aubio_vDSP_DFT_zrop_CreateSetup(s->fftSetupFwd,
     240      s->fft_size, vDSP_DFT_INVERSE);
    222241
    223242#elif defined HAVE_INTEL_IPP  // using Intel IPP
     
    293312  AUBIO_FREE(s->spec.realp);
    294313  AUBIO_FREE(s->spec.imagp);
    295   aubio_vDSP_destroy_fftsetup(s->fftSetup);
     314  aubio_vDSP_DFT_DestroySetup(s->fftSetupBwd);
     315  aubio_vDSP_DFT_DestroySetup(s->fftSetupFwd);
    296316
    297317#elif defined HAVE_INTEL_IPP  // using Intel IPP
     
    351371  aubio_vDSP_ctoz((aubio_DSPComplex*)s->in, 2, &s->spec, 1, s->fft_size/2);
    352372  // compute the FFT
    353   aubio_vDSP_fft_zrip(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_FORWARD);
     373  aubio_vDSP_DFT_Execute(s->fftSetupFwd, s->spec.realp, s->spec.imagp,
     374      s->spec.realp, s->spec.imagp);
    354375  // convert from vDSP complex split to [ r0, r1, ..., rN, iN-1, .., i2, i1]
    355376  compspec->data[0] = s->spec.realp[0];
     
    419440  aubio_vDSP_ctoz((aubio_DSPComplex*)s->out, 2, &s->spec, 1, s->fft_size/2);
    420441  // compute the FFT
    421   aubio_vDSP_fft_zrip(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_INVERSE);
     442  aubio_vDSP_DFT_Execute(s->fftSetupBwd, s->spec.realp, s->spec.imagp,
     443      s->spec.realp, s->spec.imagp);
    422444  // convert result to real output
    423445  aubio_vDSP_ztoc(&s->spec, 1, (aubio_DSPComplex*)output->data, 2, s->fft_size/2);
     
    494516  }
    495517#endif
    496   if (compspec->data[compspec->length/2] < 0) {
    497     spectrum->phas[spectrum->length - 1] = PI;
     518#ifdef HAVE_FFTW3
     519  // for even length only, make sure last element is 0 or PI
     520  if (2 * (compspec->length / 2) == compspec->length) {
     521#endif
     522    if (compspec->data[compspec->length/2] < 0) {
     523      spectrum->phas[spectrum->length - 1] = PI;
     524    } else {
     525      spectrum->phas[spectrum->length - 1] = 0.;
     526    }
     527#ifdef HAVE_FFTW3
    498528  } else {
    499     spectrum->phas[spectrum->length - 1] = 0.;
    500   }
     529    i = spectrum->length - 1;
     530    spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i],
     531        compspec->data[i]);
     532  }
     533#endif
    501534}
    502535
     
    508541        + SQR(compspec->data[compspec->length - i]) );
    509542  }
    510   spectrum->norm[spectrum->length-1] =
    511     ABS(compspec->data[compspec->length/2]);
     543#ifdef HAVE_FFTW3
     544  // for even length, make sure last element is > 0
     545  if (2 * (compspec->length / 2) == compspec->length) {
     546#endif
     547    spectrum->norm[spectrum->length-1] =
     548      ABS(compspec->data[compspec->length/2]);
     549#ifdef HAVE_FFTW3
     550  } else {
     551    i = spectrum->length - 1;
     552    spectrum->norm[i] = SQRT(SQR(compspec->data[i])
     553        + SQR(compspec->data[compspec->length - i]) );
     554  }
     555#endif
    512556}
    513557
  • src/spectral/filterbank.c

    r086a45b rf2f1b10  
    2424#include "fmat.h"
    2525#include "cvec.h"
     26#include "vecutils.h"
    2627#include "spectral/filterbank.h"
    2728#include "mathutils.h"
     
    3334  uint_t n_filters;
    3435  fmat_t *filters;
     36  smpl_t norm;
     37  smpl_t power;
    3538};
    3639
     
    4043  /* allocate space for filterbank object */
    4144  aubio_filterbank_t *fb = AUBIO_NEW (aubio_filterbank_t);
     45
     46  if ((sint_t)n_filters <= 0) {
     47    AUBIO_ERR("filterbank: n_filters should be > 0, got %d\n", n_filters);
     48    goto fail;
     49  }
     50  if ((sint_t)win_s <= 0) {
     51    AUBIO_ERR("filterbank: win_s should be > 0, got %d\n", win_s);
     52    goto fail;
     53  }
    4254  fb->win_s = win_s;
    4355  fb->n_filters = n_filters;
     
    4658  fb->filters = new_fmat (n_filters, win_s / 2 + 1);
    4759
     60  fb->norm = 1;
     61
     62  fb->power = 1;
     63
    4864  return fb;
     65fail:
     66  AUBIO_FREE (fb);
     67  return NULL;
    4968}
    5069
     
    6887  tmp.data = in->norm;
    6988
     89  if (f->power != 1.) fvec_pow(&tmp, f->power);
     90
    7091  fmat_vecmul(f->filters, &tmp, out);
    7192
     
    85106  return 0;
    86107}
     108
     109uint_t
     110aubio_filterbank_set_norm (aubio_filterbank_t *f, smpl_t norm)
     111{
     112  if (norm != 0 && norm != 1) return AUBIO_FAIL;
     113  f->norm = norm;
     114  return AUBIO_OK;
     115}
     116
     117smpl_t
     118aubio_filterbank_get_norm (aubio_filterbank_t *f)
     119{
     120  return f->norm;
     121}
     122
     123uint_t
     124aubio_filterbank_set_power (aubio_filterbank_t *f, smpl_t power)
     125{
     126  f->power = power;
     127  return AUBIO_OK;
     128}
     129
     130smpl_t
     131aubio_filterbank_get_power (aubio_filterbank_t *f)
     132{
     133  return f->power;
     134}
  • src/spectral/filterbank.h

    r086a45b rf2f1b10  
    8484uint_t aubio_filterbank_set_coeffs (aubio_filterbank_t * f, const fmat_t * filters);
    8585
     86/** set norm parameter
     87
     88  \param f filterbank object, as returned by new_aubio_filterbank()
     89  \param norm `1` to norm the filters, `0` otherwise.
     90
     91  If set to `0`, the filters will not be normalized. If set to `1`,
     92  each filter will be normalized to one. Defaults to `1`.
     93
     94  This function should be called *before* setting the filters with one of
     95  aubio_filterbank_set_triangle_bands(), aubio_filterbank_set_mel_coeffs(),
     96  aubio_filterbank_set_mel_coeffs_htk(), or
     97  aubio_filterbank_set_mel_coeffs_slaney().
     98
     99 */
     100uint_t aubio_filterbank_set_norm (aubio_filterbank_t *f, smpl_t norm);
     101
     102/** get norm parameter
     103
     104  \param f filterbank object, as returned by new_aubio_filterbank()
     105  \returns `1` if norm is set, `0` otherwise. Defaults to `1`.
     106
     107 */
     108smpl_t aubio_filterbank_get_norm (aubio_filterbank_t *f);
     109
     110/** set power parameter
     111
     112  \param f filterbank object, as returned by new_aubio_filterbank()
     113  \param power Raise norm of the input spectrum norm to this power before
     114  computing filterbank.  Defaults to `1`.
     115
     116 */
     117uint_t aubio_filterbank_set_power (aubio_filterbank_t *f, smpl_t power);
     118
     119/** get power parameter
     120
     121  \param f filterbank object, as returned by new_aubio_filterbank()
     122  \return current power parameter. Defaults to `1`.
     123
     124 */
     125smpl_t aubio_filterbank_get_power (aubio_filterbank_t *f);
     126
    86127#ifdef __cplusplus
    87128}
  • src/spectral/filterbank_mel.c

    r086a45b rf2f1b10  
    5555  }
    5656
    57   if (freqs->data[freqs->length - 1] > samplerate / 2) {
    58     AUBIO_WRN ("Nyquist frequency is %fHz, but highest frequency band ends at \
    59 %fHz\n", samplerate / 2, freqs->data[freqs->length - 1]);
     57  for (fn = 0; fn < freqs->length; fn++) {
     58    if (freqs->data[fn] < 0) {
     59      AUBIO_ERR("filterbank_mel: freqs must contain only positive values.\n");
     60      return AUBIO_FAIL;
     61    } else if (freqs->data[fn] > samplerate / 2) {
     62      AUBIO_WRN("filterbank_mel: freqs should contain only "
     63          "values < samplerate / 2.\n");
     64    } else if (fn > 0 && freqs->data[fn] < freqs->data[fn-1]) {
     65      AUBIO_ERR("filterbank_mel: freqs should be a list of frequencies "
     66          "sorted from low to high, but freq[%d] < freq[%d-1]\n", fn, fn);
     67      return AUBIO_FAIL;
     68    } else if (fn > 0 && freqs->data[fn] == freqs->data[fn-1]) {
     69      AUBIO_WRN("filterbank_mel: set_triangle_bands received a list "
     70          "with twice the frequency %f\n", freqs->data[fn]);
     71    }
    6072  }
    6173
     
    7991
    8092  /* compute triangle heights so that each triangle has unit area */
    81   for (fn = 0; fn < n_filters; fn++) {
    82     triangle_heights->data[fn] =
    83         2. / (upper_freqs->data[fn] - lower_freqs->data[fn]);
     93  if (aubio_filterbank_get_norm(fb)) {
     94    for (fn = 0; fn < n_filters; fn++) {
     95      triangle_heights->data[fn] =
     96          2. / (upper_freqs->data[fn] - lower_freqs->data[fn]);
     97    }
     98  } else {
     99    fvec_ones (triangle_heights);
    84100  }
    85101
     
    92108  /* zeroing of all filters */
    93109  fmat_zeros (filters);
    94 
    95   if (fft_freqs->data[1] >= lower_freqs->data[0]) {
    96     /* - 1 to make sure we don't miss the smallest power of two */
    97     uint_t min_win_s =
    98         (uint_t) FLOOR (samplerate / lower_freqs->data[0]) - 1;
    99     AUBIO_WRN ("Lowest frequency bin (%.2fHz) is higher than lowest frequency \
    100 band (%.2f-%.2fHz). Consider increasing the window size from %d to %d.\n",
    101         fft_freqs->data[1], lower_freqs->data[0],
    102         upper_freqs->data[0], (win_s - 1) * 2,
    103         aubio_next_power_of_two (min_win_s));
    104   }
    105110
    106111  /* building each filter table */
     
    117122
    118123    /* compute positive slope step size */
    119     riseInc =
    120         triangle_heights->data[fn] /
    121         (center_freqs->data[fn] - lower_freqs->data[fn]);
     124    riseInc = triangle_heights->data[fn]
     125      / (center_freqs->data[fn] - lower_freqs->data[fn]);
    122126
    123127    /* compute coefficients in positive slope */
     
    133137
    134138    /* compute negative slope step size */
    135     downInc =
    136         triangle_heights->data[fn] /
    137         (upper_freqs->data[fn] - center_freqs->data[fn]);
     139    downInc = triangle_heights->data[fn]
     140      / (upper_freqs->data[fn] - center_freqs->data[fn]);
    138141
    139142    /* compute coefficents in negative slope */
     
    161164  del_fvec (fft_freqs);
    162165
    163   return 0;
     166  return AUBIO_OK;
    164167}
    165168
     
    168171    smpl_t samplerate)
    169172{
    170   uint_t retval;
    171 
    172173  /* Malcolm Slaney parameters */
    173   smpl_t lowestFrequency = 133.3333;
    174   smpl_t linearSpacing = 66.66666666;
    175   smpl_t logSpacing = 1.0711703;
    176 
    177   uint_t linearFilters = 13;
    178   uint_t logFilters = 27;
    179   uint_t n_filters = linearFilters + logFilters;
    180 
    181   uint_t fn;                    /* filter counter */
    182 
     174  const smpl_t lowestFrequency = 133.3333;
     175  const smpl_t linearSpacing = 66.66666666;
     176  const smpl_t logSpacing = 1.0711703;
     177
     178  const uint_t linearFilters = 13;
     179  const uint_t logFilters = 27;
     180  const uint_t n_filters = linearFilters + logFilters;
     181
     182  uint_t fn, retval;
    183183  smpl_t lastlinearCF;
    184184
    185185  /* buffers to compute filter frequencies */
    186   fvec_t *freqs = new_fvec (n_filters + 2);
     186  fvec_t *freqs;
     187
     188  if (samplerate <= 0) {
     189    AUBIO_ERR("filterbank: set_mel_coeffs_slaney samplerate should be > 0\n");
     190    return AUBIO_FAIL;
     191  }
     192
     193  freqs = new_fvec (n_filters + 2);
    187194
    188195  /* first step: fill all the linear filter frequencies */
     
    206213  return retval;
    207214}
     215
     216static uint_t aubio_filterbank_check_freqs (aubio_filterbank_t *fb UNUSED,
     217    smpl_t samplerate, smpl_t *freq_min, smpl_t *freq_max)
     218{
     219  if (samplerate <= 0) {
     220    AUBIO_ERR("filterbank: set_mel_coeffs samplerate should be > 0\n");
     221    return AUBIO_FAIL;
     222  }
     223  if (*freq_max < 0) {
     224    AUBIO_ERR("filterbank: set_mel_coeffs freq_max should be > 0\n");
     225    return AUBIO_FAIL;
     226  } else if (*freq_max == 0) {
     227    *freq_max = samplerate / 2.;
     228  }
     229  if (*freq_min < 0) {
     230    AUBIO_ERR("filterbank: set_mel_coeffs freq_min should be > 0\n");
     231    return AUBIO_FAIL;
     232  }
     233  return AUBIO_OK;
     234}
     235
     236uint_t
     237aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, smpl_t samplerate,
     238    smpl_t freq_min, smpl_t freq_max)
     239{
     240  uint_t m, retval;
     241  smpl_t start = freq_min, end = freq_max, step;
     242  fvec_t *freqs;
     243  fmat_t *coeffs = aubio_filterbank_get_coeffs(fb);
     244  uint_t n_bands = coeffs->height;
     245
     246  if (aubio_filterbank_check_freqs(fb, samplerate, &start, &end)) {
     247    return AUBIO_FAIL;
     248  }
     249
     250  start = aubio_hztomel(start);
     251  end = aubio_hztomel(end);
     252
     253  freqs = new_fvec(n_bands + 2);
     254  step = (end - start) / (n_bands + 1);
     255
     256  for (m = 0; m < n_bands + 2; m++)
     257  {
     258    freqs->data[m] = MIN(aubio_meltohz(start + step * m), samplerate/2.);
     259  }
     260
     261  retval = aubio_filterbank_set_triangle_bands (fb, freqs, samplerate);
     262
     263  /* destroy vector used to store frequency limits */
     264  del_fvec (freqs);
     265  return retval;
     266}
     267
     268uint_t
     269aubio_filterbank_set_mel_coeffs_htk (aubio_filterbank_t * fb, smpl_t samplerate,
     270    smpl_t freq_min, smpl_t freq_max)
     271{
     272  uint_t m, retval;
     273  smpl_t start = freq_min, end = freq_max, step;
     274  fvec_t *freqs;
     275  fmat_t *coeffs = aubio_filterbank_get_coeffs(fb);
     276  uint_t n_bands = coeffs->height;
     277
     278  if (aubio_filterbank_check_freqs(fb, samplerate, &start, &end)) {
     279    return AUBIO_FAIL;
     280  }
     281
     282  start = aubio_hztomel_htk(start);
     283  end = aubio_hztomel_htk(end);
     284
     285  freqs = new_fvec (n_bands + 2);
     286  step = (end - start) / (n_bands + 1);
     287
     288  for (m = 0; m < n_bands + 2; m++)
     289  {
     290    freqs->data[m] = MIN(aubio_meltohz_htk(start + step * m), samplerate/2.);
     291  }
     292
     293  retval = aubio_filterbank_set_triangle_bands (fb, freqs, samplerate);
     294
     295  /* destroy vector used to store frequency limits */
     296  del_fvec (freqs);
     297  return retval;
     298}
  • src/spectral/filterbank_mel.h

    r086a45b rf2f1b10  
    5656
    5757  \param fb filterbank object
    58   \param samplerate audio sampling rate
     58  \param samplerate audio sampling rate, in Hz
    5959
    60   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).
     60  The filter coefficients are built to match exactly Malcolm Slaney's Auditory
     61  Toolbox implementation (see file mfcc.m). The number of filters should be 40.
     62
     63  References
     64  ----------
     65
     66  Malcolm Slaney, *Auditory Toolbox Version 2, Technical Report #1998-010*
     67  https://engineering.purdue.edu/~malcolm/interval/1998-010/
    6368
    6469*/
    6570uint_t aubio_filterbank_set_mel_coeffs_slaney (aubio_filterbank_t * fb,
    6671    smpl_t samplerate);
     72
     73/** Mel filterbank initialization
     74
     75  \param fb filterbank object
     76  \param samplerate audio sampling rate
     77  \param fmin start frequency, in Hz
     78  \param fmax end frequency, in Hz
     79
     80  The filterbank will be initialized with bands linearly spaced in the mel
     81  scale, from `fmin` to `fmax`.
     82
     83  References
     84  ----------
     85
     86  Malcolm Slaney, *Auditory Toolbox Version 2, Technical Report #1998-010*
     87  https://engineering.purdue.edu/~malcolm/interval/1998-010/
     88
     89*/
     90uint_t aubio_filterbank_set_mel_coeffs(aubio_filterbank_t * fb,
     91    smpl_t samplerate, smpl_t fmin, smpl_t fmax);
     92
     93/** Mel filterbank initialization
     94
     95  \param fb filterbank object
     96  \param samplerate audio sampling rate
     97  \param fmin start frequency, in Hz
     98  \param fmax end frequency, in Hz
     99
     100  The bank of filters will be initalized to to cover linearly spaced bands in
     101  the Htk mel scale, from `fmin` to `fmax`.
     102
     103  References
     104  ----------
     105
     106  Douglas O'Shaughnessy (1987). *Speech communication: human and machine*.
     107  Addison-Wesley. p. 150. ISBN 978-0-201-16520-3.
     108
     109  HTK Speech Recognition Toolkit: http://htk.eng.cam.ac.uk/
     110
     111*/
     112uint_t aubio_filterbank_set_mel_coeffs_htk(aubio_filterbank_t * fb,
     113    smpl_t samplerate, smpl_t fmin, smpl_t fmax);
    67114
    68115#ifdef __cplusplus
  • src/spectral/mfcc.c

    r086a45b rf2f1b10  
    2929#include "spectral/filterbank.h"
    3030#include "spectral/filterbank_mel.h"
     31#include "spectral/dct.h"
    3132#include "spectral/mfcc.h"
    3233
     
    4142  aubio_filterbank_t *fb;   /** filter bank */
    4243  fvec_t *in_dct;           /** input buffer for dct * [fb->n_filters] */
    43   fmat_t *dct_coeffs;       /** DCT transform n_filters * n_coeffs */
     44  aubio_dct_t *dct;         /** dct object */
     45  fvec_t *output;           /** dct output */
     46  smpl_t scale;
    4447};
    4548
     
    5255  /* allocate space for mfcc object */
    5356  aubio_mfcc_t *mfcc = AUBIO_NEW (aubio_mfcc_t);
    54   smpl_t scaling;
    5557
    56   uint_t i, j;
     58  if ((sint_t)n_coefs <= 0) {
     59    AUBIO_ERR("mfcc: n_coefs should be > 0, got %d\n", n_coefs);
     60    goto failure;
     61  }
     62  if ((sint_t)samplerate <= 0) {
     63    AUBIO_ERR("mfcc: samplerate should be > 0, got %d\n", samplerate);
     64    goto failure;
     65  }
    5766
    5867  mfcc->win_s = win_s;
     
    6372  /* filterbank allocation */
    6473  mfcc->fb = new_aubio_filterbank (n_filters, mfcc->win_s);
    65   aubio_filterbank_set_mel_coeffs_slaney (mfcc->fb, samplerate);
     74
     75  if (!mfcc->fb)
     76    goto failure;
     77
     78  if (n_filters == 40)
     79    aubio_filterbank_set_mel_coeffs_slaney (mfcc->fb, samplerate);
     80  else
     81    aubio_filterbank_set_mel_coeffs(mfcc->fb, samplerate,
     82        0, samplerate/2.);
    6683
    6784  /* allocating buffers */
    6885  mfcc->in_dct = new_fvec (n_filters);
    6986
    70   mfcc->dct_coeffs = new_fmat (n_coefs, n_filters);
     87  mfcc->dct = new_aubio_dct (n_filters);
     88  mfcc->output = new_fvec (n_filters);
    7189
    72   /* compute DCT transform dct_coeffs[j][i] as
    73      cos ( j * (i+.5) * PI / n_filters ) */
    74   scaling = 1. / SQRT (n_filters / 2.);
    75   for (i = 0; i < n_filters; i++) {
    76     for (j = 0; j < n_coefs; j++) {
    77       mfcc->dct_coeffs->data[j][i] =
    78           scaling * COS (j * (i + 0.5) * PI / n_filters);
    79     }
    80     mfcc->dct_coeffs->data[0][i] *= SQRT (2.) / 2.;
    81   }
     90  if (!mfcc->in_dct || !mfcc->dct || !mfcc->output)
     91    goto failure;
     92
     93  mfcc->scale = 1.;
    8294
    8395  return mfcc;
     96
     97failure:
     98  del_aubio_mfcc(mfcc);
     99  return NULL;
    84100}
    85101
     
    87103del_aubio_mfcc (aubio_mfcc_t * mf)
    88104{
    89 
    90   /* delete filterbank */
    91   del_aubio_filterbank (mf->fb);
    92 
    93   /* delete buffers */
    94   del_fvec (mf->in_dct);
    95   del_fmat (mf->dct_coeffs);
    96 
    97   /* delete mfcc object */
     105  if (mf->fb)
     106    del_aubio_filterbank (mf->fb);
     107  if (mf->in_dct)
     108    del_fvec (mf->in_dct);
     109  if (mf->dct)
     110    del_aubio_dct (mf->dct);
     111  if (mf->output)
     112    del_fvec (mf->output);
    98113  AUBIO_FREE (mf);
    99114}
     
    103118aubio_mfcc_do (aubio_mfcc_t * mf, const cvec_t * in, fvec_t * out)
    104119{
     120  fvec_t tmp;
     121
    105122  /* compute filterbank */
    106123  aubio_filterbank_do (mf->fb, in, mf->in_dct);
     
    109126  fvec_log10 (mf->in_dct);
    110127
    111   /* raise power */
    112   //fvec_pow (mf->in_dct, 3.);
     128  if (mf->scale != 1) fvec_mul (mf->in_dct, mf->scale);
    113129
    114130  /* compute mfccs */
    115   fmat_vecmul(mf->dct_coeffs, mf->in_dct, out);
     131  aubio_dct_do(mf->dct, mf->in_dct, mf->output);
     132  // copy only first n_coeffs elements
     133  // TODO assert mf->output->length == n_coeffs
     134  tmp.data = mf->output->data;
     135  tmp.length = out->length;
     136  fvec_copy(&tmp, out);
    116137
    117138  return;
    118139}
     140
     141uint_t aubio_mfcc_set_power (aubio_mfcc_t *mf, smpl_t power)
     142{
     143  return aubio_filterbank_set_power(mf->fb, power);
     144}
     145
     146smpl_t aubio_mfcc_get_power (aubio_mfcc_t *mf)
     147{
     148  return aubio_filterbank_get_power(mf->fb);
     149}
     150
     151uint_t aubio_mfcc_set_scale (aubio_mfcc_t *mf, smpl_t scale)
     152{
     153  mf->scale = scale;
     154  return AUBIO_OK;
     155}
     156
     157smpl_t aubio_mfcc_get_scale (aubio_mfcc_t *mf)
     158{
     159  return mf->scale;
     160}
     161
     162uint_t aubio_mfcc_set_mel_coeffs (aubio_mfcc_t *mf, smpl_t freq_min,
     163    smpl_t freq_max)
     164{
     165  return aubio_filterbank_set_mel_coeffs(mf->fb, mf->samplerate,
     166      freq_min, freq_max);
     167}
     168
     169uint_t aubio_mfcc_set_mel_coeffs_htk (aubio_mfcc_t *mf, smpl_t freq_min,
     170    smpl_t freq_max)
     171{
     172  return aubio_filterbank_set_mel_coeffs_htk(mf->fb, mf->samplerate,
     173      freq_min, freq_max);
     174}
     175
     176uint_t aubio_mfcc_set_mel_coeffs_slaney (aubio_mfcc_t *mf)
     177{
     178  return aubio_filterbank_set_mel_coeffs_slaney (mf->fb, mf->samplerate);
     179}
  • src/spectral/mfcc.h

    r086a45b rf2f1b10  
    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
     
    7374void aubio_mfcc_do (aubio_mfcc_t * mf, const cvec_t * in, fvec_t * out);
    7475
     76/** set power parameter
     77
     78  \param mf mfcc object, as returned by new_aubio_mfcc()
     79  \param power Raise norm of the input spectrum norm to this power before
     80  computing filterbank.  Defaults to `1`.
     81
     82  See aubio_filterbank_set_power().
     83
     84 */
     85uint_t aubio_mfcc_set_power (aubio_mfcc_t *mf, smpl_t power);
     86
     87/** get power parameter
     88
     89  \param mf mfcc object, as returned by new_aubio_mfcc()
     90  \return current power parameter. Defaults to `1`.
     91
     92  See aubio_filterbank_get_power().
     93
     94 */
     95smpl_t aubio_mfcc_get_power (aubio_mfcc_t *mf);
     96
     97/** set scaling parameter
     98
     99  \param mf mfcc object, as returned by new_aubio_mfcc()
     100  \param scale Scaling value to apply.
     101
     102  Scales the output of the filterbank after taking its logarithm and before
     103  computing the DCT. Defaults to `1`.
     104
     105*/
     106uint_t aubio_mfcc_set_scale (aubio_mfcc_t *mf, smpl_t scale);
     107
     108/** get scaling parameter
     109
     110  \param mf mfcc object, as returned by new_aubio_mfcc()
     111  \return current scaling parameter. Defaults to `1`.
     112
     113 */
     114smpl_t aubio_mfcc_get_scale (aubio_mfcc_t *mf);
     115
     116/** Mel filterbank initialization
     117
     118  \param mf mfcc object
     119  \param fmin start frequency, in Hz
     120  \param fmax end frequency, in Hz
     121
     122  The filterbank will be initialized with bands linearly spaced in the mel
     123  scale, from `fmin` to `fmax`.
     124
     125  See also
     126  --------
     127
     128  aubio_filterbank_set_mel_coeffs()
     129
     130*/
     131uint_t aubio_mfcc_set_mel_coeffs (aubio_mfcc_t *mf,
     132        smpl_t fmin, smpl_t fmax);
     133
     134/** Mel filterbank initialization
     135
     136  \param mf mfcc object
     137  \param fmin start frequency, in Hz
     138  \param fmax end frequency, in Hz
     139
     140  The bank of filters will be initalized to to cover linearly spaced bands in
     141  the Htk mel scale, from `fmin` to `fmax`.
     142
     143  See also
     144  --------
     145
     146  aubio_filterbank_set_mel_coeffs_htk()
     147
     148*/
     149uint_t aubio_mfcc_set_mel_coeffs_htk (aubio_mfcc_t *mf,
     150        smpl_t fmin, smpl_t fmax);
     151
     152/** Mel filterbank initialization (Auditory Toolbox's parameters)
     153
     154  \param mf mfcc object
     155
     156  The filter coefficients are built to match exactly Malcolm Slaney's Auditory
     157  Toolbox implementation. The number of filters should be 40.
     158
     159  This is the default filterbank when `mf` was created with `n_filters = 40`.
     160
     161  See also
     162  --------
     163
     164  aubio_filterbank_set_mel_coeffs_slaney()
     165
     166*/
     167uint_t aubio_mfcc_set_mel_coeffs_slaney (aubio_mfcc_t *mf);
     168
    75169#ifdef __cplusplus
    76170}
  • src/spectral/phasevoc.c

    r086a45b rf2f1b10  
    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

    r086a45b rf2f1b10  
    8989*/
    9090uint_t aubio_pvoc_get_win(aubio_pvoc_t* pv);
     91
    9192/** get hop size
    9293
  • src/spectral/specdesc.c

    r086a45b rf2f1b10  
    297297      onset_type = aubio_onset_default;
    298298  else {
    299       AUBIO_ERR("unknown spectral descriptor type %s\n", onset_mode);
     299      AUBIO_ERR("specdesc: unknown spectral descriptor type '%s'\n",
     300          onset_mode);
    300301      AUBIO_FREE(o);
    301302      return NULL;
  • src/synth/wavetable.c

    r086a45b rf2f1b10  
    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);
     168}
     169
     170uint_t
     171aubio_wavetable_load ( aubio_wavetable_t *s UNUSED, const char_t *uri UNUSED)
     172{
     173  AUBIO_ERR("wavetable: load method not implemented yet, see sampler\n");
     174  return AUBIO_FAIL;
    168175}
    169176
  • src/synth/wavetable.h

    r086a45b rf2f1b10  
    5353
    5454/** load source in wavetable
     55
     56  TODO: This function is not implemented yet. See new_aubio_sampler() instead.
    5557
    5658  \param o wavetable, created by new_aubio_wavetable()
  • src/tempo/tempo.c

    r086a45b rf2f1b10  
    129129
    130130uint_t aubio_tempo_set_delay_ms(aubio_tempo_t * o, smpl_t delay) {
    131   o->delay = 1000. * delay * o->samplerate;
    132   return AUBIO_OK;
     131  return aubio_tempo_set_delay_s(o, delay / 1000.);
    133132}
    134133
     
    142141
    143142smpl_t aubio_tempo_get_delay_ms(aubio_tempo_t * o) {
    144   return o->delay / (smpl_t)(o->samplerate) / 1000.;
     143  return aubio_tempo_get_delay_s(o) * 1000.;
    145144}
    146145
     
    169168{
    170169  aubio_tempo_t * o = AUBIO_NEW(aubio_tempo_t);
    171   char_t specdesc_func[20];
     170  char_t specdesc_func[PATH_MAX];
    172171  o->samplerate = samplerate;
    173172  // check parameters are valid
     
    204203  aubio_peakpicker_set_threshold (o->pp, o->threshold);
    205204  if ( strcmp(tempo_mode, "default") == 0 ) {
    206     strcpy(specdesc_func, "specflux");
     205    strncpy(specdesc_func, "specflux", PATH_MAX - 1);
    207206  } else {
    208     strcpy(specdesc_func, tempo_mode);
     207    strncpy(specdesc_func, tempo_mode, PATH_MAX - 1);
     208    specdesc_func[PATH_MAX - 1] = '\0';
    209209  }
    210210  o->od       = new_aubio_specdesc(specdesc_func,buf_size);
     
    216216    onset2 = new_fvec(1);
    217217  }*/
     218  if (!o->dfframe || !o->fftgrain || !o->out || !o->pv ||
     219      !o->pp || !o->od || !o->of || !o->bt || !o->onset) {
     220    AUBIO_ERR("tempo: failed creating tempo object\n");
     221    goto beach;
     222  }
    218223  o->last_tatum = 0;
    219224  o->tatum_signature = 4;
     
    221226
    222227beach:
    223   AUBIO_FREE(o);
     228  del_aubio_tempo(o);
    224229  return NULL;
    225230}
     
    278283void del_aubio_tempo (aubio_tempo_t *o)
    279284{
    280   del_aubio_specdesc(o->od);
    281   del_aubio_beattracking(o->bt);
    282   del_aubio_peakpicker(o->pp);
    283   del_aubio_pvoc(o->pv);
    284   del_fvec(o->out);
    285   del_fvec(o->of);
    286   del_cvec(o->fftgrain);
    287   del_fvec(o->dfframe);
    288   del_fvec(o->onset);
     285  if (o->od)
     286    del_aubio_specdesc(o->od);
     287  if (o->bt)
     288    del_aubio_beattracking(o->bt);
     289  if (o->pp)
     290    del_aubio_peakpicker(o->pp);
     291  if (o->pv)
     292    del_aubio_pvoc(o->pv);
     293  if (o->out)
     294    del_fvec(o->out);
     295  if (o->of)
     296    del_fvec(o->of);
     297  if (o->fftgrain)
     298    del_cvec(o->fftgrain);
     299  if (o->dfframe)
     300    del_fvec(o->dfframe);
     301  if (o->onset)
     302    del_fvec(o->onset);
    289303  AUBIO_FREE(o);
    290   return;
    291 }
     304}
  • src/utils/hist.c

    r086a45b rf2f1b10  
    4444  smpl_t accum = step;
    4545  uint_t i;
     46  if ((sint_t)nelems <= 0) {
     47    AUBIO_FREE(s);
     48    return NULL;
     49  }
    4650  s->nelems = nelems;
    4751  s->hist = new_fvec(nelems);
  • tests/src/io/test-sink.c

    r086a45b rf2f1b10  
    22#include "utils_tests.h"
    33
    4 int main (int argc, char **argv)
     4int test_wrong_params(void);
     5
     6int main(int argc, char **argv)
    57{
    6   sint_t err = 0;
    7 
    8   if (argc < 3) {
    9     err = 2;
    10     PRINT_ERR("not enough arguments\n");
    11     PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n", argv[0]);
     8  uint_t err = 0;
     9  if (argc < 3 || argc >= 6) {
     10    PRINT_ERR("wrong number of arguments, running tests\n");
     11    err = test_wrong_params();
     12    PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n",
     13        argv[0]);
    1214    return err;
    1315  }
     
    2022  char_t *sink_path = argv[2];
    2123
     24  aubio_source_t *src = NULL;
     25  aubio_sink_t *snk = NULL;
     26
    2227  if ( argc >= 4 ) samplerate = atoi(argv[3]);
    2328  if ( argc >= 5 ) hop_size = atoi(argv[4]);
    24   if ( argc >= 6 ) {
    25     err = 2;
    26     PRINT_ERR("too many arguments\n");
    27     return err;
    28   }
    2929
    3030  fvec_t *vec = new_fvec(hop_size);
    31   if (!vec) { err = 1; goto beach_fvec; }
     31  if (!vec) { err = 1; goto failure; }
    3232
    33   aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
    34   if (!i) { err = 1; goto beach_source; }
     33  src = new_aubio_source(source_path, samplerate, hop_size);
     34  if (!src) { err = 1; goto failure; }
     35  if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(src);
    3536
    36   if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
    37 
    38   aubio_sink_t *o = new_aubio_sink(sink_path, samplerate);
    39   if (!o) { err = 1; goto beach_sink; }
     37  snk = new_aubio_sink(sink_path, samplerate);
     38  if (!snk) { err = 1; goto failure; }
    4039
    4140  do {
    42     aubio_source_do(i, vec, &read);
    43     aubio_sink_do(o, vec, read);
     41    aubio_source_do(src, vec, &read);
     42    aubio_sink_do(snk, vec, read);
    4443    n_frames += read;
    4544  } while ( read == hop_size );
    4645
    47   PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n",
     46  PRINT_MSG("%d frames read at %dHz (%d blocks) from %s and written to %s\n",
    4847      n_frames, samplerate, n_frames / hop_size,
    4948      source_path, sink_path);
    5049
    51   del_aubio_sink(o);
    52 beach_sink:
    53   del_aubio_source(i);
    54 beach_source:
    55   del_fvec(vec);
    56 beach_fvec:
     50  // close sink now (optional)
     51  aubio_sink_close(snk);
     52
     53failure:
     54  if (snk)
     55    del_aubio_sink(snk);
     56  if (src)
     57    del_aubio_source(src);
     58  if (vec)
     59    del_fvec(vec);
     60
    5761  return err;
    5862}
     63
     64int test_wrong_params(void)
     65{
     66  fvec_t *vec;
     67  fmat_t *mat;
     68  aubio_sink_t *s;
     69  char_t sink_path[PATH_MAX] = "tmp_aubio_XXXXXX";
     70  uint_t samplerate = 44100;
     71  uint_t hop_size = 256;
     72  uint_t oversized_hop_size = 4097;
     73  uint_t oversized_samplerate = 192000 * 8 + 1;
     74  uint_t channels = 3;
     75  uint_t oversized_channels = 1025;
     76  // create temp file
     77  int fd = create_temp_sink(sink_path);
     78
     79  if (!fd) return 1;
     80
     81  if (new_aubio_sink(   0,   samplerate)) return 1;
     82  if (new_aubio_sink("\0",   samplerate)) return 1;
     83  if (new_aubio_sink(sink_path,      -1)) return 1;
     84
     85  s = new_aubio_sink(sink_path, 0);
     86
     87  // check setting wrong parameters fails
     88  if (!aubio_sink_preset_samplerate(s, oversized_samplerate)) return 1;
     89  if (!aubio_sink_preset_channels(s, oversized_channels)) return 1;
     90  if (!aubio_sink_preset_channels(s, -1)) return 1;
     91
     92  // check setting valid parameters passes
     93  if (aubio_sink_preset_samplerate(s, samplerate)) return 1;
     94  if (aubio_sink_preset_channels(s, 1)) return 1;
     95
     96  // check writing a vector with valid length
     97  vec = new_fvec(hop_size);
     98  aubio_sink_do(s, vec, hop_size);
     99  // check writing more than in the input
     100  aubio_sink_do(s, vec, hop_size+1);
     101  // check write 0 frames
     102  aubio_sink_do(s, vec, 0);
     103  del_fvec(vec);
     104
     105  // check writing an oversized vector
     106  vec = new_fvec(oversized_hop_size);
     107  aubio_sink_do(s, vec, oversized_hop_size);
     108  del_fvec(vec);
     109
     110  // test delete without closing
     111  del_aubio_sink(s);
     112
     113  s = new_aubio_sink(sink_path, 0);
     114
     115  // preset channels first
     116  if (aubio_sink_preset_channels(s, channels)) return 1;
     117  if (aubio_sink_preset_samplerate(s, samplerate)) return 1;
     118
     119  if (aubio_sink_get_samplerate(s) != samplerate) return 1;
     120  if (aubio_sink_get_channels(s) != channels) return 1;
     121
     122  mat = new_fmat(channels, hop_size);
     123  // check writing a vector with valid length
     124  aubio_sink_do_multi(s, mat, hop_size);
     125  // check writing 0 frames
     126  aubio_sink_do_multi(s, mat, 0);
     127  // check writing more than in the input
     128  aubio_sink_do_multi(s, mat, hop_size+1);
     129  del_fmat(mat);
     130
     131  // check writing oversized input
     132  mat = new_fmat(channels, oversized_hop_size);
     133  aubio_sink_do_multi(s, mat, oversized_hop_size);
     134  del_fmat(mat);
     135
     136  // check writing undersized input
     137  mat = new_fmat(channels - 1, hop_size);
     138  aubio_sink_do_multi(s, mat, hop_size);
     139  del_fmat(mat);
     140
     141  aubio_sink_close(s);
     142  // test closing twice
     143  aubio_sink_close(s);
     144
     145  del_aubio_sink(s);
     146
     147  // delete temp file
     148  close_temp_sink(sink_path, fd);
     149
     150  // shouldn't crash on null
     151  del_aubio_sink(NULL);
     152
     153  return run_on_default_source_and_sink(main);
     154}
  • tests/src/io/test-sink_apple_audio.c

    r086a45b rf2f1b10  
    22#include <aubio.h>
    33#include "utils_tests.h"
     4
     5#define aubio_sink_custom "apple_audio"
     6
     7#ifdef HAVE_SINK_APPLE_AUDIO
     8#define HAVE_AUBIO_SINK_CUSTOM
     9#define aubio_sink_custom_t aubio_sink_apple_audio_t
     10#define new_aubio_sink_custom new_aubio_sink_apple_audio
     11#define del_aubio_sink_custom del_aubio_sink_apple_audio
     12#define aubio_sink_custom_do aubio_sink_apple_audio_do
     13#define aubio_sink_custom_do_multi aubio_sink_apple_audio_do_multi
     14#define aubio_sink_custom_close aubio_sink_apple_audio_close
     15#define aubio_sink_custom_preset_samplerate aubio_sink_apple_audio_preset_samplerate
     16#define aubio_sink_custom_preset_channels aubio_sink_apple_audio_preset_channels
     17#define aubio_sink_custom_get_samplerate aubio_sink_apple_audio_get_samplerate
     18#define aubio_sink_custom_get_channels aubio_sink_apple_audio_get_channels
     19#endif /* HAVE_SINK_APPLE_AUDIO */
     20
     21#include "base-sink_custom.h"
    422
    523// this file uses the unstable aubio api, please use aubio_sink instead
     
    826int main (int argc, char **argv)
    927{
    10   sint_t err = 0;
    11 
    12   if (argc < 3) {
    13     err = 2;
    14     PRINT_ERR("not enough arguments\n");
    15     PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n", argv[0]);
    16     return err;
    17   }
    18 
    19 #ifdef HAVE_SINK_APPLE_AUDIO
    20   uint_t samplerate = 0;
    21   uint_t hop_size = 512;
    22   uint_t n_frames = 0, read = 0;
    23 
    24   char_t *source_path = argv[1];
    25   char_t *sink_path = argv[2];
    26 
    27   if ( argc >= 4 ) samplerate = atoi(argv[3]);
    28   if ( argc >= 5 ) hop_size = atoi(argv[4]);
    29   if ( argc >= 6 ) {
    30     err = 2;
    31     PRINT_ERR("too many arguments\n");
    32     return err;
    33   }
    34 
    35   fvec_t *vec = new_fvec(hop_size);
    36   if (!vec) { err = 1; goto beach_fvec; }
    37 
    38   aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
    39   if (!i) { err = 1; goto beach_source; }
    40 
    41   if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
    42 
    43   aubio_sink_apple_audio_t *o = new_aubio_sink_apple_audio(sink_path, samplerate);
    44   if (!o) { err = 1; goto beach_sink; }
    45 
    46   do {
    47     aubio_source_do(i, vec, &read);
    48     aubio_sink_apple_audio_do(o, vec, read);
    49     n_frames += read;
    50   } while ( read == hop_size );
    51 
    52   PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n",
    53       n_frames, samplerate, n_frames / hop_size,
    54       source_path, sink_path);
    55 
    56   del_aubio_sink_apple_audio(o);
    57 beach_sink:
    58   del_aubio_source(i);
    59 beach_source:
    60   del_fvec(vec);
    61 beach_fvec:
    62 #else /* HAVE_SINK_APPLE_AUDIO */
    63   err = 3;
    64   PRINT_ERR("aubio was not compiled with aubio_source_apple_audio\n");
    65 #endif /* HAVE_SINK_APPLE_AUDIO */
    66   return err;
     28  return base_main(argc, argv);
    6729}
  • tests/src/io/test-sink_sndfile.c

    r086a45b rf2f1b10  
    22#include <aubio.h>
    33#include "utils_tests.h"
     4
     5#define aubio_sink_custom "sndfile"
     6
     7#ifdef HAVE_SNDFILE
     8#define HAVE_AUBIO_SINK_CUSTOM
     9#define aubio_sink_custom_t aubio_sink_sndfile_t
     10#define new_aubio_sink_custom new_aubio_sink_sndfile
     11#define del_aubio_sink_custom del_aubio_sink_sndfile
     12#define aubio_sink_custom_do aubio_sink_sndfile_do
     13#define aubio_sink_custom_do_multi aubio_sink_sndfile_do_multi
     14#define aubio_sink_custom_close aubio_sink_sndfile_close
     15#define aubio_sink_custom_preset_samplerate aubio_sink_sndfile_preset_samplerate
     16#define aubio_sink_custom_preset_channels aubio_sink_sndfile_preset_channels
     17#define aubio_sink_custom_get_samplerate aubio_sink_sndfile_get_samplerate
     18#define aubio_sink_custom_get_channels aubio_sink_sndfile_get_channels
     19#endif /* HAVE_SNDFILE */
     20
     21#include "base-sink_custom.h"
    422
    523// this file uses the unstable aubio api, please use aubio_sink instead
     
    826int main (int argc, char **argv)
    927{
    10   sint_t err = 0;
    11 
    12   if (argc < 3) {
    13     err = 2;
    14     PRINT_ERR("not enough arguments\n");
    15     PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n", argv[0]);
    16     return err;
    17   }
    18 
    19 #ifdef HAVE_SNDFILE
    20   uint_t samplerate = 0;
    21   uint_t hop_size = 512;
    22   uint_t n_frames = 0, read = 0;
    23 
    24   char_t *source_path = argv[1];
    25   char_t *sink_path = argv[2];
    26 
    27   if ( argc >= 4 ) samplerate = atoi(argv[3]);
    28   if ( argc >= 5 ) hop_size = atoi(argv[4]);
    29   if ( argc >= 6 ) {
    30     err = 2;
    31     PRINT_ERR("too many arguments\n");
    32     return err;
    33   }
    34 
    35   fvec_t *vec = new_fvec(hop_size);
    36   if (!vec) { err = 1; goto beach_fvec; }
    37 
    38   aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
    39   if (!i) { err = 1; goto beach_source; }
    40 
    41   if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
    42 
    43   aubio_sink_sndfile_t *o = new_aubio_sink_sndfile(sink_path, samplerate);
    44   if (!o) { err = 1; goto beach_sink; }
    45 
    46   do {
    47     aubio_source_do(i, vec, &read);
    48     aubio_sink_sndfile_do(o, vec, read);
    49     n_frames += read;
    50   } while ( read == hop_size );
    51 
    52   PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n",
    53       n_frames, samplerate, n_frames / hop_size,
    54       source_path, sink_path);
    55 
    56   del_aubio_sink_sndfile(o);
    57 beach_sink:
    58   del_aubio_source(i);
    59 beach_source:
    60   del_fvec(vec);
    61 beach_fvec:
    62 #else
    63   err = 3;
    64   PRINT_ERR("aubio was not compiled with aubio_source_sndfile\n");
    65 #endif /* HAVE_SNDFILE */
    66   return err;
     28  return base_main(argc, argv);
    6729}
  • tests/src/io/test-sink_wavwrite.c

    r086a45b rf2f1b10  
    22#include <aubio.h>
    33#include "utils_tests.h"
     4
     5#define aubio_sink_custom "wavwrite"
     6
     7#ifdef HAVE_WAVWRITE
     8#define HAVE_AUBIO_SINK_CUSTOM
     9#define aubio_sink_custom_t aubio_sink_wavwrite_t
     10#define new_aubio_sink_custom new_aubio_sink_wavwrite
     11#define del_aubio_sink_custom del_aubio_sink_wavwrite
     12#define aubio_sink_custom_do aubio_sink_wavwrite_do
     13#define aubio_sink_custom_do_multi aubio_sink_wavwrite_do_multi
     14#define aubio_sink_custom_close aubio_sink_wavwrite_close
     15#define aubio_sink_custom_preset_samplerate aubio_sink_wavwrite_preset_samplerate
     16#define aubio_sink_custom_preset_channels aubio_sink_wavwrite_preset_channels
     17#define aubio_sink_custom_get_samplerate aubio_sink_wavwrite_get_samplerate
     18#define aubio_sink_custom_get_channels aubio_sink_wavwrite_get_channels
     19#endif /* HAVE_WAVWRITE */
     20
     21#include "base-sink_custom.h"
    422
    523// this file uses the unstable aubio api, please use aubio_sink instead
     
    826int main (int argc, char **argv)
    927{
    10   sint_t err = 0;
    11 
    12   if (argc < 3) {
    13     err = 2;
    14     PRINT_ERR("not enough arguments\n");
    15     PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n", argv[0]);
    16     return err;
    17   }
    18 
    19 #ifdef HAVE_WAVWRITE
    20   uint_t samplerate = 0;
    21   uint_t hop_size = 512;
    22   uint_t n_frames = 0, read = 0;
    23 
    24   char_t *source_path = argv[1];
    25   char_t *sink_path = argv[2];
    26 
    27   if ( argc >= 4 ) samplerate = atoi(argv[3]);
    28   if ( argc >= 5 ) hop_size = atoi(argv[4]);
    29   if ( argc >= 6 ) {
    30     err = 2;
    31     PRINT_ERR("too many arguments\n");
    32     return err;
    33   }
    34 
    35   fvec_t *vec = new_fvec(hop_size);
    36   if (!vec) { err = 1; goto beach_fvec; }
    37 
    38   aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
    39   if (!i) { err = 1; goto beach_source; }
    40 
    41   if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
    42 
    43   aubio_sink_wavwrite_t *o = new_aubio_sink_wavwrite(sink_path, samplerate);
    44   if (!o) { err = 1; goto beach_sink; }
    45 
    46   do {
    47     aubio_source_do(i, vec, &read);
    48     aubio_sink_wavwrite_do(o, vec, read);
    49     n_frames += read;
    50   } while ( read == hop_size );
    51 
    52   PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n",
    53       n_frames, samplerate, n_frames / hop_size,
    54       source_path, sink_path);
    55 
    56   del_aubio_sink_wavwrite(o);
    57 beach_sink:
    58   del_aubio_source(i);
    59 beach_source:
    60   del_fvec(vec);
    61 beach_fvec:
    62 #else
    63   err = 3;
    64   PRINT_ERR("aubio was not compiled with aubio_sink_wavwrite\n");
    65 #endif /* HAVE_WAVWRITE */
    66   return err;
     28  return base_main(argc, argv);
    6729}
  • tests/src/io/test-source.c

    r086a45b rf2f1b10  
    22#include "utils_tests.h"
    33
    4 int main (int argc, char **argv)
     4int test_wrong_params(void);
     5
     6int main(int argc, char **argv)
    57{
    68  uint_t err = 0;
    79  if (argc < 2) {
    8     err = 2;
    9     PRINT_ERR("not enough arguments\n");
     10    PRINT_ERR("not enough arguments, running tests\n");
     11    err = test_wrong_params();
    1012    PRINT_MSG("read a wave file as a mono vector\n");
    1113    PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
     
    2325  uint_t hop_size = 256;
    2426  uint_t n_frames = 0, read = 0;
    25   if ( argc == 3 ) samplerate = atoi(argv[2]);
    26   if ( argc == 4 ) hop_size = atoi(argv[3]);
     27  if ( argc >= 3 ) samplerate = atoi(argv[2]);
     28  if ( argc >= 4 ) hop_size = atoi(argv[3]);
    2729
    2830  char_t *source_path = argv[1];
    2931
    30 
    3132  aubio_source_t* s =
    3233    new_aubio_source(source_path, samplerate, hop_size);
    33   if (!s) { err = 1; goto beach; }
    3434  fvec_t *vec = new_fvec(hop_size);
     35  if (!s || !vec) { err = 1; goto beach; }
    3536
    3637  uint_t n_frames_expected = aubio_source_get_duration(s);
     
    5051  // close the file (optional)
    5152  aubio_source_close(s);
     53
     54beach:
     55  if (vec)
     56    del_fvec(vec);
     57  if (s)
     58    del_aubio_source(s);
     59  return err;
     60}
     61
     62int test_wrong_params(void)
     63{
     64  char_t *uri = DEFINEDSTRING(AUBIO_TESTS_SOURCE);
     65  uint_t samplerate = 44100;
     66  uint_t hop_size = 512;
     67  uint_t channels, read = 0;
     68  fvec_t *vec;
     69  fmat_t *mat;
     70  aubio_source_t *s;
     71
     72  if (new_aubio_source(0,    samplerate, hop_size)) return 1;
     73  if (new_aubio_source("\0", samplerate, hop_size)) return 1;
     74  if (new_aubio_source(uri,          -1, hop_size)) return 1;
     75  if (new_aubio_source(uri,           0,        0)) return 1;
     76
     77  s = new_aubio_source(uri, samplerate, hop_size);
     78  if (!s) return 1;
     79  channels = aubio_source_get_channels(s);
     80
     81  // vector to read downmixed samples
     82  vec = new_fvec(hop_size);
     83  // matrix to read individual channels
     84  mat = new_fmat(channels, hop_size);
     85
     86  if (aubio_source_get_samplerate(s) != samplerate) return 1;
     87
     88  // read first hop_size frames
     89  aubio_source_do(s, vec, &read);
     90  if (read != hop_size) return 1;
     91
     92  // read again in undersized vector
     93  del_fvec(vec);
     94  vec = new_fvec(hop_size - 1);
     95  aubio_source_do(s, vec, &read);
     96  if (read != hop_size - 1) return 1;
     97
     98  // read again in oversized vector
     99  del_fvec(vec);
     100  vec = new_fvec(hop_size + 1);
     101  aubio_source_do(s, vec, &read);
     102  if (read != hop_size) return 1;
     103
     104  // seek to 0
     105  if(aubio_source_seek(s, 0)) return 1;
     106
     107  // read again as multiple channels
     108  aubio_source_do_multi(s, mat, &read);
     109  if (read != hop_size) return 1;
     110
     111  // read again as multiple channels in an undersized matrix
     112  del_fmat(mat);
     113  mat = new_fmat(channels - 1, hop_size);
     114  aubio_source_do_multi(s, mat, &read);
     115  if (read != hop_size) return 1;
     116
     117  // read again as multiple channels in an undersized matrix
     118  del_fmat(mat);
     119  mat = new_fmat(channels, hop_size - 1);
     120  aubio_source_do_multi(s, mat, &read);
     121  if (read != hop_size - 1) return 1;
     122
     123  // read again as multiple channels in an oversized matrix
     124  del_fmat(mat);
     125  mat = new_fmat(channels + 1, hop_size);
     126  aubio_source_do_multi(s, mat, &read);
     127  if (read != hop_size) return 1;
     128
     129  // read again as multiple channels in an oversized matrix
     130  del_fmat(mat);
     131  mat = new_fmat(channels, hop_size + 1);
     132  aubio_source_do_multi(s, mat, &read);
     133  if (read != hop_size) return 1;
     134
     135  // close the file (optional)
     136  aubio_source_close(s);
    52137  // test closing the file a second time
    53138  aubio_source_close(s);
    54139
    55   del_fvec (vec);
    56   del_aubio_source (s);
    57 beach:
    58   return err;
     140  // reading after close fails
     141  del_fvec(vec);
     142  vec = new_fvec(hop_size);
     143  aubio_source_do(s, vec, &read);
     144  del_fmat(mat);
     145  mat = new_fmat(channels, hop_size);
     146  aubio_source_do_multi(s, mat, &read);
     147
     148  del_aubio_source(s);
     149  del_fmat(mat);
     150  del_fvec(vec);
     151
     152  // shouldn't crash on null
     153  del_aubio_source(NULL);
     154
     155  return run_on_default_source(main);
    59156}
  • tests/src/io/test-source_apple_audio.c

    r086a45b rf2f1b10  
    22#include <aubio.h>
    33#include "utils_tests.h"
     4
     5#define aubio_source_custom "apple_audio"
     6
     7#ifdef HAVE_SOURCE_APPLE_AUDIO
     8#define HAVE_AUBIO_SOURCE_CUSTOM
     9#define aubio_source_custom_t aubio_source_apple_audio_t
     10#define new_aubio_source_custom new_aubio_source_apple_audio
     11#define del_aubio_source_custom del_aubio_source_apple_audio
     12#define aubio_source_custom_get_samplerate aubio_source_apple_audio_get_samplerate
     13#define aubio_source_custom_get_duration aubio_source_apple_audio_get_duration
     14#define aubio_source_custom_do aubio_source_apple_audio_do
     15#define aubio_source_custom_do_multi aubio_source_apple_audio_do_multi
     16#define aubio_source_custom_seek aubio_source_apple_audio_seek
     17#define aubio_source_custom_close aubio_source_apple_audio_close
     18#define aubio_source_custom_get_channels aubio_source_apple_audio_get_channels
     19#define aubio_source_custom_get_samplerate aubio_source_apple_audio_get_samplerate
     20#endif /* HAVE_SOURCE_APPLE_AUDIO */
     21
     22#include "base-source_custom.h"
    423
    524// this file uses the unstable aubio api, please use aubio_source instead
     
    827int main (int argc, char **argv)
    928{
    10   uint_t err = 0;
    11   if (argc < 2) {
    12     err = 2;
    13     PRINT_ERR("not enough arguments\n");
    14     PRINT_MSG("read a wave file as a mono vector\n");
    15     PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
    16     PRINT_MSG("examples:\n");
    17     PRINT_MSG(" - read file.wav at original samplerate\n");
    18     PRINT_MSG("       %s file.wav\n", argv[0]);
    19     PRINT_MSG(" - read file.aif at 32000Hz\n");
    20     PRINT_MSG("       %s file.aif 32000\n", argv[0]);
    21     PRINT_MSG(" - read file.mp3 at original samplerate with 4096 blocks\n");
    22     PRINT_MSG("       %s file.mp3 0 4096 \n", argv[0]);
    23     return err;
    24   }
    25 
    26 #if HAVE_SOURCE_APPLE_AUDIO
    27   uint_t samplerate = 0;
    28   uint_t hop_size = 256;
    29   uint_t n_frames = 0, read = 0;
    30   if ( argc == 3 ) samplerate = atoi(argv[2]);
    31   if ( argc == 4 ) hop_size = atoi(argv[3]);
    32 
    33   char_t *source_path = argv[1];
    34 
    35 
    36   aubio_source_apple_audio_t * s =
    37     new_aubio_source_apple_audio(source_path, samplerate, hop_size);
    38   if (!s) { err = 1; goto beach; }
    39   fvec_t *vec = new_fvec(hop_size);
    40 
    41   uint_t n_frames_expected = aubio_source_apple_audio_get_duration(s);
    42 
    43   samplerate = aubio_source_apple_audio_get_samplerate(s);
    44 
    45   do {
    46     aubio_source_apple_audio_do(s, vec, &read);
    47     fvec_print (vec);
    48     n_frames += read;
    49   } while ( read == hop_size );
    50 
    51   PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n",
    52             n_frames, n_frames_expected, samplerate, n_frames / hop_size,
    53             source_path);
    54 
    55   del_fvec (vec);
    56   del_aubio_source_apple_audio (s);
    57 beach:
    58 #else /* HAVE_SOURCE_APPLE_AUDIO */
    59   err = 3;
    60   PRINT_ERR("aubio was not compiled with aubio_source_apple_audio\n");
    61 #endif /* HAVE_SOURCE_APPLE_AUDIO */
    62   return err;
     29  return base_main(argc, argv);
    6330}
  • tests/src/io/test-source_avcodec.c

    r086a45b rf2f1b10  
    22#include <aubio.h>
    33#include "utils_tests.h"
     4
     5#define aubio_source_custom "avcodec"
     6
     7#ifdef HAVE_LIBAV
     8#define HAVE_AUBIO_SOURCE_CUSTOM
     9#define aubio_source_custom_t aubio_source_avcodec_t
     10#define new_aubio_source_custom new_aubio_source_avcodec
     11#define del_aubio_source_custom del_aubio_source_avcodec
     12#define aubio_source_custom_get_samplerate aubio_source_avcodec_get_samplerate
     13#define aubio_source_custom_get_duration aubio_source_avcodec_get_duration
     14#define aubio_source_custom_do aubio_source_avcodec_do
     15#define aubio_source_custom_do_multi aubio_source_avcodec_do_multi
     16#define aubio_source_custom_seek aubio_source_avcodec_seek
     17#define aubio_source_custom_close aubio_source_avcodec_close
     18#define aubio_source_custom_get_channels aubio_source_avcodec_get_channels
     19#define aubio_source_custom_get_samplerate aubio_source_avcodec_get_samplerate
     20#endif /* HAVE_LIBAV */
     21
     22#include "base-source_custom.h"
    423
    524// this file uses the unstable aubio api, please use aubio_source instead
     
    827int main (int argc, char **argv)
    928{
    10   uint_t err = 0;
    11   if (argc < 2) {
    12     err = 2;
    13     PRINT_ERR("not enough arguments\n");
    14     PRINT_MSG("read a wave file as a mono vector\n");
    15     PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
    16     PRINT_MSG("examples:\n");
    17     PRINT_MSG(" - read file.wav at original samplerate\n");
    18     PRINT_MSG("       %s file.wav\n", argv[0]);
    19     PRINT_MSG(" - read file.wav at 32000Hz\n");
    20     PRINT_MSG("       %s file.aif 32000\n", argv[0]);
    21     PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n");
    22     PRINT_MSG("       %s file.wav 0 4096 \n", argv[0]);
    23     return err;
    24   }
    25 
    26 #ifdef HAVE_LIBAV
    27   uint_t samplerate = 0;
    28   uint_t hop_size = 256;
    29   uint_t n_frames = 0, read = 0;
    30   if ( argc == 3 ) samplerate = atoi(argv[2]);
    31   if ( argc == 4 ) hop_size = atoi(argv[3]);
    32 
    33   char_t *source_path = argv[1];
    34 
    35 
    36   aubio_source_avcodec_t * s =
    37     new_aubio_source_avcodec(source_path, samplerate, hop_size);
    38   if (!s) { err = 1; goto beach; }
    39   fvec_t *vec = new_fvec(hop_size);
    40 
    41   uint_t n_frames_expected = aubio_source_avcodec_get_duration(s);
    42 
    43   samplerate = aubio_source_avcodec_get_samplerate(s);
    44 
    45   do {
    46     aubio_source_avcodec_do(s, vec, &read);
    47     fvec_print (vec);
    48     n_frames += read;
    49   } while ( read == hop_size );
    50 
    51   PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n",
    52             n_frames, n_frames_expected, samplerate, n_frames / hop_size,
    53             source_path);
    54 
    55   del_fvec (vec);
    56   del_aubio_source_avcodec (s);
    57 beach:
    58 #else /* HAVE_LIBAV */
    59   err = 3;
    60   PRINT_ERR("aubio was not compiled with aubio_source_avcodec\n");
    61 #endif /* HAVE_LIBAV */
    62   return err;
     29  return base_main(argc, argv);
    6330}
  • tests/src/io/test-source_sndfile.c

    r086a45b rf2f1b10  
    22#include <aubio.h>
    33#include "utils_tests.h"
     4
     5#define aubio_source_custom "sndfile"
     6
     7#ifdef HAVE_SNDFILE
     8#define HAVE_AUBIO_SOURCE_CUSTOM
     9#define aubio_source_custom_t aubio_source_sndfile_t
     10#define new_aubio_source_custom new_aubio_source_sndfile
     11#define del_aubio_source_custom del_aubio_source_sndfile
     12#define aubio_source_custom_get_samplerate aubio_source_sndfile_get_samplerate
     13#define aubio_source_custom_get_duration aubio_source_sndfile_get_duration
     14#define aubio_source_custom_do aubio_source_sndfile_do
     15#define aubio_source_custom_do_multi aubio_source_sndfile_do_multi
     16#define aubio_source_custom_seek aubio_source_sndfile_seek
     17#define aubio_source_custom_close aubio_source_sndfile_close
     18#define aubio_source_custom_get_channels aubio_source_sndfile_get_channels
     19#define aubio_source_custom_get_samplerate aubio_source_sndfile_get_samplerate
     20#endif /* HAVE_LIBAV */
     21
     22#include "base-source_custom.h"
    423
    524// this file uses the unstable aubio api, please use aubio_source instead
     
    827int main (int argc, char **argv)
    928{
    10   uint_t err = 0;
    11   if (argc < 2) {
    12     err = 2;
    13     PRINT_ERR("not enough arguments\n");
    14     PRINT_MSG("read a wave file as a mono vector\n");
    15     PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
    16     PRINT_MSG("examples:\n");
    17     PRINT_MSG(" - read file.wav at original samplerate\n");
    18     PRINT_MSG("       %s file.wav\n", argv[0]);
    19     PRINT_MSG(" - read file.wav at 32000Hz\n");
    20     PRINT_MSG("       %s file.aif 32000\n", argv[0]);
    21     PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n");
    22     PRINT_MSG("       %s file.wav 0 4096 \n", argv[0]);
    23     return err;
    24   }
    25 
    26 #ifdef HAVE_SNDFILE
    27   uint_t samplerate = 0;
    28   uint_t hop_size = 256;
    29   uint_t n_frames = 0, read = 0;
    30   if ( argc == 3 ) samplerate = atoi(argv[2]);
    31   if ( argc == 4 ) hop_size = atoi(argv[3]);
    32 
    33   char_t *source_path = argv[1];
    34 
    35 
    36   aubio_source_sndfile_t * s =
    37     new_aubio_source_sndfile(source_path, samplerate, hop_size);
    38   if (!s) { err = 1; goto beach; }
    39   fvec_t *vec = new_fvec(hop_size);
    40 
    41   uint_t n_frames_expected = aubio_source_sndfile_get_duration(s);
    42 
    43   samplerate = aubio_source_sndfile_get_samplerate(s);
    44 
    45   do {
    46     aubio_source_sndfile_do(s, vec, &read);
    47     fvec_print (vec);
    48     n_frames += read;
    49   } while ( read == hop_size );
    50 
    51   PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n",
    52             n_frames, n_frames_expected, samplerate, n_frames / hop_size,
    53             source_path);
    54 
    55   del_fvec (vec);
    56   del_aubio_source_sndfile (s);
    57 beach:
    58 #else
    59   err = 3;
    60   PRINT_ERR("aubio was not compiled with aubio_source_sndfile\n");
    61 #endif /* HAVE_SNDFILE */
    62   return err;
     29  return base_main(argc, argv);
    6330}
  • tests/src/io/test-source_wavread.c

    r086a45b rf2f1b10  
    22#include <aubio.h>
    33#include "utils_tests.h"
     4
     5#define aubio_source_custom "wavread"
     6
     7#ifdef HAVE_WAVREAD
     8#define HAVE_AUBIO_SOURCE_CUSTOM
     9#define aubio_source_custom_t aubio_source_wavread_t
     10#define new_aubio_source_custom new_aubio_source_wavread
     11#define del_aubio_source_custom del_aubio_source_wavread
     12#define aubio_source_custom_get_samplerate aubio_source_wavread_get_samplerate
     13#define aubio_source_custom_get_duration aubio_source_wavread_get_duration
     14#define aubio_source_custom_do aubio_source_wavread_do
     15#define aubio_source_custom_do_multi aubio_source_wavread_do_multi
     16#define aubio_source_custom_seek aubio_source_wavread_seek
     17#define aubio_source_custom_close aubio_source_wavread_close
     18#define aubio_source_custom_get_channels aubio_source_wavread_get_channels
     19#define aubio_source_custom_get_samplerate aubio_source_wavread_get_samplerate
     20#endif /* HAVE_WAVREAD */
     21
     22#include "base-source_custom.h"
    423
    524// this file uses the unstable aubio api, please use aubio_source instead
     
    827int main (int argc, char **argv)
    928{
    10   uint_t err = 0;
    11   if (argc < 2) {
    12     err = 2;
    13     PRINT_ERR("not enough arguments\n");
    14     PRINT_MSG("read a wave file as a mono vector\n");
    15     PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
    16     PRINT_MSG("examples:\n");
    17     PRINT_MSG(" - read file.wav at original samplerate\n");
    18     PRINT_MSG("       %s file.wav\n", argv[0]);
    19     PRINT_MSG(" - read file.wav at 32000Hz\n");
    20     PRINT_MSG("       %s file.aif 32000\n", argv[0]);
    21     PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n");
    22     PRINT_MSG("       %s file.wav 0 4096 \n", argv[0]);
    23     return err;
    24   }
    25 
    26 #ifdef HAVE_WAVREAD
    27   uint_t samplerate = 0;
    28   uint_t hop_size = 256;
    29   uint_t n_frames = 0, read = 0;
    30   if ( argc == 3 ) samplerate = atoi(argv[2]);
    31   if ( argc == 4 ) hop_size = atoi(argv[3]);
    32 
    33   char_t *source_path = argv[1];
    34 
    35 
    36   aubio_source_wavread_t * s =
    37     new_aubio_source_wavread(source_path, samplerate, hop_size);
    38 
    39   if (!s) { err = 1; goto beach; }
    40   fvec_t *vec = new_fvec(hop_size);
    41 
    42   uint_t n_frames_expected = aubio_source_wavread_get_duration(s);
    43 
    44   samplerate = aubio_source_wavread_get_samplerate(s);
    45 
    46   do {
    47     aubio_source_wavread_do(s, vec, &read);
    48     fvec_print (vec);
    49     n_frames += read;
    50   } while ( read == hop_size );
    51 
    52   PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n",
    53             n_frames, n_frames_expected, samplerate, n_frames / hop_size,
    54             source_path);
    55 
    56   del_fvec (vec);
    57   del_aubio_source_wavread (s);
    58 beach:
    59 #else
    60   err = 3;
    61   PRINT_ERR("aubio was not compiled with aubio_source_wavread\n");
    62 #endif /* HAVE_WAVREAD */
    63   return err;
     29  return base_main(argc, argv);
    6430}
  • tests/src/onset/test-onset.c

    r086a45b rf2f1b10  
    11#include <aubio.h>
    22#include "utils_tests.h"
     3
     4int test_wrong_params(void);
    35
    46int main (int argc, char **argv)
     
    79  if (argc < 2) {
    810    err = 2;
    9     PRINT_ERR("not enough arguments\n");
    10     PRINT_MSG("read a wave file as a mono vector\n");
     11    PRINT_WRN("no arguments, running tests\n");
     12    err = test_wrong_params();
    1113    PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
    1214    return err;
     
    1618  uint_t hop_size = win_s / 4;
    1719  uint_t n_frames = 0, read = 0;
    18   if ( argc == 3 ) samplerate = atoi(argv[2]);
    19   if ( argc == 4 ) hop_size = atoi(argv[3]);
     20  if ( argc >= 3 ) samplerate = atoi(argv[2]);
     21  if ( argc >= 4 ) hop_size = atoi(argv[3]);
    2022
    2123  char_t *source_path = argv[1];
     
    6163  return err;
    6264}
     65
     66int test_wrong_params(void)
     67{
     68  uint_t win_size = 1024;
     69  uint_t hop_size = win_size / 2;
     70  uint_t samplerate = 44100;
     71  // hop_size < 1
     72  if (new_aubio_onset("default", 5, 0, samplerate)) return 1;
     73
     74  // buf_size < 2
     75  if (new_aubio_onset("default", 1, 1, samplerate)) return 1;
     76
     77  // buf_size < hop_size
     78  if (new_aubio_onset("default", hop_size, win_size, samplerate)) return 1;
     79
     80  // samplerate < 1
     81  if (new_aubio_onset("default", 1024, 512, 0)) return 1;
     82
     83  // specdesc creation failed
     84  if (new_aubio_onset("abcd", win_size, win_size/2, samplerate)) return 1;
     85
     86  aubio_onset_t *o;
     87
     88  // pv creation might fail
     89  o = new_aubio_onset("default", 5, 2, samplerate);
     90  if (o) del_aubio_onset(o);
     91
     92  o = new_aubio_onset("default", win_size, hop_size, samplerate);
     93  if (!aubio_onset_set_default_parameters(o, "wrong_type")) return 1;
     94  del_aubio_onset(o);
     95
     96  return run_on_default_source(main);
     97}
  • tests/src/pitch/test-pitch.c

    r086a45b rf2f1b10  
    3131  aubio_cleanup ();
    3232
     33  if (new_aubio_pitch(0, win_s, hop_s, samplerate)) return 1;
     34  if (new_aubio_pitch("unknown", win_s, hop_s, samplerate)) return 1;
     35  if (new_aubio_pitch("default", win_s,     0, samplerate)) return 1;
     36  if (new_aubio_pitch("default",     0, hop_s, samplerate)) return 1;
     37  if (new_aubio_pitch("default", hop_s, win_s, samplerate)) return 1;
     38  if (new_aubio_pitch("default", win_s, hop_s,          0)) return 1;
     39
     40  o = new_aubio_pitch("default", win_s, hop_s, samplerate);
     41
     42  if (aubio_pitch_set_unit(o, "freq")) return 1;
     43  if (aubio_pitch_set_unit(o, "hertz")) return 1;
     44  if (aubio_pitch_set_unit(o, "Hertz")) return 1;
     45  if (aubio_pitch_set_unit(o, "Hz")) return 1;
     46  if (aubio_pitch_set_unit(o, "f0")) return 1;
     47  if (aubio_pitch_set_unit(o, "midi")) return 1;
     48  if (aubio_pitch_set_unit(o, "cent")) return 1;
     49  if (aubio_pitch_set_unit(o, "bin")) return 1;
     50  if (!aubio_pitch_set_unit(o, "unknown")) return 1;
     51
     52  if (aubio_pitch_set_tolerance(o, 0.3)) return 1;
     53  if (aubio_pitch_set_silence(o, 0)) return 1;
     54  if (aubio_pitch_set_silence(o, -200)) return 1;
     55  if (!aubio_pitch_set_silence(o, -300)) return 1;
     56  del_aubio_pitch(o);
     57
     58  // fft based might fail with non power of 2
     59  o = new_aubio_pitch("yinfft", win_s + 1, hop_s, samplerate);
     60  if (o) del_aubio_pitch(o);
     61  o = new_aubio_pitch("yinfast", win_s + 1, hop_s, samplerate);
     62  if (o) del_aubio_pitch(o);
     63  o = new_aubio_pitch("fcomb", win_s + 1, hop_s, samplerate);
     64  if (o) del_aubio_pitch(o);
     65  o = new_aubio_pitch("mcomb", win_s + 1, hop_s, samplerate);
     66  if (o) del_aubio_pitch(o);
     67  o = new_aubio_pitch("specacf", win_s + 1, hop_s, samplerate);
     68  if (o) del_aubio_pitch(o);
     69
    3370  return 0;
    3471}
  • tests/src/spectral/test-awhitening.c

    r086a45b rf2f1b10  
    11#include <aubio.h>
    22#include "utils_tests.h"
     3
     4int test_wrong_params(void);
    35
    46int main (int argc, char **argv)
     
    810  if (argc < 3) {
    911    err = 2;
    10     PRINT_ERR("not enough arguments\n");
     12    PRINT_WRN("no arguments, running tests\n");
     13    err = test_wrong_params();
    1114    PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n", argv[0]);
    1215    return err;
     
    2326  if ( argc >= 4 ) samplerate = atoi(argv[3]);
    2427  if ( argc >= 5 ) hop_size = atoi(argv[4]);
    25   if ( argc >= 6 ) {
    26     err = 2;
    27     PRINT_ERR("too many arguments\n");
    28     return err;
    29   }
    3028
    3129  fvec_t *vec = new_fvec(hop_size);
     
    4442
    4543  aubio_pvoc_t *pv = new_aubio_pvoc(win_size, hop_size);
     44  if (!pv) { err = 1; goto beach_pvoc; }
    4645
    4746  aubio_spectral_whitening_t *awhitening =
    4847    new_aubio_spectral_whitening (win_size, hop_size, samplerate);
     48  if (!awhitening) { err = 1; goto beach_awhitening; }
    4949
    5050  aubio_spectral_whitening_set_relax_time(awhitening, 20.);
     
    7474      source_path, sink_path);
    7575
     76  del_aubio_spectral_whitening(awhitening);
     77beach_awhitening:
     78  del_aubio_pvoc(pv);
     79beach_pvoc:
    7680  del_aubio_sink(o);
    7781beach_sink:
     
    7983beach_source:
    8084  del_fvec(vec);
     85  del_fvec(out);
     86  del_fvec(scale);
     87  del_cvec(fftgrain);
    8188beach_fvec:
    8289  return err;
    8390}
    8491
     92int test_wrong_params(void)
     93{
     94  uint_t buf_size = 512;
     95  uint_t hop_size = 256;
     96  uint_t samplerate = 44100;
     97  aubio_spectral_whitening_t *o;
     98
     99  if (new_aubio_spectral_whitening(       0, hop_size, samplerate)) return 1;
     100  if (new_aubio_spectral_whitening(buf_size,        0, samplerate)) return 1;
     101  if (new_aubio_spectral_whitening(buf_size, hop_size,          0)) return 1;
     102
     103  o = new_aubio_spectral_whitening(buf_size, hop_size, samplerate);
     104
     105  aubio_spectral_whitening_get_relax_time(o);
     106  aubio_spectral_whitening_get_floor(o);
     107
     108  del_aubio_spectral_whitening(o);
     109
     110  return run_on_default_source_and_sink(main);
     111}
  • tests/src/spectral/test-filterbank.c

    r086a45b rf2f1b10  
    99  fvec_t *out_filters = new_fvec (n_filters); // per-band outputs
    1010
     11  if (new_aubio_filterbank(0, win_s)) return 1;
     12  if (new_aubio_filterbank(n_filters, 0)) return 1;
     13
    1114  // create filterbank object
    1215  aubio_filterbank_t *o = new_aubio_filterbank (n_filters, win_s);
     16
     17  smpl_t power = aubio_filterbank_get_power(o);
     18  smpl_t norm = aubio_filterbank_get_norm(o);
     19  if (aubio_filterbank_set_power(o, power)) {
     20    return 1;
     21  }
     22  if (aubio_filterbank_set_norm(o, norm)) {
     23    return 1;
     24  }
    1325
    1426  // apply filterbank ten times
  • tests/src/spectral/test-mfcc.c

    r086a45b rf2f1b10  
    11#include <aubio.h>
     2#include "utils_tests.h"
    23
    3 int main (void)
     4int test_wrong_params(void);
     5
     6int main (int argc, char** argv)
     7{
     8  sint_t err = 0;
     9
     10  if (argc < 2) {
     11    err = 2;
     12    PRINT_WRN("no arguments, running tests\n");
     13    err = test_wrong_params();
     14    PRINT_MSG("usage: %s <input_path> [samplerate] [hop_size]\n", argv[0]);
     15    return err;
     16  }
     17
     18  uint_t win_s; // fft size
     19  uint_t hop_s = 256; // block size
     20  uint_t samplerate = 0; // samplerate
     21  uint_t n_filters = 40; // number of filters
     22  uint_t n_coeffs = 13; // number of coefficients
     23  uint_t read = 0;
     24
     25  char_t *source_path = argv[1];
     26
     27  if ( argc >= 3 ) samplerate = atoi(argv[2]);
     28  if ( argc >= 4 ) hop_s = atoi(argv[3]);
     29
     30  win_s = 2 * hop_s;
     31
     32  aubio_source_t *source = 0;
     33  aubio_pvoc_t *pv = 0;
     34  aubio_mfcc_t *mfcc = 0;
     35
     36  fvec_t *in = new_fvec (hop_s);       // phase vocoder input
     37  cvec_t *fftgrain = new_cvec (win_s); // pvoc output / mfcc input
     38  fvec_t *out = new_fvec (n_coeffs);   // mfcc output
     39
     40  if (!in || !fftgrain || !out) { err = 1; goto failure; }
     41
     42  // source
     43  source = new_aubio_source(source_path, samplerate, hop_s);
     44  if (!source) { err = 1; goto failure; }
     45  if (samplerate == 0) samplerate = aubio_source_get_samplerate(source);
     46
     47  // phase vocoder
     48  pv = new_aubio_pvoc(win_s, hop_s);
     49  if (!pv) { err = 1; goto failure; }
     50
     51  // mfcc object
     52  mfcc = new_aubio_mfcc (win_s, n_filters, n_coeffs, samplerate);
     53  if (!mfcc) { err = 1; goto failure; }
     54
     55  // processing loop
     56  do {
     57    aubio_source_do(source, in, &read);
     58    aubio_pvoc_do(pv, in, fftgrain);
     59    aubio_mfcc_do(mfcc, fftgrain, out);
     60    fvec_print(out);
     61  } while (read == hop_s);
     62
     63failure:
     64
     65  if (mfcc)
     66    del_aubio_mfcc(mfcc);
     67  if (pv)
     68    del_aubio_pvoc(pv);
     69  if (source)
     70    del_aubio_source(source);
     71  if (in)
     72    del_fvec(in);
     73  if (fftgrain)
     74    del_cvec(fftgrain);
     75  if (out)
     76    del_fvec(out);
     77  aubio_cleanup();
     78  return err;
     79}
     80
     81int test_wrong_params()
    482{
    583  uint_t win_s = 512; // fft size
    684  uint_t n_filters = 40; // number of filters
    7   uint_t n_coefs = 13; // number of coefficients
     85  uint_t n_coeffs = 13; // number of coefficients
    886  smpl_t samplerate = 16000.; // samplerate
    9   cvec_t *in = new_cvec (win_s); // input buffer
    10   fvec_t *out = new_fvec (n_coefs); // output coefficients
    1187
    12   // create mfcc object
    13   aubio_mfcc_t *o = new_aubio_mfcc (win_s, n_filters, n_coefs, samplerate);
     88  if (new_aubio_mfcc(    0, n_filters, n_coeffs, samplerate)) return 1;
     89  if (new_aubio_mfcc(win_s,         0, n_coeffs, samplerate)) return 1;
     90  if (new_aubio_mfcc(win_s, n_filters,        0, samplerate)) return 1;
     91  if (new_aubio_mfcc(win_s, n_filters, n_coeffs,          0)) return 1;
    1492
    15   cvec_norm_set_all (in, 1.);
    16   aubio_mfcc_do (o, in, out);
    17   fvec_print (out);
    18 
    19   cvec_norm_set_all (in, .5);
    20   aubio_mfcc_do (o, in, out);
    21   fvec_print (out);
    22 
    23   // clean up
    24   del_aubio_mfcc (o);
    25   del_cvec (in);
    26   del_fvec (out);
    27   aubio_cleanup ();
    28 
    29   return 0;
     93  return run_on_default_source(main);
    3094}
  • tests/src/spectral/test-phasevoc.c

    r086a45b rf2f1b10  
    1313  // allocate fft and other memory space
    1414  aubio_pvoc_t * pv = new_aubio_pvoc(win_s,hop_s);
     15
     16  if (new_aubio_pvoc(win_s, 0)) return 1;
     17
     18  if (aubio_pvoc_get_win(pv) != win_s) return 1;
     19  if (aubio_pvoc_get_hop(pv) != hop_s) return 1;
     20
     21  if (aubio_pvoc_set_window(pv, "hanningz") != 0) return 1;
    1522
    1623  // fill input with some data
  • tests/src/spectral/test-tss.c

    r086a45b rf2f1b10  
    3535  }
    3636
     37  aubio_tss_set_alpha(tss, 4.);
     38  aubio_tss_set_beta(tss, 3.);
     39  aubio_tss_set_threshold(tss, 3.);
     40
    3741  del_aubio_pvoc(pv);
    3842  del_aubio_pvoc(pvt);
  • tests/src/synth/test-sampler.c

    r086a45b rf2f1b10  
     1#include <string.h> // strncpy
     2#include <limits.h> // PATH_MAX
    13#include <aubio.h>
    24#include "utils_tests.h"
     
    68  sint_t err = 0;
    79
    8   if (argc < 4) {
    9     err = 2;
    10     PRINT_ERR("not enough arguments\n");
     10  if (argc < 3) {
     11    PRINT_ERR("not enough arguments, running tests\n");
     12    err = run_on_default_source_and_sink(main);
    1113    PRINT_MSG("usage: %s <input_path> <output_path> <sample_path> [samplerate]\n", argv[0]);
    1214    return err;
     
    1921  char_t *source_path = argv[1];
    2022  char_t *sink_path = argv[2];
    21   char_t *sample_path = argv[3];
    22   if ( argc == 5 ) samplerate = atoi(argv[4]);
     23  char_t sample_path[PATH_MAX];
     24  if ( argc >= 4 ) {
     25    strncpy(sample_path, argv[3], PATH_MAX - 1);
     26  } else {
     27    // use input_path as sample
     28    strncpy(sample_path, source_path, PATH_MAX - 1);
     29  }
     30  sample_path[PATH_MAX - 1] = '\0';
     31  if ( argc >= 5 ) samplerate = atoi(argv[4]);
    2332
    2433  fvec_t *vec = new_fvec(hop_size);
  • tests/src/synth/test-wavetable.c

    r086a45b rf2f1b10  
    77
    88  if (argc < 2) {
    9     err = 2;
    10     PRINT_ERR("not enough arguments\n");
     9    PRINT_ERR("not enough arguments, running tests\n");
     10    err = run_on_default_sink(main);
    1111    PRINT_MSG("usage: %s <output_path> [freq] [samplerate]\n", argv[0]);
    1212    return err;
     
    1818
    1919  char_t *sink_path = argv[1];
    20   if ( argc == 4 ) samplerate = atoi(argv[3]);
    21   if ( argc == 3 ) freq = atof(argv[2]);
     20  if ( argc >= 4 ) samplerate = atoi(argv[3]);
     21  if ( argc >= 3 ) freq = atof(argv[2]);
    2222
    2323  fvec_t *vec = new_fvec(hop_size);
  • tests/src/tempo/test-tempo.c

    r086a45b rf2f1b10  
    11#include <aubio.h>
    22#include "utils_tests.h"
     3
     4int test_wrong_params(void);
    35
    46int main (int argc, char **argv)
     
    68  uint_t err = 0;
    79  if (argc < 2) {
    8     err = 2;
    9     PRINT_ERR("not enough arguments\n");
    10     PRINT_MSG("read a wave file as a mono vector\n");
    11     PRINT_MSG("usage: %s <source_path> [samplerate] [win_size] [hop_size]\n", argv[0]);
     10    PRINT_WRN("no arguments, running tests\n");
     11    err = test_wrong_params();
     12    PRINT_MSG("usage: %s <source_path> [samplerate] [win_size] [hop_size]\n",
     13        argv[0]);
    1214    return err;
    1315  }
     
    2123
    2224  char_t *source_path = argv[1];
    23   aubio_source_t * source = new_aubio_source(source_path, samplerate, hop_size);
     25  aubio_source_t * source = new_aubio_source(source_path, samplerate,
     26      hop_size);
    2427  if (!source) { err = 1; goto beach; }
    2528
     
    3134
    3235  // create tempo object
    33   aubio_tempo_t * o = new_aubio_tempo("default", win_size, hop_size, samplerate);
     36  aubio_tempo_t * o = new_aubio_tempo("default", win_size, hop_size,
     37      samplerate);
     38
     39  if (!o) { err = 1; goto beach_tempo; }
    3440
    3541  do {
     
    4046    // do something with the beats
    4147    if (out->data[0] != 0) {
    42       PRINT_MSG("beat at %.3fms, %.3fs, frame %d, %.2fbpm with confidence %.2f\n",
     48      PRINT_MSG("beat at %.3fms, %.3fs, frame %d, %.2f bpm "
     49          "with confidence %.2f\n",
    4350          aubio_tempo_get_last_ms(o), aubio_tempo_get_last_s(o),
    44           aubio_tempo_get_last(o), aubio_tempo_get_bpm(o), aubio_tempo_get_confidence(o));
     51          aubio_tempo_get_last(o), aubio_tempo_get_bpm(o),
     52          aubio_tempo_get_confidence(o));
    4553    }
    4654    n_frames += read;
     
    5462  // clean up memory
    5563  del_aubio_tempo(o);
     64beach_tempo:
    5665  del_fvec(in);
    5766  del_fvec(out);
     
    6271  return err;
    6372}
     73
     74int test_wrong_params(void)
     75{
     76  uint_t win_size = 1024;
     77  uint_t hop_size = 256;
     78  uint_t samplerate = 44100;
     79  aubio_tempo_t *t;
     80  fvec_t* in, *out;
     81  uint_t i;
     82
     83  // test wrong method fails
     84  if (new_aubio_tempo("undefined", win_size, hop_size, samplerate)) return 1;
     85
     86  // test hop > win fails
     87  if (new_aubio_tempo("default", hop_size, win_size, samplerate)) return 1;
     88
     89  // test null hop_size fails
     90  if (new_aubio_tempo("default", win_size, 0, samplerate)) return 1;
     91
     92  // test 1 buf_size fails
     93  if (new_aubio_tempo("default", 1, 1, samplerate)) return 1;
     94
     95  // test null samplerate fails
     96  if (new_aubio_tempo("default", win_size, hop_size, 0)) return 1;
     97
     98  // test short sizes workaround
     99  t = new_aubio_tempo("default", 2048, 2048, 500);
     100  if (!t) return 1;
     101
     102  del_aubio_tempo(t);
     103
     104  t = new_aubio_tempo("default", win_size, hop_size, samplerate);
     105  if (!t) return 1;
     106
     107  in = new_fvec(hop_size);
     108  out = new_fvec(1);
     109
     110  // up to step = (next_power_of_two(5.8 * samplerate / hop_size ) / 4 )
     111  for (i = 0; i < 256 + 1; i++)
     112  {
     113    aubio_tempo_do(t,in,out);
     114    PRINT_MSG("beat at %.3fms, %.3fs, frame %d, %.2f bpm "
     115        "with confidence %.2f, was tatum %d\n",
     116        aubio_tempo_get_last_ms(t), aubio_tempo_get_last_s(t),
     117        aubio_tempo_get_last(t), aubio_tempo_get_bpm(t),
     118        aubio_tempo_get_confidence(t), aubio_tempo_was_tatum(t));
     119  }
     120
     121  del_aubio_tempo(t);
     122  del_fvec(in);
     123  del_fvec(out);
     124
     125  return run_on_default_source(main);
     126}
  • tests/src/temporal/test-filter.c

    r086a45b rf2f1b10  
    99
    1010  aubio_filter_t *o = new_aubio_filter_c_weighting (44100);
     11
     12  if (new_aubio_filter(0)) return 1;
     13
     14  if (aubio_filter_get_samplerate(o) != 44100) return 1;
     15
     16  if (aubio_filter_set_c_weighting (o, -1) == 0) return 1;
     17
     18  if (aubio_filter_set_c_weighting (0, 32000) == 0) return 1;
     19
    1120  in->data[impulse_at] = 0.5;
    1221  fvec_print (in);
     
    1625
    1726  o = new_aubio_filter_a_weighting (32000);
     27
     28  if (aubio_filter_set_a_weighting (o, -1) == 0) return 1;
     29
     30  if (aubio_filter_set_a_weighting (0, 32000) == 0) return 1;
     31
    1832  in->data[impulse_at] = 0.5;
    1933  fvec_print (in);
  • tests/src/test-cvec.c

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

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

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

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

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

    r086a45b rf2f1b10  
    101101  fvec_set_window(window, "rectangle");
    102102  fvec_print(window);
     103  del_fvec(window);
    103104
    104105  window_size /= 2.;
    105   window = new_aubio_window("triangle", window_size);
     106  window = new_aubio_window("parzen", window_size);
    106107  fvec_print(window);
    107108  del_fvec(window);
     
    117118  test_miditofreq();
    118119  test_freqtomidi();
     120  test_aubio_window();
    119121  return 0;
    120122}
  • tests/src/utils/test-hist.c

    r086a45b rf2f1b10  
    2626    del_fvec(t);
    2727  }
     28  if (new_aubio_hist(0, 1, 0)) return 1;
    2829  return 0;
    2930}
  • tests/utils_tests.h

    r086a45b rf2f1b10  
    55#include <assert.h>
    66#include "config.h"
     7
     8#ifdef HAVE_STRING_H
     9#include <string.h>
     10#endif
     11
     12#ifdef HAVE_UNISTD_H
     13#include <unistd.h> // unlink, close
     14#endif
     15
     16#ifdef HAVE_LIMITS_H
     17#include <limits.h> // PATH_MAX
     18#endif /* HAVE_LIMITS_H */
     19#ifndef PATH_MAX
     20#define PATH_MAX 1024
     21#endif
     22
     23#if defined(HAVE_WIN_HACKS) && !defined(__GNUC__)
     24#include <io.h> // _access
     25#endif
     26
     27// This macro is used to pass a string to msvc compiler: since msvc's -D flag
     28// strips the quotes, we define the string without quotes and re-add them with
     29// this macro.
     30
     31#define REDEFINESTRING(x) #x
     32#define DEFINEDSTRING(x) REDEFINESTRING(x)
     33
     34#ifndef AUBIO_TESTS_SOURCE
     35#error "AUBIO_TESTS_SOURCE is not defined"
     36#endif
    737
    838#ifdef HAVE_C99_VARARGS_MACROS
     
    2656#endif
    2757
    28 // are we on windows ? or are we using -std=c99 ?
    29 #if defined(HAVE_WIN_HACKS) || defined(__STRICT_ANSI__)
    30 // http://en.wikipedia.org/wiki/Linear_congruential_generator
    31 // no srandom/random on win32
     58#if defined(HAVE_WIN_HACKS)
    3259
    33 uint_t srandom_seed = 1029;
     60// use srand/rand on windows
     61#define srandom srand
     62#define random rand
    3463
    35 void srandom(uint_t new_seed) {
    36     srandom_seed = new_seed;
    37 }
     64#elif defined(__STRICT_ANSI__)
    3865
    39 uint_t random(void) {
    40     srandom_seed = 1664525 * srandom_seed + 1013904223;
    41     return srandom_seed;
    42 }
     66// workaround to build with -std=c99 (for instance with older cygwin),
     67// assuming libbc is recent enough to supports these functions.
     68extern void srandom(unsigned);
     69extern int random(void);
     70extern char mkstemp(const char *pat);
     71
    4372#endif
    4473
     
    4877  time_t now = time(0);
    4978  struct tm *tm_struct = localtime(&now);
    50   int seed = tm_struct->tm_sec;
     79  size_t **tm_address = (void*)&tm_struct;
     80  int seed = tm_struct->tm_sec + (size_t)tm_address;
    5181  //PRINT_WRN("current seed: %d\n", seed);
    52   srandom (seed);
     82  srandom ((unsigned int)seed);
    5383}
     84
     85// create_temp_sink / close_temp_sink
     86#if defined(__GNUC__) // mkstemp
     87
     88int check_source(char *source_path)
     89{
     90  return access(source_path, R_OK);
     91}
     92
     93int create_temp_sink(char *sink_path)
     94{
     95  return mkstemp(sink_path);
     96}
     97
     98int close_temp_sink(char *sink_path, int sink_fildes)
     99{
     100  int err;
     101  if ((err = close(sink_fildes)) != 0) return err;
     102  if ((err = unlink(sink_path)) != 0) return err;
     103  return err;
     104}
     105
     106#elif defined(HAVE_WIN_HACKS) //&& !defined(__GNUC__)
     107// windows workaround, where mkstemp does not exist...
     108
     109int check_source(char *source_path)
     110{
     111  return _access(source_path, 04);
     112}
     113
     114int create_temp_sink(char *templ)
     115{
     116  int i = 0;
     117  static const char letters[] = "abcdefg0123456789";
     118  int letters_len = strlen(letters);
     119  int templ_len = strlen(templ);
     120  if (templ_len == 0) return 0;
     121  utils_init_random();
     122  for (i = 0; i < 6; i++)
     123  {
     124    templ[templ_len - i] = letters[rand() % letters_len];
     125  }
     126  return 1;
     127}
     128
     129int close_temp_sink(char* sink_path, int sink_fildes) {
     130  // the file should be closed when not using mkstemp, no need to open it
     131  if (sink_fildes == 0) return 1;
     132  return _unlink(sink_path);
     133}
     134
     135#else // windows workaround
     136// otherwise, we don't really know what to do yet
     137#error "mkstemp undefined, but not on windows. additional workaround required."
     138#endif
     139
     140// pass progname / default
     141int run_on_default_source( int main(int, char**) )
     142{
     143  const int argc = 2;
     144  int err = 0;
     145  char** argv = (char**)calloc(argc, sizeof(char*));
     146  argv[0] = __FILE__;
     147  argv[1] = DEFINEDSTRING(AUBIO_TESTS_SOURCE);
     148  // check if the file can be read
     149  if ( check_source(argv[1]) ) return 1;
     150  err = main(argc, argv);
     151  if (argv) free(argv);
     152  return err;
     153}
     154
     155int run_on_default_sink( int main(int, char**) )
     156{
     157  const int argc = 2;
     158  int err = 0;
     159  char** argv = (char**)calloc(argc, sizeof(char*));
     160  char sink_path[PATH_MAX] = "tmp_aubio_XXXXXX";
     161  int fd = create_temp_sink(sink_path);
     162  if (!fd) return 1;
     163  argv[0] = __FILE__;
     164  argv[1] = sink_path;
     165  err = main(argc, argv);
     166  close_temp_sink(sink_path, fd);
     167  if (argv) free(argv);
     168  return err;
     169}
     170
     171int run_on_default_source_and_sink( int main(int, char**) )
     172{
     173  const int argc = 3;
     174  int err = 0;
     175  char** argv = (char**)calloc(argc, sizeof(char*));
     176  char sink_path[PATH_MAX] = "tmp_aubio_XXXXXX";
     177  int fd = create_temp_sink(sink_path);
     178  if (!fd) return 1;
     179  argv[0] = __FILE__;
     180  argv[1] = DEFINEDSTRING(AUBIO_TESTS_SOURCE);
     181  argv[2] = sink_path;
     182  // check if the file can be read
     183  if ( check_source(argv[1]) ) return 1;
     184  err = main(argc, argv);
     185  close_temp_sink(sink_path, fd);
     186  if (argv) free(argv);
     187  return err;
     188}
  • tests/wscript_build

    r086a45b rf2f1b10  
    88programs_sources = ctx.path.ant_glob('src/**/*.c')
    99
     10test_sound_target = '44100Hz_44100f_sine441_stereo.wav'
     11test_sound_abspath = bld.path.get_bld().make_node(test_sound_target)
     12# workaround to double escape backslash characters on windows
     13test_sound_abspath = str(test_sound_abspath).replace('\\', '\\\\')
     14
     15b = bld(name='create_tests_source',
     16    rule='python ${SRC} ${TGT}',
     17    source='create_tests_source.py',
     18    target=test_sound_target)
     19# use post() to create the task, keep a reference to it
     20b.post()
     21create_tests_source = b.tasks[0]
     22
    1023for source_file in programs_sources:
    1124    target = os.path.basename(os.path.splitext(str(source_file))[0])
    12     bld(features = 'c cprogram test',
     25    a = bld(features = 'c cprogram test',
    1326            source = source_file,
    1427            target = target,
     
    1629            use = uselib,
    1730            install_path = None,
    18             defines = 'AUBIO_UNSTABLE_API=1',
     31            defines = ['AUBIO_UNSTABLE_API=1',
     32                        'AUBIO_TESTS_SOURCE={}'.format(test_sound_abspath)]
    1933       )
     34    a.post()
     35    # make sure the unit_test task runs *after* the source is created
     36    a.tasks[-1].set_run_after(create_tests_source)
  • wscript

    r086a45b rf2f1b10  
    4343            choices = ('debug', 'release'),
    4444            dest = 'build_type',
    45             help = 'whether to compile with (--build-type=release) or without (--build-type=debug) '\
    46               ' compiler opimizations [default: release]')
     45            help = 'whether to compile with (--build-type=release)' \
     46                    ' or without (--build-type=debug)' \
     47                    ' compiler opimizations [default: release]')
    4748    add_option_enable_disable(ctx, 'fftw3f', default = False,
    4849            help_str = 'compile with fftw3f instead of ooura (recommended)',
     
    8485            help_str = 'use CoreFoundation (darwin only) (auto)',
    8586            help_disable_str = 'do not use CoreFoundation framework')
     87    add_option_enable_disable(ctx, 'blas', default = False,
     88            help_str = 'use BLAS acceleration library (no)',
     89            help_disable_str = 'do not use BLAS library')
    8690    add_option_enable_disable(ctx, 'atlas', default = False,
    87             help_str = 'use Atlas library (no)',
    88             help_disable_str = 'do not use Atlas library')
     91            help_str = 'use ATLAS acceleration library (no)',
     92            help_disable_str = 'do not use ATLAS library')
    8993    add_option_enable_disable(ctx, 'wavread', default = True,
    9094            help_str = 'compile with source_wavread (default)',
     
    98102            help_disable_str = 'do not build documentation')
    99103
     104    add_option_enable_disable(ctx, 'tests', default = True,
     105            help_str = 'build tests (true)',
     106            help_disable_str = 'do not build or run tests')
     107
     108    add_option_enable_disable(ctx, 'examples', default = True,
     109            help_str = 'build examples (true)',
     110            help_disable_str = 'do not build examples')
     111
    100112    ctx.add_option('--with-target-platform', type='string',
    101             help='set target platform for cross-compilation', dest='target_platform')
     113            help='set target platform for cross-compilation',
     114            dest='target_platform')
    102115
    103116    ctx.load('compiler_c')
     
    127140    ctx.check(header_name='math.h')
    128141    ctx.check(header_name='string.h')
     142    ctx.check(header_name='errno.h')
    129143    ctx.check(header_name='limits.h')
    130144    ctx.check(header_name='stdarg.h')
     
    195209            ctx.msg('Checking for AudioToolbox.framework', 'yes')
    196210        else:
    197             ctx.msg('Checking for AudioToolbox.framework', 'no (disabled)', color = 'YELLOW')
     211            ctx.msg('Checking for AudioToolbox.framework', 'no (disabled)',
     212                    color = 'YELLOW')
    198213        if (ctx.options.enable_accelerate != False):
    199214            ctx.define('HAVE_ACCELERATE', 1)
     
    201216            ctx.msg('Checking for Accelerate framework', 'yes')
    202217        else:
    203             ctx.msg('Checking for Accelerate framework', 'no (disabled)', color = 'YELLOW')
     218            ctx.msg('Checking for Accelerate framework', 'no (disabled)',
     219                    color = 'YELLOW')
    204220
    205221    if target_platform in [ 'ios', 'iosimulator' ]:
     
    255271        # tell emscripten functions we want to expose
    256272        from python.lib.gen_external import get_c_declarations, \
    257                 get_cpp_objects_from_c_declarations, get_all_func_names_from_lib, \
     273                get_cpp_objects_from_c_declarations, \
     274                get_all_func_names_from_lib, \
    258275                generate_lib_from_c_declarations
    259         c_decls = get_c_declarations(usedouble=False)  # emscripten can't use double
     276        # emscripten can't use double
     277        c_decls = get_c_declarations(usedouble=False)
    260278        objects = list(get_cpp_objects_from_c_declarations(c_decls))
    261279        # ensure that aubio structs are exported
     
    264282        exported_funcnames = get_all_func_names_from_lib(lib)
    265283        c_mangled_names = ['_' + s for s in exported_funcnames]
    266         ctx.env.LINKFLAGS_cshlib += ['-s', 'EXPORTED_FUNCTIONS=%s' % c_mangled_names]
    267 
    268     if (ctx.options.enable_atlas != True):
    269         ctx.options.enable_atlas = False
     284        ctx.env.LINKFLAGS_cshlib += ['-s',
     285                'EXPORTED_FUNCTIONS=%s' % c_mangled_names]
    270286
    271287    # check support for C99 __VA_ARGS__ macros
     
    297313    # check for Intel IPP
    298314    if (ctx.options.enable_intelipp != False):
    299         has_ipp_headers = ctx.check(header_name=['ippcore.h', 'ippvm.h', 'ipps.h'],
    300                 mandatory = False)
     315        has_ipp_headers = ctx.check(header_name=['ippcore.h', 'ippvm.h',
     316            'ipps.h'], mandatory = False)
    301317        has_ipp_libs = ctx.check(lib=['ippcore', 'ippvm', 'ipps'],
    302318                uselib_store='INTEL_IPP', mandatory = False)
     
    305321            ctx.define('HAVE_INTEL_IPP', 1)
    306322            if ctx.env.CC_NAME == 'msvc':
    307                 # force linking multi-threaded static IPP libraries on Windows with msvc
     323                # force linking multi-threaded static IPP libraries on Windows
     324                # with msvc
    308325                ctx.define('_IPP_SEQUENTIAL_STATIC', 1)
    309326        else:
     
    354371    if (ctx.options.enable_double):
    355372        if (ctx.options.enable_samplerate):
    356             ctx.fatal("Could not compile aubio in double precision mode with libsamplerate")
     373            ctx.fatal("Could not compile aubio in double precision mode' \
     374                    ' with libsamplerate")
    357375        else:
    358376            ctx.options.enable_samplerate = False
    359             ctx.msg('Checking if using samplerate', 'no (disabled in double precision mode)',
    360                     color = 'YELLOW')
     377            ctx.msg('Checking if using samplerate',
     378                    'no (disabled in double precision mode)', color = 'YELLOW')
    361379    if (ctx.options.enable_samplerate != False):
    362380        ctx.check_cfg(package = 'samplerate',
     
    401419        elif 'HAVE_AVUTIL' not in ctx.env:
    402420            ctx.msg(msg_check, 'not found (missing avutil)', color = 'YELLOW')
    403         elif 'HAVE_SWRESAMPLE' not in ctx.env and 'HAVE_AVRESAMPLE' not in ctx.env:
     421        elif 'HAVE_SWRESAMPLE' not in ctx.env \
     422                and 'HAVE_AVRESAMPLE' not in ctx.env:
    404423            resample_missing = 'not found (avresample or swresample required)'
    405424            ctx.msg(msg_check, resample_missing, color = 'YELLOW')
     
    414433    if (ctx.options.enable_wavread != False):
    415434        ctx.define('HAVE_WAVREAD', 1)
    416     ctx.msg('Checking if using source_wavread', ctx.options.enable_wavread and 'yes' or 'no')
     435    ctx.msg('Checking if using source_wavread',
     436            ctx.options.enable_wavread and 'yes' or 'no')
    417437    if (ctx.options.enable_wavwrite!= False):
    418438        ctx.define('HAVE_WAVWRITE', 1)
    419     ctx.msg('Checking if using sink_wavwrite', ctx.options.enable_wavwrite and 'yes' or 'no')
    420 
    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)
     439    ctx.msg('Checking if using sink_wavwrite',
     440            ctx.options.enable_wavwrite and 'yes' or 'no')
     441
     442    # use BLAS/ATLAS
     443    if (ctx.options.enable_blas != False):
     444        ctx.check_cfg(package = 'blas',
     445                args = '--cflags --libs',
     446                uselib_store='BLAS', mandatory = ctx.options.enable_blas)
     447        if 'LIB_BLAS' in ctx.env:
     448            blas_header = None
     449            if ctx.env['LIBPATH_BLAS']:
     450                if 'atlas' in ctx.env['LIBPATH_BLAS'][0]:
     451                    blas_header = 'atlas/cblas.h'
     452                elif 'openblas' in ctx.env['LIBPATH_BLAS'][0]:
     453                    blas_header = 'openblas/cblas.h'
     454            else:
     455                blas_header = 'cblas.h'
     456            ctx.check(header_name = blas_header, mandatory =
     457                    ctx.options.enable_atlas)
    426458
    427459    # use memcpy hacks
     
    474506        if bld.env['DEST_OS']=='emscripten' and not bld.options.testcmd:
    475507            bld.options.testcmd = 'node %s'
    476         bld.recurse('examples')
    477         bld.recurse('tests')
     508        if bld.options.enable_examples:
     509            bld.recurse('examples')
     510        if bld.options.enable_tests:
     511            bld.recurse('tests')
    478512
    479513    # pkg-config template
     
    484518    doxygen(bld)
    485519    sphinx(bld)
     520
     521    from waflib.Tools import waf_unit_test
     522    bld.add_post_fun(waf_unit_test.summary)
     523    bld.add_post_fun(waf_unit_test.set_exit_code)
    486524
    487525def txt2man(bld):
     
    510548    if bld.env['DOXYGEN']:
    511549        bld.env.VERSION = VERSION
    512         rule = '( cat ${SRC} && echo PROJECT_NUMBER=${VERSION}; )'
     550        rule = '( cat ${SRC[0]} && echo PROJECT_NUMBER=${VERSION}'
     551        rule += ' && echo OUTPUT_DIRECTORY=%s && echo HTML_OUTPUT=%s )'
    513552        rule += ' | doxygen - > /dev/null'
     553        rule %= (os.path.abspath(out), 'api')
    514554        bld( name = 'doxygen', rule = rule,
    515                 source = 'doc/web.cfg',
    516                 target = '../doc/web/html/index.html',
    517                 cwd = 'doc')
    518         bld.install_files( '${DATAROOTDIR}' + '/doc/libaubio-doc',
    519                 bld.path.ant_glob('doc/web/html/**'),
    520                 cwd = bld.path.find_dir ('doc/web'),
    521                 relative_trick = True)
     555                source = ['doc/web.cfg']
     556                    + bld.path.find_dir('src').ant_glob('**/*.h'),
     557                target = bld.path.find_or_declare('api/index.html'),
     558                cwd = bld.path.find_dir('doc'))
     559        # evaluate nodes lazily to prevent build directory traversal warnings
     560        bld.install_files('${DATAROOTDIR}/doc/libaubio-doc/api',
     561                bld.path.find_or_declare('api').ant_glob('**/*',
     562                    generator=True), cwd=bld.path.find_or_declare('api'),
     563                relative_trick=True)
    522564
    523565def sphinx(bld):
    524566    # build documentation from source files using sphinx-build
    525     # note: build in ../doc/_build/html, otherwise waf wont install unsigned files
    526     if bld.env['SPHINX']:
     567    try:
     568        import aubio
     569        has_aubio = True
     570    except ImportError:
     571        from waflib import Logs
     572        Logs.pprint('YELLOW', "Sphinx manual: install aubio first")
     573        has_aubio = False
     574    if bld.env['SPHINX'] and has_aubio:
    527575        bld.env.VERSION = VERSION
    528         bld( name = 'sphinx',
    529                 rule = '${SPHINX} -b html -D release=${VERSION} -D version=${VERSION} -a -q `dirname ${SRC}` `dirname ${TGT}`',
    530                 source = 'doc/conf.py',
    531                 target = '../doc/_build/html/index.html')
    532         bld.install_files( '${DATAROOTDIR}' + '/doc/libaubio-doc/sphinx',
    533                 bld.path.ant_glob('doc/_build/html/**'),
    534                 cwd = bld.path.find_dir('doc/_build/html'),
    535                 relative_trick = True)
     576        rule = '${SPHINX} -b html -D release=${VERSION}' \
     577                ' -D version=${VERSION} -W -a -q' \
     578                ' -d %s ' % os.path.join(os.path.abspath(out), 'doctrees')
     579        rule += ' . %s' % os.path.join(os.path.abspath(out), 'manual')
     580        bld( name = 'sphinx', rule = rule,
     581                cwd = bld.path.find_dir('doc'),
     582                source = bld.path.find_dir('doc').ant_glob('*.rst'),
     583                target = bld.path.find_or_declare('manual/index.html'))
     584        # evaluate nodes lazily to prevent build directory traversal warnings
     585        bld.install_files('${DATAROOTDIR}/doc/libaubio-doc/manual',
     586                bld.path.find_or_declare('manual').ant_glob('**/*',
     587                    generator=True), cwd=bld.path.find_or_declare('manual'),
     588                relative_trick=True)
    536589
    537590# register the previous rules as build rules
     
    557610    from waflib import Logs
    558611    if bld.options.target_platform in ['ios', 'iosimulator']:
    559         msg ='building for %s, contact the author for a commercial license' % bld.options.target_platform
     612        msg ='building for %s, contact the author for a commercial license' \
     613                % bld.options.target_platform
    560614        Logs.pprint('RED', msg)
    561615        msg ='   Paul Brossier <piem@aubio.org>'
     
    563617
    564618def dist(ctx):
    565     ctx.excl  = ' **/.waf* **/*~ **/*.pyc **/*.swp **/*.swo **/*.swn **/.lock-w* **/.git*'
     619    ctx.excl  = ' **/.waf*'
     620    ctx.excl += ' **/.git*'
     621    ctx.excl += ' **/*~ **/*.pyc **/*.swp **/*.swo **/*.swn **/.lock-w*'
    566622    ctx.excl += ' **/build/*'
    567623    ctx.excl += ' doc/_build'
     
    571627    ctx.excl += ' **/python/lib/aubio/_aubio.so'
    572628    ctx.excl += ' **.egg-info'
     629    ctx.excl += ' **/.eggs'
     630    ctx.excl += ' **/.pytest_cache'
     631    ctx.excl += ' **/.cache'
    573632    ctx.excl += ' **/**.zip **/**.tar.bz2'
    574     ctx.excl += ' **.tar.bz2'
     633    ctx.excl += ' **.tar.bz2**'
    575634    ctx.excl += ' **/doc/full/* **/doc/web/*'
    576635    ctx.excl += ' **/doc/full.cfg'
     
    578637    ctx.excl += ' **/python.old/*'
    579638    ctx.excl += ' **/python/*/*.old'
     639    ctx.excl += ' **/python/lib/aubio/*.so'
    580640    ctx.excl += ' **/python/tests/sounds'
    581641    ctx.excl += ' **/**.asc'
     
    583643    ctx.excl += ' **/.DS_Store'
    584644    ctx.excl += ' **/.travis.yml'
    585     ctx.excl += ' **/.landscape.yml'
    586645    ctx.excl += ' **/.appveyor.yml'
    587     ctx.excl += ' **/circlei.yml'
     646    ctx.excl += ' **/.circleci/*'
     647    ctx.excl += ' **/azure-pipelines.yml'
     648    ctx.excl += ' **/.coverage*'
Note: See TracChangeset for help on using the changeset viewer.