In [80]:
import os
import subprocess
import numpy as np
import pandas as pd
from supriya.tools import nonrealtimetools
from supriya.tools import soundfiletools
from supriya.tools import synthdeftools
from supriya.tools import ugentools

import hashlib
import math
import matplotlib.pyplot as plt
import scipy.special as sps
from scipy import stats
  1. Param builder
  2. Data structure mapping osc/aiff file name to parameters

In [3]:
def mtof(d):
    return 2.**((d-69.)/12.) * 440.

def ftom(f):
    return 69. + (12. * math.log2(f/440.))

In [172]:
def min_max_freq(size=1, lambda_=0.7):
    def min_gen(a):
        """Generate a random int between 0 & a (inclusive) of a 1-D array"""
        return np.random.randint(0, a+1, size=1)
    
    # Vectorize function so it can be applied to array
    min_func = np.vectorize(min_gen)
    
    octave_range = stats.planck.rvs(lambda_, size=size)
    note_range = np.random.randint(1, 13, size=size)
    total_range = np.clip(octave_range, 0, 8)*12 + note_range
    base_note = min_func(110-total_range)
    
    return np.append(mtof(base_note), mtof((base_note+total_range))).reshape(2, size).T

In [87]:
def gen_params(rows=1, lambda_=0.7, M=100, n=12, N=65):
    
    return np.concatenate([np.random.uniform(low=0.0001, high=1.0, size=4*rows).reshape(rows, 4),
                           np.random.randint(6, size=2*rows).reshape(rows, 2),
                           ((stats.hypergeom.rvs(M=M, n=n, N=N, size=1*rows))+4).reshape(rows, 1),
                           min_max_freq(size=rows, lambda_=lambda_),
                           (np.zeros(rows)+16).reshape(rows, 1)],
                          axis=1)

In [160]:
def format_params(param_mtx):
    
    cols = ('adparam', 'ampscale', 'ddparam', 'durscale', 'ampdist', 'durdist', 
            'knum', 'minfrequency', 'maxfrequency', 'init_cps')
    
    _df = pd.DataFrame(param_mtx, columns=cols)
    
    _df["hash"] = np.array([hashlib.md5(series.tostring()).hexdigest() for series in param_mtx])
    
    return _df

In [171]:
def make_builder(row):
    
    return synthdeftools.SynthDefBuilder(adparam=row["adparam"],
                                         ampdist=row["ampdist"],
                                         ampscale=row["ampscale"],
                                         ddparam=row["ddparam"],
                                         durdist=row["durdist"],
                                         durscale=row["durscale"],
                                         init_cps=row["init_cps"],
                                         knum=row["knum"],
                                         maxfrequency=row["maxfrequency"],
                                         minfrequency=row["minfrequency"],
                                        )

In [7]:
def make_out_dirs(path):
    if os.path.exists(path):
        of = os.path.join(path, "osc_files")
        af = os.path.join(path, "aif_files")
        os.makedirs(of, exist_ok=True)
        os.makedirs(af, exist_ok=True)
        return of, af
    else:
        return "{} does not exist".format(path)

In [8]:
def join_path_to_file(osc_p, aif_p, f):
    osc_fp = os.path.join(osc_p, f) + ".osc"
    aif_fp = os.path.join(aif_p, f) + ".aiff"
    return osc_fp, aif_fp

In [9]:
def make_osc_file(session, fpath):
    datagram = session.to_datagram()
    with open(fpath, 'wb') as file_pointer:
        file_pointer.write(datagram)

In [10]:
def make_cmd(osc_fp, aif_fp):
    return "scsynth -N {0} _ {1} 44100 AIFF int16 -o 1".format(osc_fp, aif_fp)

In [11]:
def render_session(session, out_dir, fname):
    osc_path, aif_path = make_out_dirs(out_dir)
    osc_fpath, aif_fpath = join_path_to_file(osc_path, aif_path, fname)
    make_osc_file(session, osc_fpath)
    bashCommand = make_cmd(osc_fpath, aif_fpath)
    process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
    output, error = process.communicate()
    return output, error

In [176]:
def build_out(builder):
    
    with builder:
        return ugentools.Out.ar(
            source=ugentools.Gendy1.ar(
                adparam=builder['adparam'],
                ampdist=builder['ampdist'],
                ampscale=builder['ampscale'],
                ddparam=builder['ddparam'],
                durdist=builder['durdist'],
                durscale=builder['durscale'],
                init_cps=builder['init_cps'],
                knum=builder['knum'],
                maxfrequency=builder['maxfrequency'],
                minfrequency=builder['minfrequency'],
            )
            )

In [173]:
pmtx = gen_params(rows=20)

In [174]:
df = format_params(pmtx)

In [186]:
df.sort_values(["hash"])


