Warning: session_start(): open(/var/lib/php/sessions/sess_fekboq4s3168689ncu4uotv9dq, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
sclass PianoSampler {
macro dprint { if (debug) printVars } bool debug;
int channels = 1;
double sampleRate = 48000;
double currentSample;
IQuerySound sound;
IAudioSample audio;
SlidingWindow window;
long haarFeaturesChecked;
persistable class Oscillator extends HasKey {
double currentPeriodStart;
// all recorded intensities
new TreeMap> intensities;
double interval; // in samples
*(Frequency f) {
super(f);
interval = frequency().interval()*sampleRate;
}
Frequency frequency() { ret key(); }
double interval() { ret interval; }
void record_impl(DoubleRange r, Channels c) {
intensities.put(r, c);
}
void advancePeriodToRange(DoubleRange timeRange) {
double end = currentPeriodStart + interval;
int phaseShifts = ifloor((timeRange.start-end)/interval);
if (phaseShifts = 0) ret;
setStart(currentPeriodStart + phaseShifts*interval);
}
// we span a total range of interval*1.25 because of the sin/cos thing
void measure(DoubleRange timeRange) {
DoubleRange p1 = doubleRangeWithLength(phaseMinus90(), interval);
p1 = intersectDoubleRanges(p1, timeRange);
double re = 0;
if (!isEmpty(p1)) {
AudioHaarFeature haar = new(audio, p1);
re = haar!;
}
DoubleRange p2 = doubleRangeWithLength(currentPeriodStart, interval);
p2 = intersectDoubleRanges(p2, timeRange);
double im = 0;
if (!isEmpty(p2)) {
AudioHaarFeature haar = new(audio, p2);
im = haar!;
}
record(this, p1 /*TODO*/, complexChannels(re, im));
haarFeaturesChecked += 2;
}
void dropMeasurementsLeftOf(double t) {
while ping (true) {
var r = firstKey(intensities);
if (r != null && r.end() <= t)
popFirst(intensities);
else
break;
}
}
void initial(double currentSample) {
setStart(currentSample + startPhase());
}
void moveTo(double time) {
currentPeriodStart = time;
double next = phase360();
dprint("relocate", +this, +next);
completionsForSample.put(next, this);
}
double startPhase() { ret phase90(); }
double quarterPhase() { ret interval()*.25; }
double phaseMinus90() { ret currentPeriodStart - interval()*.25; }
double phase0() { ret currentPeriodStart; }
double phase90() { ret currentPeriodStart + interval()*.25; }
double phase180() { ret currentPeriodStart + interval()*.5; }
double phase270() { ret currentPeriodStart + interval()*.75; }
double phase360() { ret currentPeriodStart + interval(); }
double phase450() { ret currentPeriodStart + interval()*1.25; }
} // end of Oscillator
TreeHasKeyMap oscillators = new TreeHasKeyMap(map(f -> new Oscillator(f), pianoFrequencies88()));
new TreeMultiMap completionsForSample;
*() {}
*(IAudioSample audio, double *currentSample) { setAudio(audio); }
*(IAudioSample audio) { setAudio(audio); } // start at time 0
void setAudio(IAudioSample audio) {
this.audio = audio;
window = optCast SlidingWindow(audio);
}
void verboseOnRecordAdded() {
onRecordAdded(lambda1 print);
}
int nFrequencies() {
ret oscillators.size();
}
void startOscillators {
for (o : oscillators)
o.initial(currentSample);
}
void stepTo(DoubleRange timeRange) {
while ping (true) {
Double t = firstKey(completionsForSample);
if (t != null && t <= time) {
var list = completionsForSample.getAndClear(t);
dprint(+t, +list);
for (Oscillator o : list) {
o.measure(timeRange);
o.relocate(t);
}
} else
break;
}
}
void record(Oscillator o, DoubleRange r, Channels c) {
if (o == null) ret;
o.record_impl(r, c);
onRecordAdded(new RecordAdded(o, r, c));
}
record RecordAdded(Oscillator oscillator, DoubleRange period, Channels intensity) {}
transient event interface OnRecordAdded as onRecordAdded shipping RecordAdded;
Frequency lowestFrequency() { ret oscillators.firstKey(); }
Frequency highestFrequency() { ret oscillators.lastKey(); }
int minWindowSize() {
ret iceil(sampleRate*lowestFrequency().interval());
}
void makeSmallestWindow(IQuerySound sound) {
this.sound = sound;
setAudio(new SlidingWindow(channels, sampleRate, sound, 0, minWindowSize());
}
double windowSize() {
ret window.length();
}
S stats() { ret renderVars(+audio, +haarFeaturesChecked); }
IIntegralImage imageColumn(DoubleRange timeRange) {
int n = nFrequencies();
var l = reversedList(oscillators);
double[] col = new[n];
for y to n: {
var l2 = l.get(y).intensities;
new Average avg;
forEach(l2, (r, val) -> {
double amplitude = val.first().abs();
// if only a part is in the time range
double actualDuration = l(intersectDoubleRanges(r, timeRange));
avg.add(amplitude, actualDuration);
});
col[y] = avg!;
}
double[] col2 = normalizeDoubles(col, 255);
ret bwIntegralImageFromFunction(1, n, (x, y) -> ifloor(col2[y]));
}
// how much horizontal area have we covered
L coverageByFreq() {
ret mapReversed(oscillators, o -> totalLengthOfDoubleRanges(keys(o.intensities)));
}
void stepRight(double shift) {
assertNotNull(+window);
var r = window.bounds();
window.shiftRight(max(1, ifloor(shift)));
for (o : oscillators) o.dropMeasurementsLeftOf(window.start());
stepTo(window.end());
}
}