Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes for v0.17 release #498

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/python-package-conda.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Python Package using Conda

on: [push]

jobs:
build-linux:
runs-on: ubuntu-latest

defaults:
run:
shell: bash -l {0}

strategy:
max-parallel: 5
fail-fast: false
matrix:
python-version: [ "3.7", "3.8", "3.9", "3.10" ]

steps:
- uses: actions/checkout@v2

- name: Cache conda
uses: actions/cache@v2
env:
CACHE_NUMBER: 1 # increment this value to reset cache if environment.yml has not changed
with:
path: ~/conda_pkgs_dir
key: ${{ runner.os }}-${{ matrix.python-version }}-conda-${{ env.CACHE_NUMBER }}

- name: Install Conda env
uses: conda-incubator/setup-miniconda@v2
with:
auto-update-conda: true
python-version: ${{ matrix.python-version }}
add-pip-as-python-dependency: true
auto-activate-base: false
activate-environment: madmom
environment-file: environment.yml
use-only-tar-bz2: true # this needs to be set for caching to work properly

- name: Conda info
run: |
conda info -a
conda list

- name: Install madmom
run: |
pip install -e .
git submodule update --init --remote

- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --exit-zero --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

- name: Test with pytest
run: |
pytest --cov --doctest-ignore-import-errors madmom tests

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
directory: ./coverage/reports/
flags: unittests
env_vars: OS,PYTHON
name: codecov-umbrella
fail_ci_if_error: true
path_to_write_report: ./coverage/codecov_report.txt
verbose: true
49 changes: 0 additions & 49 deletions .travis.yml

This file was deleted.

19 changes: 14 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,15 @@ will give different help messages.
Additional resources
====================

Mailing list
------------
Discussions / Q&A
-----------------

