sclass ContinuousOscillators_TestAudioRestoration { //S audioURL = "https://mouth.gazelle.rocks/beaHTML/15/5502%2Frecognize+this+-+a8528bcbf1dc96d0da768ed6778373f4.mp3"; S audioURL = "https://mouth.gazelle.rocks/beaHTML/15/5502%2Frecognize+-+61351880347bd84b28c7f42d779cde94.mp3"; //S audioURL = "https://mouth.gazelle.rocks/beaHTML/15/5502%2Fhello+hello+hello+-+667a6d14b2dc154feac362ddad4d4ca8.mp3"; short[] inputSamples; double inputSampleRate = 48000; settable bool separateFrequencies; double silence = 0.2; new L audioOutput; File wavOut; new ContinuousOscillators co; void loadAudioURL { File mp3 = loadBinaryPageOnce(audioURL); printFileInfo(+mp3); File wav = mp3ToWAVUnlessExists(mp3, appendToFileName(mp3, ".wav")); playWAV(wav); printFileInfo(+wav); wavOut = appendToBaseFileName(wav, ".restored"); temp WAVDecoder decoder = new(wav); print(sampleRate := decoder.sampleRate); int n = decoder.totalValues(); inputSamples = decodeWAVToMonoSamples(decoder, n); inputSampleRate = decoder.sampleRate; } // assumes soundSource is using the default inputSampleRate void setAudio(double seconds, VF1 soundSource) { inputSamples = concatShortArrays(soundSourceToShortArrays(seconds, soundSource, 1)); print(inputSamples := sfu(takeFirst(10, inputSamples)); } run { short[] samples2 = convertSampleRate_shortArray_simple(inputSampleRate, co.sampleRate, inputSamples); print(samples := l(samples2)); IQuerySound sound = shortSamplesToQuerySound(samples2); co.setAudio(new StaticAudioSample(ll(samples2), 1, co.sampleRate)); co.makeFullWindow(sound); print(windowBounds := co.windowBounds()); co.startOscillators(); co.stepTo(co.windowBounds()); print(coverageByFreq := co.coverageByFreq()); restoreAudio(); double[] audio = concatDoubleArrays(audioOutput); double[] audioNorm = normalizeDoubles(audio, 32767); if (wavOut != null) { shortArrayToMonoWAVE(doubleToShortArray_iround(audioNorm), wavOut, co.sampleRate); printFileInfo(+wavOut); playWAV(wavOut); } print(audioNorm := sfu(takeFirst(10, audioNorm)); double pixelsPerSecond = 100; //ret co.imageForWindow(pixelsPerSecond); } void restoreAudio { L oscillators = new L; //double ratio = 2; // octave int nOscillators = l(co.oscillators); var lOsc = asList(co.oscillators); for i to nOscillators: { if ((i % 12) == 0) oscillators.add(lOsc.get(i)); } double minFreq = 0, maxFreq = 48000; oscillators = filter(oscillators, o -> between(o.frequency()!, minFreq, maxFreq)); print("Using " + nFrequencies(oscillators) + ": " + map(oscillators, o -> formatDouble(o.frequency()!, 1)); if (separateFrequencies) { wavOut = appendToBaseFileName(wavOut, ".separate"); for (o : oscillators) { audioOutput.add(co.toAudio(ifloor(co.windowBounds()), ll(o))); audioOutput.add(repDouble(iround(co.sampleRate*silence), 0)); } } audioOutput.add(co.toAudio(ifloor(co.windowBounds()), oscillators)); } }