Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

133
LINES

< > BotCompany Repo | #1033273 // ContinuousOscillators_TestAudioRestoration_v2

JavaX fragment (include) [tags: use-pretranspiled]

Uses 11894K of libraries. Click here for Pure Java version (20559L/135K).

sclass ContinuousOscillators_TestAudioRestoration_v2 {
  S audioURL = "https://mouth.gazelle.rocks/beaHTML/15/5502%2Frecognize+-+61351880347bd84b28c7f42d779cde94.mp3";

  short[] inputSamples;
  double inputSampleRate = 48000;

  settable bool separateFrequencies;
  settable bool cumulative;
  settable bool subtractive;
  settable bool separateRealAndImag;
  settable bool playRestored;
  settable bool showImage;
  settable bool printAllIntensities;
  bool useInputSampleRate = true;
  double silence = 0.2;
  double minFreq = 0, maxFreq = 48000;
  int useEveryNthOscillator = 1;
  
  short[] resampled;
  new L<double[]> audioOutput;
  File wavOut;
  
  new ContinuousOscillators_v2 co;

  void loadAudioURL {
    File mp3 = loadBinaryPageOnce(audioURL);
    loadMP3(mp3);
  }
  
  void loadMP3(File mp3) {
    printFileInfo(+mp3);
    File wav = mp3ToWAVUnlessExists(mp3, replaceExtension(mp3, ".mp3", ".wav"));
    loadWAV(wav);
  }
   
  void loadWAV(File 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<double[]> soundSource) {
    inputSamples = concatShortArrays(soundSourceToShortArrays(seconds, soundSource, 1));
    print(inputSamples := sfu(takeFirst(10, inputSamples));
  }
  
  run {
    if (useInputSampleRate) co.sampleRate = inputSampleRate;
    resampled = convertSampleRate_shortArray_simple(inputSampleRate, co.sampleRate, inputSamples);
    print(samples := l(resampled));
    
    co.setAudio(new StaticAudioSample(ll(resampled), 1, co.sampleRate));

    if (subtractive) co.onEscalating(o -> {
      print("Escalating " + o);
      var data = co.subtractedAudio.toDoubleArray();
      audioOutput.add(data);
      print("Got samples: " + l(data));
    });

    // START CALCULATION
    co.stepTo(co.audio.bounds());
    
    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);
      if (playRestored) playWAV(wavOut);
    }
    
    print(audioNorm := sfu(takeFirst(10, audioNorm));
    
    double pixelsPerSecond = 100;
    if (showImage)
      dm_showPixelatedImage(co.image(co.audio.bounds(), pixelsPerSecond));
  }
  
  void restoreAudio {
    L<ContinuousOscillators_v2.Oscillator> oscillators = new L;
    //double ratio = 2; // octave
    int nOscillators = l(co.oscillators);
    var lOsc = asList(co.oscillators);
    
    for i to nOscillators: {
      if ((i % useEveryNthOscillator) == 0)
        oscillators.add(lOsc.get(i));
    }
    
    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");
      double[] cum = null;
      
      for (o : oscillators) {
        if (printAllIntensities) pnl(map(o.intensities, (k, v) ->
          o.frequency() + " " + formatDouble(k, 1) + " = " + renderComplexWithAngle(div(v.first(), l(k)*32767))));
        //co.toAudio_shouldPrint = (i, n) -> i < 30 || i >= n-10;
        for (xx : separateRealAndImag ? ll(1, 2) : ll(0)) {
          co.realOnly = (xx & 1) != 0;
          co.imagOnly = (xx & 2) != 0;
          double[] newAudio = co.toAudio(ifloor(co.audio.bounds()), ll(o));
          /*if (subtractive) {
            audioOutput.add(co.subtractedAudio.toDoubleArray());
          } else*/ {
            if (cumulative) cum = newAudio = doubleAdd(cum, newAudio);
            audioOutput.add(newAudio); 
            audioOutput.add(repDouble(iround(co.sampleRate*silence), 0));
          }
          
          co.toAudio_shouldPrint = null;
          co.realOnly = co.imagOnly = false;
        }
      }
    }
      
    audioOutput.add(co.toAudio(ifloor(co.audio.bounds()), oscillators));
  }
}

Author comment

Began life as a copy of #1033253

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033273
Snippet name: ContinuousOscillators_TestAudioRestoration_v2
Eternal ID of this version: #1033273/16
Text MD5: 46f245a9b45cd191fb4d20f1b01a71ff
Transpilation MD5: d68b0626a7fbbd6ba251539274254082
Author: stefan
Category: javax / speech
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-10-18 08:50:13
Source code size: 4515 bytes / 133 lines
Pitched / IR pitched: No / No
Views / Downloads: 175 / 305
Version history: 15 change(s)
Referenced in: #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)