Skip to content

Instantly share code, notes, and snippets.

@bmcfee
Created December 14, 2016 16:37
Show Gist options
  • Select an option

  • Save bmcfee/2138a281f01f77b6b548d1808fd9b2bd to your computer and use it in GitHub Desktop.

Select an option

Save bmcfee/2138a281f01f77b6b548d1808fd9b2bd to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import os"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"os.environ['MEDLEYDB_PATH'] = '/home/bmcfee/data/MedleyDB/'"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import jams\n",
"import jams.display\n",
"import matplotlib.pyplot as plt\n",
"%matplotlib nbagg"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from IPython.display import Audio"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import medleydb\n",
"import medleydb.mix"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from joblib import Parallel, delayed"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def encode_intervals(times, values, threshold=0.5):\n",
" \n",
" # times is an array of frame times\n",
" # values are the observed activations per frame\n",
" \n",
" # Threshold the activations\n",
" v_t = values >= threshold\n",
" \n",
" on = False\n",
" \n",
" for t, v in zip(times, v_t):\n",
" if v and not on:\n",
" on = v\n",
" start = t\n",
" elif on and not v:\n",
" on = False\n",
" yield dict(time=start, duration=t-start)\n",
" if on:\n",
" yield dict(time=start, duration=t-start)\n",
" \n",
"def jam_out(mtrack, output_path, stem_indices=None):\n",
" \n",
" if stem_indices is None:\n",
" stem_indices = list(mtrack.stems.keys())\n",
" \n",
" meta = jams.FileMetadata(title=mtrack.title, artist=mtrack.artist, duration=mtrack.duration)\n",
" jam = jams.JAMS(file_metadata=meta)\n",
" ann = jams.Annotation('tag_medleydb_instruments', duration=mtrack.duration)\n",
" \n",
" time_act = np.asarray(mtrack.stem_activations).T\n",
" \n",
" time = time_act[0]\n",
" \n",
" for stem in stem_indices:\n",
" tag = mtrack.stems[stem].instrument\n",
" if tag not in jams.schema.values(ann.namespace):\n",
" continue\n",
" \n",
" if stem not in mtrack.stem_activations_idx:\n",
" continue\n",
" \n",
" row = mtrack.stem_activations_idx[stem]\n",
" \n",
" for obs in encode_intervals(time, time_act[row], threshold=0.5):\n",
" ann.append(time=obs['time'], duration=obs['duration'], value=tag, confidence=None)\n",
" \n",
" jam.annotations.append(ann)\n",
" \n",
" jam.save(output_path)"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def mix_out(mtrack, instruments, output_prefix, ext='ogg', redo=True):\n",
" \"\"\"Remixes a multitrack with anything type of vocals removed.\n",
" If no vocals are present, the mix will be a simple weighted linear remix.\n",
"\n",
" Parameters\n",
" ----------\n",
" mtrack : Multitrack\n",
" Multitrack object\n",
" output_prefix : str\n",
" Prefix to save output file.\n",
"\n",
" Returns\n",
" -------\n",
" stem_indices : list\n",
" List of stem indices used in mix.\n",
"\n",
" \"\"\"\n",
" \n",
" # What instrumenst are in this mix?\n",
" mix_instruments = set([stem.instrument for stem in mtrack.stems.values()])\n",
" \n",
" \n",
" # For each instrument we care about modeling,\n",
" # generate a mix with that instrument removed\n",
" loop_set = mix_instruments & set(instruments)\n",
"\n",
" # We'll throw in a null-subtraction just to keep a full mix in with the rest\n",
" for inst in loop_set | set(['']):\n",
" \n",
" stem_indices = [idx for idx in mtrack.stems if mtrack.stems[idx].instrument != inst]\n",
"\n",
" # If there's nothing left, we're done\n",
" if not stem_indices:\n",
" break\n",
" \n",
" # Make the multitrack output\n",
" output_path = '{}---{}{}{}'.format(output_prefix, inst, os.path.extsep, ext)\n",
" if redo or not os.path.exists(output_path):\n",
" medleydb.mix.mix_multitrack(mtrack, output_path, stem_indices=stem_indices)\n",
" \n",
" # Make the annotation\n",
" output_path = '{}---{}{}{}'.format(output_prefix, inst, os.path.extsep, 'jams')\n",
" jam_out(mtrack, output_path, stem_indices=stem_indices)"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def tmo(track_id, instruments, outpath, redo=False):\n",
" mt = medleydb.MultiTrack(track_id)\n",
" mix_out(mt, instruments, '{}/{}'.format(outpath, mt.track_id), redo=redo)"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# The top-14 instruments, except for synth\n",
"INSTRUMENTS = [ 'drum set',\n",
" 'electric bass',\n",
" 'piano',\n",
" 'male singer',\n",
" 'clean electric guitar',\n",
" 'vocalists',\n",
" 'female singer',\n",
" 'acoustic guitar',\n",
" 'distorted electric guitar',\n",
" 'auxiliary percussion',\n",
" 'double bass',\n",
" 'violin',\n",
" 'cello',\n",
" 'flute']\n"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"[Parallel(n_jobs=23)]: Done 4 tasks | elapsed: 4.3s\n",
"[Parallel(n_jobs=23)]: Done 122 out of 122 | elapsed: 1.4min finished\n"
]
},
{
"data": {
"text/plain": [
"[None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None,\n",
" None]"
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Parallel(verbose=1, n_jobs=23)(delayed(tmo)(track_id, INSTRUMENTS, '/home/bmcfee/working/Medleydb_Downmix/')\n",
" for track_id in medleydb.TRACK_LIST)"
]
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python [conda env:py35]",
"language": "python",
"name": "conda-env-py35-py"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment