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 }