package revid import ( "bytes" "errors" "io/ioutil" "testing" "time" "bitbucket.org/ausocean/av/codec/lex" "github.com/yobert/alsa" ) // Check that a device exists with the given config parameters. func checkDevice(ac *AudioConfig) error { cards, err := alsa.OpenCards() if err != nil { return errors.New("no audio cards found") } defer alsa.CloseCards(cards) var testDev *alsa.Device for _, card := range cards { devices, err := card.Devices() if err != nil { continue } for _, dev := range devices { if dev.Type != alsa.PCM || !dev.Record { continue } testDev = dev break } } if testDev == nil { return errors.New("no suitable device found") } err = testDev.Open() if err != nil { return err } _, err = testDev.NegotiateChannels(2) if err != nil { return err } foundRate := false for i := 0; i < len(Rates) && !foundRate; i++ { if Rates[i] < ac.SampleRate { continue } if Rates[i]%ac.SampleRate == 0 { _, err = testDev.NegotiateRate(Rates[i]) if err == nil { foundRate = true } } } if !foundRate { _, err = testDev.NegotiateRate(defaultSampleRate) if err != nil { return err } } var aFmt alsa.FormatType switch ac.BitDepth { case 16: aFmt = alsa.S16_LE case 32: aFmt = alsa.S32_LE default: return errors.New("unsupported bitdepth") } _, err = testDev.NegotiateFormat(aFmt) if err != nil { return err } _, err = testDev.NegotiateBufferSize(8192, 16384) if err != nil { return err } if err = testDev.Prepare(); err != nil { return err } if testDev != nil { testDev.Close() } return nil } func TestAudio(t *testing.T) { // We want to open a device with a standard configuration. ac := &AudioConfig{ SampleRate: 8000, Channels: 1, RecPeriod: 1, BitDepth: 16, Codec: ADPCM, } // Skip if there are no suitable devices to test with. err := checkDevice(ac) if err != nil { t.Error(err) } // Create a new audioDevice, start, read/lex, and then stop it. ai, err := NewAudioDevice(ac) if err != nil { t.Error(err) } dst := bytes.NewBuffer(make([]byte, 0)) err = ai.Start() if err != nil { t.Error(err) } num := 3 // How many 'ac.RecPeriod's to record. go lex.ADPCM(dst, ai, time.Duration(ac.RecPeriod*float64(time.Second)), ai.ChunkSize()) time.Sleep(time.Millisecond * 1000 * time.Duration(num)) ai.Stop() err = ioutil.WriteFile("./testout", dst.Bytes(), 0644) }