Skip to content

Commit

Permalink
download the bitKlavier dataset to do a polyphonic faust piano example (
Browse files Browse the repository at this point in the history
  • Loading branch information
DBraun authored Nov 11, 2021
1 parent 2adb477 commit cddfd14
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 50 deletions.
44 changes: 0 additions & 44 deletions .travis.yml

This file was deleted.

4 changes: 1 addition & 3 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@ authors:
given-names: "David"
orcid: "https://orcid.org/0000-0001-8866-0756"
title: "DawDreamer"
version: 0.5.7
date-released: 2021-09-12
url: "https://github.com/DBraun/DawDreamer/"
url: "https://github.com/DBraun/DawDreamer"
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def has_ext_modules(foo):
'Documentation': 'https://ccrma.stanford.edu/~braun/dawdreamer',
'Source': 'https://github.com/DBraun/DawDreamer',
},
version='0.5.7.9',
version='0.5.7.10',
author='David Braun',
author_email='[email protected]',
description='An audio-processing Python library supporting core DAW features',
Expand Down
3 changes: 2 additions & 1 deletion test-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
librosa>=0.8.1
numpy>=1.21.2
pytest>=6.2.4
scipy>=1.7.0
scipy>=1.7.0
requests
1 change: 1 addition & 0 deletions tests/assets/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bitKlavierGrand_PianoBar
Binary file not shown.
10 changes: 9 additions & 1 deletion tests/assets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@

