mirror of https://github.com/probonopd/MiniDexed
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.9 KiB
91 lines
2.9 KiB
#include "wave.h"
|
|
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <cstring>
|
|
|
|
void saveWaveFile(const std::string& fileName,
|
|
const float32_t* LChannel,
|
|
const float32_t* RChannel,
|
|
size_t size,
|
|
int sampleRate,
|
|
int bitsPerSample)
|
|
{
|
|
std::ofstream file(fileName, std::ios::binary);
|
|
if(!file)
|
|
{
|
|
std::cerr << "Error opening file: " << fileName << std::endl;
|
|
return;
|
|
}
|
|
|
|
WaveHeader header;
|
|
std::memset(&header, 0, sizeof(header));
|
|
header.sampleRate = sampleRate;
|
|
header.numChannels = 2;
|
|
header.bitsPerSample = bitsPerSample;
|
|
header.byteRate = header.sampleRate * header.numChannels * header.bitsPerSample / 8;
|
|
header.blockAlign = header.numChannels * header.bitsPerSample / 8;
|
|
header.subchunk2Size = size * header.blockAlign;
|
|
header.chunkSize = 36 + header.subchunk2Size;
|
|
header.subchunk1Size = 16;
|
|
header.audioFormat = 1;
|
|
|
|
header.chunkId.Value = id2int("RIFF");
|
|
header.format.Value = id2int("WAVE");
|
|
header.subchunk1Id.Value = id2int("fmt ");
|
|
header.subchunk2Id.Value = id2int("data");
|
|
// std::strncpy(header.chunkId, "RIFF", 4);
|
|
// std::strncpy(header.format, "WAVE", 4);
|
|
// std::strncpy(header.subchunk1Id, "fmt ", 4);
|
|
// std::strncpy(header.subchunk2Id, "data", 4);
|
|
|
|
file.write((char*)&header, sizeof(header));
|
|
|
|
if(bitsPerSample == 8)
|
|
{
|
|
for (size_t i = 0; i < size; i++)
|
|
{
|
|
int8_t leftSample = (int8_t)(LChannel[i] * 128.0f + 128.0f);
|
|
int8_t rightSample = (int8_t)(RChannel[i] * 128.0f + 128.0f);
|
|
file.write((char*)&leftSample, 1);
|
|
file.write((char*)&rightSample, 1);
|
|
}
|
|
}
|
|
else if(bitsPerSample == 16)
|
|
{
|
|
for (size_t i = 0; i < size; i++)
|
|
{
|
|
int16_t leftSample = (int16_t)(LChannel[i] * 32768.0f);
|
|
int16_t rightSample = (int16_t)(RChannel[i] * 32768.0f);
|
|
file.write((char*)&leftSample, 2);
|
|
file.write((char*)&rightSample, 2);
|
|
}
|
|
}
|
|
else if(bitsPerSample == 24)
|
|
{
|
|
for(size_t i = 0; i < size; i++)
|
|
{
|
|
int32_t leftSample = (int32_t)(LChannel[i] * 8388608.0f);
|
|
int32_t rightSample = (int32_t)(RChannel[i] * 8388608.0f);
|
|
file.write((char*)&leftSample, 3);
|
|
file.write((char*)&rightSample, 3);
|
|
}
|
|
}
|
|
else if(bitsPerSample == 32)
|
|
{
|
|
for (size_t i = 0; i < size; i++)
|
|
{
|
|
int32_t leftSample = (int32_t)(LChannel[i] * 2147483648.0f);
|
|
int32_t rightSample = (int32_t)(RChannel[i] * 2147483648.0f);
|
|
file.write((char*)&leftSample, 4);
|
|
file.write((char*)&rightSample, 4);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "Error: unsupported bit depth: " << bitsPerSample << std::endl;
|
|
return;
|
|
}
|
|
|
|
file.close();
|
|
}
|
|
|