music.profile¶
- music.profile(adict, sample_rate=44100)[source]¶
Summarize a namespace of variables.
Sorts the names by what they hold, measures every array in it, and reads each array as PCM samples or as parametrisation. Written for looking at a piece of synthesis code mid-flight: hand it
locals()and it says which of the names are sounds, how long each is, and which of the numbers look like frequencies, decibels or pitches.- Parameters:
- Returns:
dictd['type']sorts the names:'scalar'for numbers and strings,'collections'for dicts, lists, sets and arrays, and'other'for everything else.d['analyses']['ndarray']maps each array name to its measurements –shape,samples,secondsat sample_rate,mean,mean_square,rms,minimum,maximum, and the mean and standard deviation of the RMS taken block by block, whose spread is what discontinuity shows up in.d['guesses']maps the same names to readings of those measurements, each a(reading, reason)pair.
See also
amp_to_dbthe conversion the decibel reading above is about.
hz_to_midithe conversion the pitch reading is about.
Notes
The measurements are measurements; the guesses are guesses, which is why they are kept apart. A guess carries the reason that produced it so that a caller can disagree with it:
A large array whose mean sits at zero and whose values are bounded by 1 or by a power of two is read as PCM samples.
A short array with an offset mean is read as parametrisation – values meant to be used rather than heard, often driving a rhythm.
Values reaching into the hundreds are read as frequencies in Hz.
Values within [0, 150] are read as MIDI pitches or semitone intervals when they are integers or move in steps under 10, and as decibels when they move in steps of tens.
This function used to raise
NotImplementedError: its body had been a commented-out sketch since it was written, and the docstring above was a specification rather than a description. It is now the second of these.Examples
>>> sound = np.sin(2 * np.pi * 440 * np.arange(88200) / 44100) >>> summary = profile({'s': sound, 'freqs': np.array([220., 440.])}) >>> sorted(summary['type']['collections']) ['freqs', 's'] >>> summary['analyses']['ndarray']['s']['seconds'] 2.0 >>> [reading for reading, _reason in summary['guesses']['s']] ['pcm samples']