/*
NAME
  pcm_test.go

DESCRIPTION
  pcm_test.go contains functions for testing the pcm package.

AUTHOR
  Trek Hopton <trek@ausocean.org>

LICENSE
  pcm_test.go is Copyright (C) 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 [GNU licenses](http://www.gnu.org/licenses).
*/
package pcm

import (
	"bytes"
	"io/ioutil"
	"log"
	"testing"

	"github.com/yobert/alsa"
)

// TestResample tests the Resample function using a pcm file that contains audio of a freq. sweep.
// The output of the Resample function is compared with a file containing the expected result.
func TestResample(t *testing.T) {
	inPath := "../../../test/test-data/av/input/sweep_400Hz_20000Hz_-3dBFS_5s_48khz.pcm"
	expPath := "../../../test/test-data/av/output/sweep_400Hz_20000Hz_resampled_48to8kHz.pcm"

	// Read input pcm.
	inPcm, err := ioutil.ReadFile(inPath)
	if err != nil {
		log.Fatal(err)
	}

	format := alsa.BufferFormat{
		Channels:     1,
		Rate:         48000,
		SampleFormat: alsa.S16_LE,
	}

	buf := alsa.Buffer{
		Format: format,
		Data:   inPcm,
	}

	// Resample pcm.
	resampled, err := Resample(buf, 8000)
	if err != nil {
		log.Fatal(err)
	}

	// Read expected resampled pcm.
	exp, err := ioutil.ReadFile(expPath)
	if err != nil {
		log.Fatal(err)
	}

	// Compare result with expected.
	if !bytes.Equal(resampled, exp) {
		t.Error("Resampled data does not match expected result.")
	}
}

// TestStereoToMono tests the StereoToMono function using a pcm file that contains stereo audio.
// The output of the StereoToMono function is compared with a file containing the expected mono audio.
func TestStereoToMono(t *testing.T) {
	inPath := "../../../test/test-data/av/input/stereo_DTMF_tones.pcm"
	expPath := "../../../test/test-data/av/output/mono_DTMF_tones.pcm"

	// Read input pcm.
	inPcm, err := ioutil.ReadFile(inPath)
	if err != nil {
		log.Fatal(err)
	}

	format := alsa.BufferFormat{
		Channels:     2,
		Rate:         44100,
		SampleFormat: alsa.S16_LE,
	}

	buf := alsa.Buffer{
		Format: format,
		Data:   inPcm,
	}

	// Convert audio.
	mono, err := StereoToMono(buf)
	if err != nil {
		log.Fatal(err)
	}

	// Read expected mono pcm.
	exp, err := ioutil.ReadFile(expPath)
	if err != nil {
		log.Fatal(err)
	}

	// Compare result with expected.
	if !bytes.Equal(mono, exp) {
		t.Error("Converted data does not match expected result.")
	}
}