[CC0 1.0 Universal (CC0 1.0)
Public Domain Dedication](https://creativecommons.org/publicdomain/zero/1.0/) applies to the following files:
* [60988__folktelemetry__crash-fast-14.wav](https://freesound.org/people/folktelemetry/sounds/60988/)
* [60988__folktelemetry__crash-fast-14.wav](https://freesound.org/people/folktelemetry/sounds/60988/)


[CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/) applies to the following files:
* [bitKlavierGrand_PianoBar](https://bitklavier.com/get/)


[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) applies to the following files:
* [MIDI-Unprocessed_SMF_02_R1_2004_01-05_ORIG_MID--AUDIO_02_R1_2004_05_Track05_wav.midi](https://magenta.tensorflow.org/datasets/maestro)
26 changes: 26 additions & 0 deletions tests/faust_dsp/soundfile_piano.dsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
declare name "MyInstrument";

declare options "[nvoices:8]"; // FaustProcessor has a property which will override this.
import("stdfaust.lib");

// variation of hs_phasor that doesn't loop. It's like a one-shot trigger.
my_phasor(inc,c) = inc*on_memory : + ~ (_*(1-start_pulse))
with {
is_on = c>0;

start_pulse = is_on & (1-is_on');
on_memory = is_on : max ~ (_*(1-start_pulse));
};

gain = hslider("gain",0.1,0,1,0.01); // note velocity
gate = button("gate"); // note on/off
key = hslider("freq", 60, 1, 127, 1) : ba.hz2midikey : _ , -21 : +;
// note that A0 is midi note 21, so we subtract 21 to get to 0 (the first file is named 0.wav)
release = hslider("release",0.1,0.,2.,0.001); // note release in seconds
envVol = en.adsr(0., 0., 1., release, gate);
safeKey = key : min(87) : max(0);
totalGain = gain * envVol * .5;

process = safeKey,my_phasor(1., gate):soundfile("mySound",2):!,!,_,_ : _*totalGain, _*totalGain;
// polyphonic DSP code must declare a stereo effect
effect = _, _;
64 changes: 64 additions & 0 deletions tests/scripts/bitKlavier_convert_piano_samples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# author: David Braun ([email protected])

import soundfile as sf
import pyrubberband as pyrb
import os.path

"""
This file takes the bitKlavier Grand Piano dataset and turns it into 88 wav files, named 0.wav through 87.wav.
You can customize a few parameters directly below:
"""

velocity = 'v8'
src_dir = 'E:/data/bitKlavierGrand_PianoBar_44k16b'
duration_seconds = 10.
output_dir = os.path.abspath('bitKlavierGrand_PianoBar_converted')

# No need to modify below here:

os.makedirs(output_dir, exist_ok=True)

pairs = [
('A0', 0), # A
('A0', 1), # A#
('C1', -1), # B
('C1', 0), # C
('C1', 1), # C#
('D#1', -1), # D
('D#1', 0), # D#
('D#1', 1), # E
('F#1', -1), # F
('F#1', 0), # F#
('F#1', 1), # G
('A1', -1), # G#
]

num_completed = 0
is_done = False
octave = 0

while not is_done:

for i, (input_note, shift) in enumerate(pairs):

note = input_note[:-1] + str(octave if i < 2 else octave + 1)

filepath = os.path.join(os.path.normpath(src_dir), f"{note}{velocity}.wav")
print(filepath)
y, sr = sf.read(filepath, always_2d=True)

y = y[:int(sr*(duration_seconds+1.)), :] # limit the time

y_stretch = pyrb.pitch_shift(y, sr, shift)

y_stretch = y_stretch[:int(sr*duration_seconds), :] # limit the time

output_filepath = os.path.join(output_dir, f"{num_completed}{velocity}.wav")
sf.write(output_filepath, y_stretch, sr)

num_completed += 1
is_done = num_completed >= 88
if is_done:
break

octave += 1
72 changes: 72 additions & 0 deletions tests/test_faust_soundfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,78 @@ def _test_faust_soundfile(sample_seq, output_path, sound_choice=0):
audio = engine.get_audio()
assert(np.mean(np.abs(audio)) > .01)

def download_grand_piano():

"""Download the dataset if it's missing"""

try:

file_paths = [f"assets/bitKlavierGrand_PianoBar/{i}v8.wav" for i in range(88)]

import os.path

if os.path.isfile(file_paths[0]):
return

bitKlavierURL = 'https://ccrma.stanford.edu/~braun/assets/bitKlavierGrand_PianoBar.zip'
import requests

# download the file contents in binary format
print(f'Downloading: {bitKlavierURL}')
r = requests.get(bitKlavierURL)

path_to_zip_file = abspath("assets/bitKlavierGrand_PianoBar.zip")
with open(path_to_zip_file, "wb") as zip:
zip.write(r.content)

import zipfile
with zipfile.ZipFile(path_to_zip_file, 'r') as zip_ref:
zip_ref.extractall("assets")

os.remove(path_to_zip_file)

except Exception as e:
print('Something went wrong downloading the bitKlavier Grand Piano data.')
raise e


def test_faust_soundfile_piano():

download_grand_piano()

engine = daw.RenderEngine(SAMPLE_RATE, BUFFER_SIZE)

faust_processor = engine.make_faust_processor("faust")
faust_processor.num_voices = 16
faust_processor.group_voices = True

dsp_path = abspath("faust_dsp/soundfile_piano.dsp")

# set_soundfiles
soundfiles = {
'mySound': [load_audio_file(f"assets/bitKlavierGrand_PianoBar/{i}v8.wav") for i in range(88)]
}
faust_processor.set_soundfiles(soundfiles)

assert(faust_processor.set_dsp(dsp_path))
assert(faust_processor.compile())
# desc = faust_processor.get_parameters_description()
# for par in desc:
# print(par)

midi_path = 'MIDI-Unprocessed_SMF_02_R1_2004_01-05_ORIG_MID--AUDIO_02_R1_2004_05_Track05_wav.midi'
faust_processor.load_midi(abspath(f'assets/{midi_path}'))

graph = [
(faust_processor, [])
]

assert(engine.load_graph(graph))
render(engine, file_path='output/test_sound_file_piano.wav', duration=10.)

audio = engine.get_audio()
assert(np.mean(np.abs(audio)) > .0001)


def test_faust_soundfile_cymbal():
# Load a stereo audio sample and pass it to Faust
Expand Down

0 comments on commit cddfd14

Please sign in to comment.