/* NAME audio_test.go AUTHOR Trek Hopton LICENSE audio_test.go is Copyright (C) 2017-2019 the Australian Ocean Lab (AusOcean) It is free software: you can redistribute it and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in gpl.txt. If not, see http://www.gnu.org/licenses. */ package mts import ( "bytes" "io" "io/ioutil" "testing" "github.com/Comcast/gots/packet" "github.com/Comcast/gots/pes" "bitbucket.org/ausocean/av/container/mts/meta" ) type nopCloser struct{ io.Writer } func (nopCloser) Close() error { return nil } // TestEncodePcm tests the mpegts encoder's ability to encode pcm audio data. // It reads and encodes input pcm data into mpegts, then decodes the mpegts and compares the result to the input pcm. func TestEncodePcm(t *testing.T) { Meta = meta.New() var buf bytes.Buffer sampleRate := 48000 sampleSize := 2 blockSize := 16000 writeFreq := float64(sampleRate*sampleSize) / float64(blockSize) e := NewEncoder(nopCloser{&buf}, writeFreq, Audio) inPath := "../../../test/test-data/av/input/sweep_400Hz_20000Hz_-3dBFS_5s_48khz.pcm" inPcm, err := ioutil.ReadFile(inPath) if err != nil { t.Errorf("unable to read file: %v", err) } // Break pcm into blocks and encode to mts and get the resulting bytes. for i := 0; i < len(inPcm); i += blockSize { if len(inPcm)-i < blockSize { block := inPcm[i:] _, err = e.Write(block) if err != nil { t.Errorf("unable to write block: %v", err) } } else { block := inPcm[i : i+blockSize] _, err = e.Write(block) if err != nil { t.Errorf("unable to write block: %v", err) } } } clip := buf.Bytes() // Get the first MTS packet to check var pkt packet.Packet pesPacket := make([]byte, 0, blockSize) got := make([]byte, 0, len(inPcm)) i := 0 if i+PacketSize <= len(clip) { copy(pkt[:], clip[i:i+PacketSize]) } // Loop through MTS packets until all the audio data from PES packets has been retrieved for i+PacketSize <= len(clip) { // Check MTS packet if !(pkt.PID() == audioPid) { i += PacketSize if i+PacketSize <= len(clip) { copy(pkt[:], clip[i:i+PacketSize]) } continue } if !pkt.PayloadUnitStartIndicator() { i += PacketSize if i+PacketSize <= len(clip) { copy(pkt[:], clip[i:i+PacketSize]) } } else { // Copy the first MTS payload payload, err := pkt.Payload() if err != nil { t.Errorf("unable to get MTS payload: %v", err) } pesPacket = append(pesPacket, payload...) i += PacketSize if i+PacketSize <= len(clip) { copy(pkt[:], clip[i:i+PacketSize]) } // Copy the rest of the MTS payloads that are part of the same PES packet for (!pkt.PayloadUnitStartIndicator()) && i+PacketSize <= len(clip) { payload, err = pkt.Payload() if err != nil { t.Errorf("unable to get MTS payload: %v", err) } pesPacket = append(pesPacket, payload...) i += PacketSize if i+PacketSize <= len(clip) { copy(pkt[:], clip[i:i+PacketSize]) } } } // Get the audio data from the current PES packet pesHeader, err := pes.NewPESHeader(pesPacket) if err != nil { t.Errorf("unable to read PES packet: %v", err) } got = append(got, pesHeader.Data()...) pesPacket = pesPacket[:0] } // Compare data from MTS with original data. if !bytes.Equal(got, inPcm) { t.Error("data decoded from mts did not match input data") } }