diff options
Diffstat (limited to 'wav')
| -rw-r--r-- | wav/wav.go | 63 | ||||
| -rw-r--r-- | wav/wav_test.go | 2 |
2 files changed, 47 insertions, 18 deletions
@@ -5,49 +5,78 @@ package wav import "C" import ( "fmt" + + "github.com/op/go-logging" + "layeh.com/gopus" ) -const batchSize = 64 +// number of individual samples per batch (counting all channels) +const samplesPerBatch = 1920 + +var log = logging.MustGetLogger("wav") -func Load(filename string) (<-chan [2]int16, error) { +func Load(filename string) (<-chan []byte, <-chan struct{}, error) { cfname := C.CString(filename) wav := C.drwav_open_file(cfname) if wav == nil { - return nil, fmt.Errorf("Unable to initialize drwav.") + return nil, nil, fmt.Errorf("Unable to initialize drwav.") } if int(wav.channels) != 2 { C.drwav_close(wav) - return nil, fmt.Errorf("Wrong number of channels!") + return nil, nil, fmt.Errorf("Wrong number of channels!") } - if int(wav.sampleRate) != 44100 { + if int(wav.sampleRate) != 48000 { C.drwav_close(wav) - return nil, fmt.Errorf("Wrong sample rate.") + return nil, nil, fmt.Errorf("Wrong sample rate.") } - ch := make(chan [2]int16, 1024*32) + ch := make(chan []byte, 1024*32) + enc, err := gopus.NewEncoder(int(wav.sampleRate), int(wav.channels), gopus.Audio) + if err != nil { + return nil, nil, err + } + doneCh := make(chan struct{}) + encoderCh := make(chan []int16, 2*48000*2) go func() { - buf := C.malloc(C.size_t(batchSize * wav.bytesPerSample)) + buf := C.malloc(C.size_t(samplesPerBatch * wav.bytesPerSample)) defer C.free(buf) defer C.drwav_close(wav) - for i := 0; i < int(wav.totalSampleCount)/batchSize; i++ { - readSamples := C.drwav_read_s16(wav, batchSize, (*C.dr_int16)(buf)) - + for i := 0; i < (int(wav.totalSampleCount)/samplesPerBatch)+1; i++ { + readSamples := C.drwav_read_s16(wav, samplesPerBatch, (*C.dr_int16)(buf)) slc := (*[1 << 30]int16)(buf)[:readSamples:readSamples] - for i := 0; i < int(readSamples); i += 2 { - ch <- [2]int16{slc[i], slc[i+1]} - } + encoderCh <- slc - if readSamples < batchSize { + if readSamples < samplesPerBatch { break } } - close(ch) + close(encoderCh) }() - return ch, nil + go func(channels int) { + elems := []int16{} + for v := range encoderCh { + elems = append(elems, v...) + + if len(elems) > samplesPerBatch*channels { + opus, err := enc.Encode(elems[:samplesPerBatch*channels], samplesPerBatch, samplesPerBatch*channels*2) + elems = elems[samplesPerBatch*channels:] + if err != nil { + log.Errorf("Error encoding opus audio: %q", err) + continue + } + ch <- opus + } + } + + close(ch) + close(doneCh) + }(int(wav.channels)) + + return ch, doneCh, nil } diff --git a/wav/wav_test.go b/wav/wav_test.go index a641b8f..5d6bef7 100644 --- a/wav/wav_test.go +++ b/wav/wav_test.go @@ -8,7 +8,7 @@ import ( func TestLoad(t *testing.T) { ch, err := Load("../downloader/out.wav") if err != nil { - t.Error(err) + t.Fatal(err) } ct := 0 |
