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

Added Tempo Changes to pretty midi #24

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion .github/workflows/linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
build:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Set up Python
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/packaging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:

jobs:
deploy:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Set up Python
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-20.04, macos-latest, windows-latest]
python-version: ['3.6', '3.7', '3.8']
runs-on: ${{ matrix.os }}
steps:
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Working files
*.mid
*.midi
# add any permanent files with git add -f

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
2 changes: 1 addition & 1 deletion doc/source/read_write.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ Functions
:noindex:

.. note::
Writing the tempo array and downbeat array to tempo change and time signature change events are not supported yet.
Writing the downbeat array to time signature change events is not supported yet.
2 changes: 1 addition & 1 deletion docs/_sources/read_write.rst.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ Functions
:noindex:

.. note::
Writing the tempo array and downbeat array to tempo change and time signature change events are not supported yet.
Writing the downbeat array to time signature change events is not supported yet.
20 changes: 9 additions & 11 deletions docs/doc.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->

<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
Expand All @@ -19,10 +19,10 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="prev" title="Metrics" href="metrics.html" />
<link rel="prev" title="Metrics" href="metrics.html" />
</head>

<body class="wy-body-for-nav">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
Expand Down Expand Up @@ -71,7 +71,7 @@
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">

<section id="module-pypianoroll">
<span id="technical-documentation"></span><h1>Technical Documentation<a class="headerlink" href="#module-pypianoroll" title="Permalink to this headline"></a></h1>
<p>A Python library for handling multitrack pianorolls.</p>
Expand Down Expand Up @@ -1797,8 +1797,7 @@ <h2>Features<a class="headerlink" href="#features" title="Permalink to this head
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>default_tempo</strong> (int, default: <cite>pypianoroll.DEFAULT_TEMPO</cite> (120)) – Default tempo to use. If attribute <cite>tempo</cite> is available, use its
first element.</p></li>
<li><p><strong>default_tempo</strong> (int, default: <cite>pypianoroll.DEFAULT_TEMPO</cite> (120)) – Default tempo to use. If attribute <cite>tempo</cite> is available, encorporate it into the midi file with any tempo changes and time signature changes that occur.</p></li>
<li><p><strong>default_velocity</strong> (int, default: <cite>pypianoroll.DEFAULT_VELOCITY</cite> (64)) – Default velocity to assign to binarized tracks.</p></li>
</ul>
</dd>
Expand All @@ -1811,8 +1810,7 @@ <h2>Features<a class="headerlink" href="#features" title="Permalink to this head
</dl>
<p class="rubric">Notes</p>
<ul class="simple">
<li><p>Tempo changes are not supported.</p></li>
<li><p>Time signature changes are not supported.</p></li>
<li><p>Time signature changes default to */4.</p></li>
<li><p>The velocities of the converted piano rolls will be clipped to
[0, 127].</p></li>
<li><p>Adjacent nonzero values of the same pitch will be considered
Expand Down Expand Up @@ -1928,7 +1926,7 @@ <h2>Features<a class="headerlink" href="#features" title="Permalink to this head
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.


</footer>
</div>
Expand All @@ -1939,7 +1937,7 @@ <h2>Features<a class="headerlink" href="#features" title="Permalink to this head
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>

</body>
</html>
</html>
22 changes: 10 additions & 12 deletions docs/read_write.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->

<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
Expand All @@ -19,10 +19,10 @@
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Visualization" href="visualization.html" />
<link rel="prev" title="Save &amp; Load" href="save_load.html" />
<link rel="prev" title="Save &amp; Load" href="save_load.html" />
</head>

<body class="wy-body-for-nav">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
Expand Down Expand Up @@ -71,7 +71,7 @@
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">

<section id="read-write">
<h1>Read &amp; Write<a class="headerlink" href="#read-write" title="Permalink to this headline"></a></h1>
<p>Pypianoroll currently supports reading from and writing to MIDI files.</p>
Expand Down Expand Up @@ -178,8 +178,7 @@ <h2>Functions<a class="headerlink" href="#functions" title="Permalink to this he
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>default_tempo</strong> (int, default: <cite>pypianoroll.DEFAULT_TEMPO</cite> (120)) – Default tempo to use. If attribute <cite>tempo</cite> is available, use its
first element.</p></li>
<li><p><strong>default_tempo</strong> (int, default: <cite>pypianoroll.DEFAULT_TEMPO</cite> (120)) – Default tempo to use. If attribute <cite>tempo</cite> is available, encorporate it into the midi file with any tempo changes and time signature changes that occur.</p></li>
<li><p><strong>default_velocity</strong> (int, default: <cite>pypianoroll.DEFAULT_VELOCITY</cite> (64)) – Default velocity to assign to binarized tracks.</p></li>
</ul>
</dd>
Expand All @@ -192,8 +191,7 @@ <h2>Functions<a class="headerlink" href="#functions" title="Permalink to this he
</dl>
<p class="rubric">Notes</p>
<ul class="simple">
<li><p>Tempo changes are not supported.</p></li>
<li><p>Time signature changes are not supported.</p></li>
<li><p>Time signature changes default to */4.</p></li>
<li><p>The velocities of the converted piano rolls will be clipped to
[0, 127].</p></li>
<li><p>Adjacent nonzero values of the same pitch will be considered
Expand All @@ -203,7 +201,7 @@ <h2>Functions<a class="headerlink" href="#functions" title="Permalink to this he

