Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added saveToMemory method #94

Merged
merged 5 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 26 additions & 20 deletions AudioFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ class AudioFile
//=============================================================
/** Loads an audio file from data in memory */
bool loadFromMemory (const std::vector<uint8_t>& fileData);


//=============================================================
/** Saves an audio file to data in memory */
bool saveToMemory (std::vector<uint8_t>& fileData, AudioFileFormat format = AudioFileFormat::Wave);

//=============================================================
/** @Returns the sample rate */
uint32_t getSampleRate() const;
Expand Down Expand Up @@ -190,10 +194,10 @@ class AudioFile
//=============================================================
bool decodeWaveFile (const std::vector<uint8_t>& fileData);
bool decodeAiffFile (const std::vector<uint8_t>& fileData);

//=============================================================
bool saveToWaveFile (const std::string& filePath);
bool saveToAiffFile (const std::string& filePath);
bool encodeWaveFile (std::vector<uint8_t>& fileData);
bool encodeAiffFile (std::vector<uint8_t>& fileData);

//=============================================================
void clearAudioBuffer();
Expand Down Expand Up @@ -889,25 +893,31 @@ void AudioFile<T>::addSampleRateToAiffData (std::vector<uint8_t>& fileData, uint
//=============================================================
template <class T>
bool AudioFile<T>::save (const std::string& filePath, AudioFileFormat format)
{
std::vector<uint8_t> fileData;
return saveToMemory (fileData, format) && writeDataToFile (fileData, filePath);
}

//=============================================================
template <class T>
bool AudioFile<T>::saveToMemory (std::vector<uint8_t>& fileData, AudioFileFormat format)
{
if (format == AudioFileFormat::Wave)
{
return saveToWaveFile (filePath);
return encodeWaveFile (fileData);
}
else if (format == AudioFileFormat::Aiff)
{
return saveToAiffFile (filePath);
return encodeAiffFile (fileData);
}

return false;
}

//=============================================================
template <class T>
bool AudioFile<T>::saveToWaveFile (const std::string& filePath)
{
std::vector<uint8_t> fileData;

bool AudioFile<T>::encodeWaveFile (std::vector<uint8_t>& fileData)
{
int32_t dataChunkSize = getNumSamplesPerChannel() * (getNumChannels() * bitDepth / 8);
int16_t audioFormat = bitDepth == 32 && std::is_floating_point_v<T> ? WavAudioFormat::IEEEFloat : WavAudioFormat::PCM;
int32_t formatChunkSize = audioFormat == WavAudioFormat::PCM ? 16 : 18;
Expand Down Expand Up @@ -1011,20 +1021,17 @@ bool AudioFile<T>::saveToWaveFile (const std::string& filePath)
// check that the various sizes we put in the metadata are correct
if (fileSizeInBytes != static_cast<int32_t> (fileData.size() - 8) || dataChunkSize != (getNumSamplesPerChannel() * getNumChannels() * (bitDepth / 8)))
{
reportError ("ERROR: couldn't save file to " + filePath);
reportError ("ERROR: Incorrect file or data chunk size.");
return false;
}

// try to write the file
return writeDataToFile (fileData, filePath);
return true;
}

//=============================================================
template <class T>
bool AudioFile<T>::saveToAiffFile (const std::string& filePath)
{
std::vector<uint8_t> fileData;

bool AudioFile<T>::encodeAiffFile (std::vector<uint8_t>& fileData)
{
int32_t numBytesPerSample = bitDepth / 8;
int32_t numBytesPerFrame = numBytesPerSample * getNumChannels();
int32_t totalNumAudioSampleBytes = getNumSamplesPerChannel() * numBytesPerFrame;
Expand Down Expand Up @@ -1116,12 +1123,11 @@ bool AudioFile<T>::saveToAiffFile (const std::string& filePath)
// check that the various sizes we put in the metadata are correct
if (fileSizeInBytes != static_cast<int32_t> (fileData.size() - 8) || soundDataChunkSize != getNumSamplesPerChannel() * numBytesPerFrame + 8)
{
reportError ("ERROR: couldn't save file to " + filePath);
reportError ("ERROR: Incorrect file or data chunk size.");
return false;
}

// try to write the file
return writeDataToFile (fileData, filePath);
return true;
}

//=============================================================
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ AudioFile is written and maintained by Adam Stark.
// Aiff file
audioFile.save ("path/to/desired/audioFile.aif", AudioFileFormat::Aiff);

### Save the audio file to memory

Write the audio file data directly to a vector of bytes (without writing to a file on disk):

std::vector<uint8_t> fileData;
saveToMemory (fileData, AudioFileFormat::Wave);

or

saveToMemory (fileData, AudioFileFormat::Aiff);

## Examples

Please see the `examples` folder for some examples on library usage.
Expand Down Expand Up @@ -256,6 +267,7 @@ Many thanks to the following people for their contributions to this library:
- [Metalsofa](https://github.com/Metalsofa)
- [mrpossoms](https://github.com/mrpossoms)
- [mynameisjohn](https://github.com/mynameisjohn)
- [nicmell](https://github.com/nicmell)
- [Sidelobe](https://github.com/Sidelobe)
- [sschaetz](https://github.com/sschaetz)
- [Yhcrown](https://github.com/Yhcrown)
Expand Down