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

101
LINES

< > BotCompany Repo | #1032981 // SlidingWindow - audio window with fixed size

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

Libraryless. Click here for Pure Java version (6459L/37K).

// We're a a bit confused about whether the time coordinates are double
// or int. (Probably int.)
persistable sclass SlidingWindow implements IAudioSample {
  // general params
  double sampleRate = 48000;
  int channels;
  
  // length of window
  int length;       // in samples per channel
  
  // start of window
  int start;
  
  // at which index in data array is our first value?
  int boundaryIndex; // in data
  
  // Here they are: the partial sums of the 16 bit audio samples
  // in an array of 6-byte integers. Channels are stored interleaved.
  HalfLongs data;
  
  // query original sound (channel, time -> short-range)
  IQuerySound sound;

  public double sampleRate() { ret sampleRate; }
  public int channels() { ret channels; }
  public DoubleRange bounds() { ret DoubleRange(start, start+length); }
  
  // Get an entry of the sum table - allow for out-of-bounds
  // requests (those just default to silence).
  @Override public double readSumTable(int channel, int i) {
    // do the first shift
    i -= start;
    
    ret getEntry(channel, i);
  }
  
  long getEntry(int channel, int i) {
    if (i < 0) ret 0;
    i = min(i, length-1);
    
    // do the second shift
    i = (i+boundaryIndex) % length;
    ret data.get(i*channels+channel);
  }
  
  void setEntry(int channel, int i, long l) {
    // do the shift
    i = (i+boundaryIndex) % length;
    data.set(i*channels+channel, l);
  }
  
  // constructor - perform integration of the raw audio data
  *(int *channels, double *sampleRate, IQuerySound *sound,
    int *start, int *length) {
    grab();
  }
  
  short getSample_short(int channel, double relTime) {
    ret clampToShort(iround(sound.getSample(channel, start+relTime)));
  }
  
  void grab {
    assertTrue(length > 0);
    if (l(data) != length*channels)
      data = new HalfLongs(length*channels);
    long[] sums = new[channels];
    for i to length:
      for c to channels:
        setEntry(c, i, sums[c] += getSample_short(c, i));
  }
  
  void moveTo(int newStart) {
    shiftRight(newStart-start);
  }
  
  void moveToCenter(int t) {
    moveTo(max(start, t-length/2));
  }
  
  void shiftRight(int n default 1) {
    if (n == 0) ret;
    assertTrue(n >= 0);
    
    int oldEnd = ifloor(end());
    start += n;
    boundaryIndex = mod(boundaryIndex+n, length);
    
    int overlap = max(0, oldEnd-ifloor(start));
    
    if (overlap == 0)
      grab();
    else
      for (int i = overlap; i < length; i++)
        try {
          for c to channels:
            setEntry(c, i, getEntry(c, i-1) + getSample_short(c, i));
        } on fail {
          printVars(+i, +start, +n, +length);
        }
  }
}

Author comment

Began life as a copy of #1032980

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1032981
Snippet name: SlidingWindow - audio window with fixed size
Eternal ID of this version: #1032981/42
Text MD5: 876fc4aa4bfa16d5e276b76c163fdf72
Transpilation MD5: f767beb45a6ed0458506970c42a03315
Author: stefan
Category: javax / audio analysis
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-10-18 05:27:51
Source code size: 2760 bytes / 101 lines
Pitched / IR pitched: No / No
Views / Downloads: 260 / 467
Version history: 41 change(s)
Referenced in: #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)