diff options
Diffstat (limited to 'wav/wav.go')
| -rw-r--r-- | wav/wav.go | 140 |
1 files changed, 0 insertions, 140 deletions
diff --git a/wav/wav.go b/wav/wav.go deleted file mode 100644 index acd7841..0000000 --- a/wav/wav.go +++ /dev/null @@ -1,140 +0,0 @@ -package wav - -// #define DR_WAV_IMPLEMENTATION -// #include "dr_wav.h" -import "C" -import ( - "fmt" - - "sync" - - "github.com/op/go-logging" - "layeh.com/gopus" -) - -// number of individual samples per channel per batch -const samplesPerChannelPerBatch = 1920 - -var log = logging.MustGetLogger("wav") - -type Wav struct { - filename *C.char - enc *gopus.Encoder - wav *C.drwav - - once sync.Once - Done <-chan struct{} - done chan<- struct{} -} - -func New(filename string) (*Wav, error) { - cfname := C.CString(filename) - wav := C.drwav_open_file(cfname) - if wav == nil { - C.drwav_close(wav) - return nil, fmt.Errorf("Unable to initialize drwav.") - } - - if int(wav.channels) != 2 { - C.drwav_close(wav) - return nil, fmt.Errorf("Wrong number of channels!") - } - - if int(wav.sampleRate) != 48000 { - C.drwav_close(wav) - return nil, fmt.Errorf("Wrong sample rate.") - } - - enc, err := gopus.NewEncoder(int(wav.sampleRate), int(wav.channels), gopus.Audio) - if err != nil { - C.drwav_close(wav) - return nil, err - } - - done := make(chan struct{}, 1) - return &Wav{ - filename: C.CString(filename), - enc: enc, - wav: wav, - - done: done, - Done: done, - }, nil -} - -func (w *Wav) Stop() { - w.once.Do(func() { - close(w.done) - }) -} - -func (w *Wav) Start(ch chan<- []byte) { - go func() { - defer w.Stop() - - samplesPerBatch := samplesPerChannelPerBatch * int(w.wav.channels) - batchSize := samplesPerBatch * int(w.wav.bytesPerSample) - - buf := C.malloc(C.size_t(batchSize)) - defer C.free(buf) - defer C.drwav_close(w.wav) - - elems := make([]int16, samplesPerBatch) - idx := 0 - - for i := 0; i*samplesPerBatch <= int(w.wav.totalSampleCount); i += 1 { - readSamples := C.drwav_read_s16(w.wav, C.dr_uint64(samplesPerBatch), (*C.dr_int16)(buf)) - slc := (*[1 << 30]int16)(buf)[:readSamples:readSamples] - - readIdx := 0 - - for { - batchSamplesToFill := samplesPerBatch - idx - readSamplesRemaining := int(readSamples) - readIdx - - // break if we don't have enough samples to fill the rest of the buffer - if readSamplesRemaining < batchSamplesToFill { - break - } - - copy(elems[idx:], slc[readIdx:readIdx+batchSamplesToFill]) - idx = 0 - readIdx += batchSamplesToFill - - b, err := processPCM(w.wav, w.enc, elems[:]) - if err != nil { - log.Errorf("error encoding pcm: %q", err) - continue - } - - select { - case <-w.Done: - return - default: - } - select { - case <-w.Done: - return - case ch <- b: - } - } - - batchSamplesToFill := samplesPerBatch - idx - readSamplesRemaining := int(readSamples) - readIdx - if readSamplesRemaining >= batchSamplesToFill { - log.Fatalf("Had enough samples to fill batch after for loop.") - } - - copy(elems[idx:], slc) - idx += len(slc) - - if int(readSamples) < samplesPerBatch { - break - } - } - }() -} - -func processPCM(wav *C.drwav, enc *gopus.Encoder, data []int16) ([]byte, error) { - return enc.Encode(data, len(data)/int(wav.channels), len(data)*2) -} |
