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

82
LINES

< > BotCompany Repo | #1018247 // recordToAudioListeners

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

Libraryless. Click here for Pure Java version (3021L/20K).

// TODO: copy buffers less (have multiple listeners keep buffers without copying)

static recordToAudioListeners_AudioLoop recordToAudioListeners(L<VF1<short[]>> audioListeners, int bufSize, SimpleLiveValue<Float> lvVolume) {
  recordToAudioListeners_AudioLoop loop = new(bufSize);
  loop.audioListeners = audioListeners;
  loop.lvVolume = lvVolume;
  ret loop;
}

static recordToAudioListeners_AudioLoop recordToAudioListeners(L<VF1<short[]>> audioListeners, int bufSize, SimpleLiveValue<Float> lvVolume, AudioFormat quality) {
  recordToAudioListeners_AudioLoop loop = new(bufSize, quality);
  loop.audioListeners = audioListeners;
  loop.lvVolume = lvVolume;
  ret loop;
}

sclass recordToAudioListeners_AudioLoop extends Thread implements AutoCloseable {
  TargetDataLine line;
  new Flag stopFlag;
  byte[] buf;
  short[] convertedBuf;
  L<VF1<short[]>> audioListeners;
  SimpleLiveValue<Float> lvVolume;
  AudioFormat quality;
  bool cloneDataOnce;
  bool verbose;
  O currentListener; // who is holding up audio processing

  *(int bufSize) {
    this(bufSize, javaSound_cdQuality());
  }
  
  *(int bufSize, AudioFormat *quality) {
    line = javaSound_recordLine(quality, bufSize);
    buf = new byte[bufSize];
    convertedBuf = new short[bufSize/2];
  }
  
  public void start { line.start°; super.start°; }
  void stopRecording { // "stop()" was taken
    if (stopFlag.isUp()) ret;
    stopFlag.raise°; line.close°;
    print("Audio input loop stopped.");
  }
  public void close { stopRecording(); }
  
  public void run° {
    print("Audio input loop started. Buffer size=" + l(buf) + " (" + iround(l(buf)/quality.getSampleRate()/quality.getFrameSize()*1000) + " ms)");
    
    while (licensed() && !stopFlag.isUp()) {
      int n = line.read(buf, 0, l(buf));
      if (stopFlag.isUp()) break;
      if (n < l(buf)) print("Weird: Got less than a buffer: " + n + "/" + l(buf));
      if (n == 0) ret with print("EMERGENCY STOP.");
      handleData(buf, n);
    }
  }
  
  void handleData(byte[] data, int n) {
    if (verbose) printWithMilliseconds("Handling audio data (" + nBytes(n) + ")");
    pcall {
      bytesToShorts_littleEndian(data, convertedBuf, n);
      short[] convertedData = subShortArray(convertedBuf, 0, n/2);
      lvSet(lvVolume, shortSamplesToPercentVolume(convertedData));
  
      if (cloneDataOnce)
        convertedData = cloneShortArray(convertedData);
        
      for i over audioListeners: { // synchro-safe, garbage-free iteration
        VF1<short[]> l = syncGet(audioListeners, i);
        continue if l == null;
        try {
          currentListener = l;
          pcallF(l, convertedData);
        } finally {
          currentListener = null;
        }
      }
    }
    if (verbose) printWithMilliseconds("Done handling audio data");
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1018247
Snippet name: recordToAudioListeners
Eternal ID of this version: #1018247/17
Text MD5: 7aaf5ab1917939b27358baec0eb36a94
Transpilation MD5: 18e80dd45e2e973d0c339faac4ce805f
Author: stefan
Category: javax / audio
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2020-02-15 14:03:10
Source code size: 2880 bytes / 82 lines
Pitched / IR pitched: No / No
Views / Downloads: 453 / 576
Version history: 16 change(s)
Referenced in: #1006654 - Standard functions list 2 (LIVE, continuation of #761)
#1027052 - AudioInputDispatcher