github.com/noriah/catnip@v1.8.5/catnip.go (about) 1 package catnip 2 3 import ( 4 "context" 5 "sync" 6 7 "github.com/noriah/catnip/input" 8 "github.com/noriah/catnip/processor" 9 10 "github.com/pkg/errors" 11 ) 12 13 const MaxChannelCount = 2 14 const MaxSampleSize = 2048 15 16 type SetupFunc func() error 17 type StartFunc func(ctx context.Context) (context.Context, error) 18 type CleanupFunc func() error 19 20 func Run(cfg *Config, ctx context.Context) error { 21 if err := cfg.Validate(); err != nil { 22 return err 23 } 24 25 inputBuffers := input.MakeBuffers(cfg.ChannelCount, cfg.SampleSize) 26 27 procConfig := processor.Config{ 28 SampleRate: cfg.SampleRate, 29 SampleSize: cfg.SampleSize, 30 ChannelCount: cfg.ChannelCount, 31 ProcessRate: cfg.ProcessRate, 32 Buffers: inputBuffers, 33 Analyzer: cfg.Analyzer, 34 Output: cfg.Output, 35 Smoother: cfg.Smoother, 36 Windower: cfg.Windower, 37 } 38 39 var vis processor.Processor 40 41 if cfg.UseThreaded { 42 vis = processor.NewThreaded(procConfig) 43 } else { 44 vis = processor.New(procConfig) 45 } 46 47 backend, err := input.InitBackend(cfg.Backend) 48 if err != nil { 49 return err 50 } 51 52 sessConfig := input.SessionConfig{ 53 FrameSize: cfg.ChannelCount, 54 SampleSize: cfg.SampleSize, 55 SampleRate: cfg.SampleRate, 56 } 57 58 if sessConfig.Device, err = input.GetDevice(backend, cfg.Device); err != nil { 59 return err 60 } 61 62 audio, err := backend.Start(sessConfig) 63 defer backend.Close() 64 65 if err != nil { 66 return errors.Wrap(err, "failed to start the input backend") 67 } 68 69 if cfg.SetupFunc != nil { 70 if err := cfg.SetupFunc(); err != nil { 71 return err 72 } 73 } 74 75 if cfg.CleanupFunc != nil { 76 defer cfg.CleanupFunc() 77 } 78 79 if cfg.StartFunc != nil { 80 if ctx, err = cfg.StartFunc(ctx); err != nil { 81 return err 82 } 83 } 84 85 kickChan := make(chan bool, 1) 86 mu := &sync.Mutex{} 87 88 ctx = vis.Start(ctx, kickChan, mu) 89 defer vis.Stop() 90 91 if err := audio.Start(ctx, inputBuffers, kickChan, mu); err != nil { 92 if !errors.Is(ctx.Err(), context.Canceled) { 93 return errors.Wrap(err, "failed to start input session") 94 } 95 } 96 97 return nil 98 }