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 ass