Out[186]:
adparam ampscale ddparam durscale ampdist durdist knum minfrequency maxfrequency init_cps hash
10 0.028068 0.995970 0.145464 0.363215 3.0 2.0 15.0 87.307058 103.826174 16.0 162a624b021a40f353a22168ea26c573
1 0.313963 0.105873 0.636145 0.472342 0.0 5.0 12.0 43.653529 51.913087 16.0 164800373deb0ad1d2bbfdb94f4e0c68
0 0.381463 0.337390 0.773213 0.446644 5.0 5.0 13.0 25.956544 30.867706 16.0 1807d611b652c7ed22b960540d3b1208
7 0.776254 0.270405 0.552245 0.480237 0.0 0.0 11.0 1244.507935 1975.533205 16.0 194e326892c603191a46c1e9b5d9faea
2 0.050123 0.281992 0.058949 0.837020 4.0 3.0 12.0 55.000000 97.998859 16.0 1aa932121587c599c9b45b143995bdbc
8 0.584941 0.838104 0.700391 0.206100 2.0 1.0 13.0 14.567618 138.591315 16.0 1f92aee8c888829a6980da6f213838a2
6 0.431908 0.522181 0.617156 0.474759 4.0 3.0 13.0 830.609395 4434.922096 16.0 23e420c533fecce8d39cbd32d2ed0eef
3 0.265873 0.499219 0.472424 0.698578 5.0 5.0 14.0 73.416192 783.990872 16.0 5647d587a3848107653ba97210749189
5 0.531921 0.697173 0.196447 0.670461 0.0 3.0 13.0 698.456463 1864.655046 16.0 7712a2c84fa6a0474ec1a6ec79c1effb
12 0.125951 0.142279 0.670690 0.823041 2.0 5.0 10.0 184.997211 369.994423 16.0 7dbc4c3eb03ad7b924577c4c9fa789ed
11 0.575554 0.485850 0.539237 0.712222 4.0 1.0 11.0 21.826764 58.270470 16.0 91fed4198e3f42277b23f0c115fac505
18 0.411067 0.962466 0.087907 0.708392 0.0 3.0 11.0 2093.004522 2959.955382 16.0 932e8686a54afc16ac78c6094bb0b456
15 0.619462 0.100370 0.889339 0.930125 0.0 3.0 14.0 415.304698 622.253967 16.0 9f3e97586114cdb9f21d74302d05763d
14 0.849473 0.881947 0.781403 0.937418 3.0 5.0 12.0 523.251131 659.255114 16.0 ab9619fb140244fa9c5ebae56bfadbdb
13 0.306299 0.814993 0.807425 0.427284 0.0 1.0 13.0 82.406889 164.813778 16.0 ce5578f60cb57caafc3b66f68ddec000
4 0.397122 0.101574 0.377121 0.084015 1.0 0.0 15.0 246.941651 1396.912926 16.0 ce9afe64b036aac1c5ee351a6e17a03a
16 0.153485 0.109522 0.148417 0.303177 5.0 3.0 14.0 116.540940 349.228231 16.0 d3ed351978f9da0ae0ab6001bf366de8
9 0.962524 0.528199 0.685752 0.013916 0.0 3.0 12.0 146.832384 329.627557 16.0 e123f943561e00ed40b4fa896e42f350
17 0.155471 0.107804 0.558315 0.745568 2.0 3.0 13.0 38.890873 97.998859 16.0 f57cba2ffa7049d403ba7d958bbcf9b9
19 0.176831 0.342760 0.171473 0.729278 2.0 3.0 12.0 12.978272 23.124651 16.0 f695b3972ff5bbc293793992406011da

In [192]:
def cp_to_sc(r):
    print("{}, {}, {}, {}, {}, {}, {}, {}, {}, {}".format(r["ampdist"],
                                                          r["durdist"],
                                                          r["adparam"],
                                                          r["ddparam"],
                                                          r["minfrequency"],
                                                          r["maxfrequency"],
                                                          r["ampscale"],
                                                          r["durscale"],
                                                          r["init_cps"],
                                                          r["knum"]))

In [193]:
cp_to_sc(df.iloc[1])


0.0, 5.0, 0.3139628495234624, 0.6361449935557908, 43.653528929125486, 51.91308719749314, 0.10587332198232761, 0.4723424139652405, 16.0, 12.0

In [187]:
this_dir = os.getcwd()

for i, row in df.iterrows():
    
    session = nonrealtimetools.Session()
    
    builder = make_builder(row)
    
    out = build_out(builder)
    
    synthdef = builder.build()
    
    with session.at(0):
        synth_a = session.add_synth(duration=10, synthdef=synthdef)
    
    render_session(session, this_dir, row["hash"])

In [ ]: