@@ -109,7 +109,11 @@ class AudioFile
109109 // =============================================================
110110 /* * Loads an audio file from data in memory */
111111 bool loadFromMemory (const std::vector<uint8_t >& fileData);
112-
112+
113+ // =============================================================
114+ /* * Saves an audio file to data in memory */
115+ bool saveToMemory (std::vector<uint8_t >& fileData, AudioFileFormat format = AudioFileFormat::Wave);
116+
113117 // =============================================================
114118 /* * @Returns the sample rate */
115119 uint32_t getSampleRate () const ;
@@ -190,10 +194,10 @@ class AudioFile
190194 // =============================================================
191195 bool decodeWaveFile (const std::vector<uint8_t >& fileData);
192196 bool decodeAiffFile (const std::vector<uint8_t >& fileData);
193-
197+
194198 // =============================================================
195- bool saveToWaveFile ( const std::string& filePath );
196- bool saveToAiffFile ( const std::string& filePath );
199+ bool encodeWaveFile ( std::vector< uint8_t >& fileData );
200+ bool encodeAiffFile ( std::vector< uint8_t >& fileData );
197201
198202 // =============================================================
199203 void clearAudioBuffer ();
@@ -889,25 +893,31 @@ void AudioFile<T>::addSampleRateToAiffData (std::vector<uint8_t>& fileData, uint
889893// =============================================================
890894template <class T >
891895bool AudioFile<T>::save (const std::string& filePath, AudioFileFormat format)
896+ {
897+ std::vector<uint8_t > fileData;
898+ return saveToMemory (fileData, format) && writeDataToFile (fileData, filePath);
899+ }
900+
901+ // =============================================================
902+ template <class T >
903+ bool AudioFile<T>::saveToMemory (std::vector<uint8_t >& fileData, AudioFileFormat format)
892904{
893905 if (format == AudioFileFormat::Wave)
894906 {
895- return saveToWaveFile (filePath );
907+ return encodeWaveFile (fileData );
896908 }
897909 else if (format == AudioFileFormat::Aiff)
898910 {
899- return saveToAiffFile (filePath );
911+ return encodeAiffFile (fileData );
900912 }
901913
902914 return false ;
903915}
904916
905917// =============================================================
906918template <class T >
907- bool AudioFile<T>::saveToWaveFile (const std::string& filePath)
908- {
909- std::vector<uint8_t > fileData;
910-
919+ bool AudioFile<T>::encodeWaveFile (std::vector<uint8_t >& fileData)
920+ {
911921 int32_t dataChunkSize = getNumSamplesPerChannel () * (getNumChannels () * bitDepth / 8 );
912922 int16_t audioFormat = bitDepth == 32 && std::is_floating_point_v<T> ? WavAudioFormat::IEEEFloat : WavAudioFormat::PCM;
913923 int32_t formatChunkSize = audioFormat == WavAudioFormat::PCM ? 16 : 18 ;
@@ -985,9 +995,22 @@ bool AudioFile<T>::saveToWaveFile (const std::string& filePath)
985995 int32_t sampleAsInt;
986996
987997 if (audioFormat == WavAudioFormat::IEEEFloat)
988- sampleAsInt = (int32_t ) reinterpret_cast <int32_t &> (samples[channel][i]);
998+ {
999+ if constexpr (std::is_same_v<T, float >)
1000+ {
1001+ sampleAsInt = (int32_t ) reinterpret_cast <int32_t &> (samples[channel][i]);
1002+ }
1003+ else if constexpr (std::is_same_v<T, double >)
1004+ {
1005+ auto sampleAsFloat = (float ) samples[channel][i];
1006+ float & referenceToSample = sampleAsFloat;
1007+ sampleAsInt = (int32_t ) reinterpret_cast <int32_t &> (referenceToSample);
1008+ }
1009+ }
9891010 else // assume PCM
1011+ {
9901012 sampleAsInt = AudioSampleConverter<T>::sampleToThirtyTwoBitInt (samples[channel][i]);
1013+ }
9911014
9921015 addInt32ToFileData (fileData, sampleAsInt, Endianness::LittleEndian);
9931016 }
@@ -1011,20 +1034,17 @@ bool AudioFile<T>::saveToWaveFile (const std::string& filePath)
10111034 // check that the various sizes we put in the metadata are correct
10121035 if (fileSizeInBytes != static_cast <int32_t > (fileData.size () - 8 ) || dataChunkSize != (getNumSamplesPerChannel () * getNumChannels () * (bitDepth / 8 )))
10131036 {
1014- reportError (" ERROR: couldn't save file to " + filePath );
1037+ reportError (" ERROR: Incorrect file or data chunk size. " );
10151038 return false ;
10161039 }
10171040
1018- // try to write the file
1019- return writeDataToFile (fileData, filePath);
1041+ return true ;
10201042}
10211043
10221044// =============================================================
10231045template <class T >
1024- bool AudioFile<T>::saveToAiffFile (const std::string& filePath)
1025- {
1026- std::vector<uint8_t > fileData;
1027-
1046+ bool AudioFile<T>::encodeAiffFile (std::vector<uint8_t >& fileData)
1047+ {
10281048 int32_t numBytesPerSample = bitDepth / 8 ;
10291049 int32_t numBytesPerFrame = numBytesPerSample * getNumChannels ();
10301050 int32_t totalNumAudioSampleBytes = getNumSamplesPerChannel () * numBytesPerFrame;
@@ -1116,12 +1136,11 @@ bool AudioFile<T>::saveToAiffFile (const std::string& filePath)
11161136 // check that the various sizes we put in the metadata are correct
11171137 if (fileSizeInBytes != static_cast <int32_t > (fileData.size () - 8 ) || soundDataChunkSize != getNumSamplesPerChannel () * numBytesPerFrame + 8 )
11181138 {
1119- reportError (" ERROR: couldn't save file to " + filePath );
1139+ reportError (" ERROR: Incorrect file or data chunk size. " );
11201140 return false ;
11211141 }
11221142
1123- // try to write the file
1124- return writeDataToFile (fileData, filePath);
1143+ return true ;
11251144}
11261145
11271146// =============================================================
0 commit comments