<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Writing the tempo array and downbeat array to tempo change and time signature change events are not supported yet.</p>
<p>Writing the downbeat array to time signature change events is not supported yet.</p>
</div>
</section>
</section>
Expand All @@ -225,7 +223,7 @@ <h2>Functions<a class="headerlink" href="#functions" title="Permalink to this he
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.


</footer>
</div>
Expand All @@ -236,7 +234,7 @@ <h2>Functions<a class="headerlink" href="#functions" title="Permalink to this he
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>

</body>
</html>
</html>
4 changes: 2 additions & 2 deletions pypianoroll/inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def from_pretty_midi(

# Parse downbeat array
if not midi.time_signature_changes:
# This probably won't happen as pretty_midi always add a 4/4 time
# This probably won't happen as pretty_midi always adds a 4/4 time
# signature at time 0
beat = None
downbeat = None
Expand Down Expand Up @@ -234,7 +234,7 @@ def from_pretty_midi(
one_more_beat = 2 * beat_times[-1] - beat_times[-2]
beat_times_one_more = np.append(beat_times, one_more_beat)
bpm = 60.0 / np.diff(beat_times_one_more)
tempo = np.tile(bpm, (1, 24)).reshape(-1, 1)
tempo = np.repeat(bpm, resolution).reshape(-1, 1)

# Parse the tracks
tracks = []
Expand Down
2 changes: 1 addition & 1 deletion pypianoroll/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def qualified_note_rate(pianoroll: ndarray, threshold: float = 2) -> float:
2018.

"""
if np.issubdtype(pianoroll.dtype, np.bool_):
if np.issubdtype(pianoroll.dtype, bool):
pianoroll = pianoroll.astype(np.uint8)
padded = np.pad(pianoroll, ((1, 1), (0, 0)), "constant")
diff = np.diff(padded, axis=0).reshape(-1)
Expand Down
35 changes: 19 additions & 16 deletions pypianoroll/multitrack.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
- DEFAULT_RESOLUTION

"""
from typing import List, Sequence, TypeVar
from typing import List, Sequence, TypeVar, Union

import numpy as np
from matplotlib.axes import Axes
Expand Down Expand Up @@ -66,7 +66,8 @@ class Multitrack:
Time steps per quarter note.
tempo : ndarray, dtype=float, shape=(?, 1), optional
Tempo (in qpm) at each time step. Length is the total number
of time steps. Cast to float if not of float type.
of time steps. Cast to float if not of float type. Alternatively,
enter a single float or integer and the array will be generated.
beat : ndarray, dtype=bool, shape=(?, 1), optional
A boolean array that indicates whether the time step contains a
beat. Length is the total number of time steps. Cast to bool if
Expand All @@ -84,7 +85,7 @@ def __init__(
self,
name: str = None,
resolution: int = None,
tempo: ndarray = None,
tempo: Union[ndarray, int, float] = None,
beat: ndarray = None,
downbeat: ndarray = None,
tracks: Sequence[Track] = None,
Expand All @@ -96,8 +97,17 @@ def __init__(
else:
self.resolution = DEFAULT_RESOLUTION

if tracks is None:
self.tracks = []
elif isinstance(tracks, list):
self.tracks = tracks
else:
self.tracks = list(tracks)

if tempo is None:
self.tempo = None
elif isinstance(tempo, int) or isinstance(tempo, float):
self.tempo = np.tile(tempo, (self.get_max_length(), 1)).astype(float)
elif np.issubdtype(tempo.dtype, np.floating):
self.tempo = tempo
else:
Expand All @@ -117,13 +127,6 @@ def __init__(
else:
self.downbeat = np.asarray(downbeat).astype(bool)

if tracks is None:
self.tracks = []
elif isinstance(tracks, list):
self.tracks = tracks
else:
self.tracks = list(tracks)

def __len__(self) -> int:
return len(self.tracks)

Expand Down Expand Up @@ -187,15 +190,15 @@ def _validate_type(self, attr):
elif attr == "beat":
if not isinstance(self.beat, np.ndarray):
raise TypeError("`beat` must be a NumPy array.")
if not np.issubdtype(self.beat.dtype, np.bool_):
if not np.issubdtype(self.beat.dtype, bool):
raise TypeError(
"`beat` must be of data type bool, but got data type"
f"{self.beat.dtype}."
)
elif attr == "downbeat":
if not isinstance(self.downbeat, np.ndarray):
raise TypeError("`downbeat` must be a NumPy array.")
if not np.issubdtype(self.downbeat.dtype, np.bool_):
if not np.issubdtype(self.downbeat.dtype, bool):
raise TypeError(
"`downbeat` must be of data type bool, but got data type"
f"{self.downbeat.dtype}."
Expand Down Expand Up @@ -248,16 +251,16 @@ def _validate(self, attr):
if self.resolution < 1:
raise ValueError("`resolution` must be a positive integer.")
elif attr == "tempo":
if self.tempo.ndim != 1:
raise ValueError("`tempo` must be a 1D NumPy array.")
if self.tempo.ndim != 2:
raise ValueError("`tempo` must be a 2D NumPy array of shape (?,1)")
if np.any(self.tempo <= 0.0):
raise ValueError("`tempo` must contain only positive numbers.")
elif attr == "beat":
if self.beat.ndim != 1:
raise ValueError("`beat` must be a 1D NumPy array.")
elif attr == "downbeat":
if self.downbeat.ndim != 1:
raise ValueError("`downbeat` must be a 1D NumPy array.")
if self.downbeat.ndim != 2 or self.downbeat.shape[1] != 1:
raise ValueError("`downbeat` must be a 2D NumPy array of shape (?,1).")
elif attr == "tracks":
for track in self.tracks:
track.validate()
Expand Down
Loading