#include "AudioWriter.h"

#include "File.h"
#include "BinaryStream.h"
#include "AudioSample.h"

AudioWriter::AudioWriter()
{

}

void AudioWriter::SetPath(const std::string& path)
{
    mPath = path;
}

void AudioWriter::Write(const AudioSamplePtr& sample)
{
    if (mPath.empty())
    {
        return;
    }

    const auto sample_rate = sample->GetSampleRate();
    const auto num_channels = sample->GetNumChannels();
    const auto bytes_per_sample = sample->GetBitDepth() / 8;
    unsigned byte_rate = sample_rate*num_channels*bytes_per_sample;

    File outfile(mPath);
    outfile.SetAccessMode(File::AccessMode::Write);
    outfile.Open(true);
    auto handle = outfile.GetOutHandle();

    handle->write("RIFF", 4);
    auto data = sample->GetChannelData(0);
    const auto num_samples = data.size();
    unsigned content_size = 36 + bytes_per_sample* num_samples*num_channels;

    BinaryStream::write<int>(handle, content_size);
    handle->write("WAVE", 4);

    /* write fmt  subchunk */
    handle->write("fmt ", 4);
    BinaryStream::write<int>(handle, 16); // SubChunk1Size
    BinaryStream::write<short>(handle, 1); // PCM Format
    BinaryStream::write<short>(handle, num_channels);
    BinaryStream::write<int>(handle, sample_rate);
    BinaryStream::write<int>(handle, byte_rate);
    BinaryStream::write<short>(handle, num_channels*bytes_per_sample); // block align
    BinaryStream::write<short>(handle, 8*bytes_per_sample); // bits/sample

    /* write data subchunk */
    handle->write("data", 4);
    BinaryStream::write<int>(handle, bytes_per_sample* num_samples*num_channels); // bits/sample

    handle->write(reinterpret_cast<const char*>(&data[0]), data.size()*sizeof(short));
    outfile.Close();
}