Github discussions (https://github.com/CPJKU/madmom/discussions) should be
used to get in touch with the developers and other users, to ask questions
about madmom's usage and ideas for development.

The `mailing list <https://groups.google.com/d/forum/madmom-users>`_ should be
used to get in touch with the developers and other users.
The `mailing list <https://groups.google.com/d/forum/madmom-users>`_ is kept
as an archive but should not be used for new questions/

Wiki
----
Expand Down Expand Up @@ -366,12 +370,17 @@ References
*Deep Polyphonic ADSR Piano Note Transcription*,
Proceedings of the 44th International Conference on Acoustics, Speech and
Signal Processing (ICASSP), 2019.
.. [20] Sebastian Böck, Matthew Davies and Peter Knees,
*Multi-Task learning of tempo and beat: learning one to improve the other*,
Proceedings of the 20th International Society for Music Information
Retrieval Conference (ISMIR), 2019.


Acknowledgements
================

Supported by the European Commission through the `GiantSteps project
<http://www.giantsteps-project.eu>`_ (FP7 grant agreement no. 610591) and the
<http://giantsteps-project.upf.edu>`_ (FP7 grant agreement no. 610591) and the
`Phenicx project <http://phenicx.upf.edu>`_ (FP7 grant agreement no. 601166)
as well as the `Austrian Science Fund (FWF) <https://www.fwf.ac.at>`_ project
Z159.
1 change: 1 addition & 0 deletions bin/BarTracker
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def main():
# signal processor
signal_processor = SignalProcessor(**vars(args))
# beats processor
load_beats_processor = None
if hasattr(args, 'infile'):
# single mode: read the beats from STDIN
load_beats_processor = LoadBeatsProcessor(**vars(args))
Expand Down
5 changes: 5 additions & 0 deletions bin/evaluate
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ def main():
# parse the args
args = p.parse_args()

# print usage if no evaluation mode was set
if not getattr(args, 'eval', False):
p.print_usage()
exit(0)

# print the arguments
if args.verbose >= 2:
print(args)
Expand Down
19 changes: 12 additions & 7 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@ dependencies:
- scipy
- opencv
- portaudio
- pyfftw
- ffmpeg
- pyaudio
- pip
- pip:
- mido>=1.2.6
- pyfftw
- pyaudio
- pytest
- black
- pre-commit
- prospector
- mido>=1.2.6
- flake8<4
- coverage
- pytest
- pytest-cov
- pytest-flake8
- black
- pre-commit
- prospector
3 changes: 3 additions & 0 deletions madmom/audio/spectrogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ def tuning_frequency(self, **kwargs):
Tuning frequency of the spectrogram.

"""
import warnings
warnings.warn('tuning_frequency() is deprecated as of version 0.17 '
'and will be removed in 0.19.')
from scipy.ndimage.filters import maximum_filter
# widen the spectrogram in frequency dimension
max_spec = maximum_filter(self, size=[1, 3])
Expand Down
10 changes: 5 additions & 5 deletions madmom/evaluation/chords.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def encode(chord_labels):
Parameters
----------
chord_labels : numpy structured array
Chord segments in `madmom.io.SEGMENT_DTYPE` format
Chord segments in `madmom.io.SEGMENT_DTYPE` format.

Returns
-------
Expand Down Expand Up @@ -728,10 +728,10 @@ class ChordEvaluation(EvaluationMixin):

Parameters
----------
detections : str
File containing chords detections.
annotations : str
File containing chord annotations.
detections : numpy structured array
Detected chord segments in `madmom.io.SEGMENT_DTYPE` format.
annotations : numpy structured array
Annotated chord segments in `madmom.io.SEGMENT_DTYPE` format.
name : str, optional
Name of the evaluation object (e.g., the name of the song).

Expand Down
8 changes: 5 additions & 3 deletions madmom/features/beats.py
Original file line number Diff line number Diff line change
Expand Up @@ -1014,16 +1014,18 @@ def process_offline(self, activations, **kwargs):
Detected beat positions [seconds].

"""
# init the beats to return and the offset
beats = np.empty(0, dtype=int)
# init beats to return and offset (to be added later)
beats = np.empty(0, dtype=float)
first = 0
# use only the activations > threshold
# use only activations > threshold
if self.threshold:
activations, first = threshold_activations(activations,
self.threshold)
# return no beats if no activations given / remain after thresholding
if not activations.any():
return beats
# add a small epsilon to prevent division by 0
activations += np.finfo(activations.dtype).eps
# get the best state path by calling the viterbi algorithm
path, _ = self.hmm.viterbi(activations)
# also return no beats if no path was found
Expand Down
20 changes: 16 additions & 4 deletions madmom/features/downbeats.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,13 @@ def _process_dbn(process_tuple):

class DBNDownBeatTrackingProcessor(Processor):
"""
Downbeat tracking with RNNs and a dynamic Bayesian network (DBN)
approximated by a Hidden Markov Model (HMM).
Downbeat tracking with a dynamic Bayesian network (DBN) approximated by
a Hidden Markov Model (HMM).

The observations must reflect the probabilities corresponding to beats
and downbeats. The probability for non-beats is computed given these two
probabilities as p(nb) = 1 - p(b) - p(db). All three observations must be
a probability density function, i.e. sum(p(nb) + p(b) + p(db)) == 1.

Parameters
----------
Expand Down Expand Up @@ -268,21 +273,28 @@ def process(self, activations, **kwargs):
"""
# pylint: disable=arguments-differ
import itertools as it
# use only the activations > threshold (init offset to be added later)
# init beats to return and offset (to be added later)
beats = np.empty((0, 2), dtype=float)
first = 0
# use only activations > threshold
if self.threshold:
activations, first = threshold_activations(activations,
self.threshold)
# return no beats if no activations given / remain after thresholding
if not activations.any():
return np.empty((0, 2))
return beats
# add a small epsilon to prevent division by 0
activations += np.finfo(activations.dtype).eps
# (parallel) decoding of the activations with HMM
results = list(self.map(_process_dbn, zip(self.hmms,
it.repeat(activations))))
# choose the best HMM (highest log probability)
best = np.argmax(list(r[1] for r in results))
# the best path through the state space
path, _ = results[best]
# also return no beats if no path was found
if not path.any():
return beats
# the state space and observation model of the best HMM
st = self.hmms[best].transition_model.state_space
om = self.hmms[best].observation_model
Expand Down
6 changes: 2 additions & 4 deletions madmom/ml/hmm.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,8 @@ class TransitionModel(object):
probabilities = np.asarray(probabilities)
if not np.allclose(np.bincount(prev_states, weights=probabilities), 1):
raise ValueError('Not a probability distribution.')
# convert everything into a sparse CSR matrix, make sure it is square.
# looking through prev_states is enough, because there *must* be a
# transition *from* every state
num_states = max(prev_states) + 1
# convert everything into a sparse CSR matrix, make sure it is square
num_states = max(states.max(), prev_states.max()) + 1
transitions = csr_matrix((probabilities, (states, prev_states)),
shape=(num_states, num_states))
# convert to correct types
Expand Down
3 changes: 3 additions & 0 deletions madmom/ml/nn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ def load(cls, nn_files, **kwargs):

"""
networks = [NeuralNetwork.load(f) for f in nn_files]
# raise error if no NNs were loaded
if not networks:
raise ValueError('No neural network(s) could be loaded.')
return cls(networks, **kwargs)

@staticmethod
Expand Down
10 changes: 9 additions & 1 deletion madmom/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ def process_online(processor, infile, outfile, **kwargs):
kwargs['sample_rate'] = kwargs.get('sample_rate', 44100)
kwargs['num_channels'] = kwargs.get('num_channels', 1)
# list all available PyAudio devices and exit afterwards
if kwargs['list_stream_input_device']:
if kwargs.get('list_stream_input_device'):
import pyaudio
pa = pyaudio.PyAudio()
for i in range(pa.get_device_count()):
Expand Down Expand Up @@ -947,6 +947,14 @@ def io_arguments(parser, output_suffix='.txt', pickle=True, online=False):
# add general options
parser.add_argument('-v', dest='verbose', action='count',
help='increase verbosity level')

# print usage if no processing mode is set
def print_usage(*args, **kwargs):
parser.print_usage()
exit(0)

parser.set_defaults(func=print_usage)

# add subparsers
sub_parsers = parser.add_subparsers(title='processing options')

Expand Down
14 changes: 10 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@
['madmom/features/beats_crf.pyx'],
include_dirs=include_dirs,
),
Extension('madmom.ml.hmm', ['madmom/ml/hmm.pyx'], include_dirs=include_dirs),
Extension(
'madmom.ml.nn.layers', ['madmom/ml/nn/layers.py'], include_dirs=include_dirs
'madmom.ml.hmm',
['madmom/ml/hmm.pyx'],
include_dirs=include_dirs
),
Extension(
'madmom.ml.nn.layers',
['madmom/ml/nn/layers.py'],
include_dirs=include_dirs,
),
]

Expand All @@ -44,10 +50,10 @@
package_data = [
'models/LICENSE',
'models/README.rst',
'models/beats/201[56]/*',
'models/beats/201[569]/*',
'models/chords/*/*',
'models/chroma/*/*',
'models/downbeats/*/*',
'models/downbeats/2016/*',
'models/key/2018/*',
'models/notes/*/*',
'models/onsets/*/*',
Expand Down
Loading