github.com/noriah/catnip@v1.8.5/input/input.go (about)

     1  package input
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  )
     7  
     8  type Device interface {
     9  	// String returns the device name.
    10  	String() string
    11  }
    12  
    13  type SessionConfig struct {
    14  	Device     Device
    15  	FrameSize  int     // number of channels per frame
    16  	SampleSize int     // number of frames per buffer write
    17  	SampleRate float64 // sample rate
    18  }
    19  
    20  // Session is the interface for an input session. Its task is to call the
    21  // processor everytime the buffer is full using the parameters given in
    22  // SessionConfig.
    23  type Session interface {
    24  	// Start blocks until either the context is canceled or an error is
    25  	// encountered.
    26  	Start(context.Context, [][]Sample, chan bool, *sync.Mutex) error
    27  }
    28  
    29  // Processor is called by Session everytime the buffer is full. Session may call
    30  // this on another goroutine; the implementation must handle synchronization. It
    31  // must also handle buffer swapping or copying if it wants to synchronize it
    32  // away.
    33  type Processor interface {
    34  	Process()
    35  }
    36  
    37  type Sample = float64
    38  
    39  // MakeBuffer allocates a slice of sample buffers.
    40  func MakeBuffers(channels, samples int) [][]Sample {
    41  	buf := make([][]Sample, channels)
    42  	for i := range buf {
    43  		buf[i] = make([]Sample, samples)
    44  	}
    45  	return buf
    46  }
    47  
    48  // EnsureBufferLen ensures that the given buffer has matching sizes with the
    49  // needed parameters from SessionConfig. It is effectively a bound check.
    50  func EnsureBufferLen(cfg SessionConfig, buf [][]Sample) bool {
    51  	if len(buf) != cfg.FrameSize {
    52  		return false
    53  	}
    54  	for _, samples := range buf {
    55  		if len(samples) != cfg.SampleSize {
    56  			return false
    57  		}
    58  	}
    59  	return true
    60  }
    61  
    62  // CopyBuffers deep copies src to dst. It does NOT do length check.
    63  func CopyBuffers(dst, src [][]Sample) {
    64  	frames := len(dst)
    65  	size := len(dst[frames-1]) * frames
    66  	for i := 0; i < size; i++ {
    67  		dst[i%frames][i/frames] = src[i%frames][i/frames]
    68  	}
    69  }