-
Notifications
You must be signed in to change notification settings - Fork 474
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support writing generated audio samples to wave files (#363)
- Loading branch information
1 parent
536d580
commit 1ac2232
Showing
6 changed files
with
149 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// sherpa-onnx/csrc/wave-writer.cc | ||
// | ||
// Copyright (c) 2023 Xiaomi Corporation | ||
|
||
#include "sherpa-onnx/csrc/wave-writer.h" | ||
|
||
#include <fstream> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include "sherpa-onnx/csrc/macros.h" | ||
|
||
namespace sherpa_onnx { | ||
namespace { | ||
|
||
// see http://soundfile.sapp.org/doc/WaveFormat/ | ||
// | ||
// Note: We assume little endian here | ||
// TODO(fangjun): Support big endian | ||
struct WaveHeader { | ||
int32_t chunk_id; | ||
int32_t chunk_size; | ||
int32_t format; | ||
int32_t subchunk1_id; | ||
int32_t subchunk1_size; | ||
int16_t audio_format; | ||
int16_t num_channels; | ||
int32_t sample_rate; | ||
int32_t byte_rate; | ||
int16_t block_align; | ||
int16_t bits_per_sample; | ||
int32_t subchunk2_id; // a tag of this chunk | ||
int32_t subchunk2_size; // size of subchunk2 | ||
}; | ||
|
||
} // namespace | ||
|
||
bool WriteWave(const std::string &filename, int32_t sampling_rate, | ||
const float *samples, int32_t n) { | ||
WaveHeader header; | ||
header.chunk_id = 0x46464952; // FFIR | ||
header.format = 0x45564157; // EVAW | ||
header.subchunk1_id = 0x20746d66; // "fmt " | ||
header.subchunk1_size = 16; // 16 for PCM | ||
header.audio_format = 1; // PCM =1 | ||
|
||
int32_t num_channels = 1; | ||
int32_t bits_per_sample = 16; // int16_t | ||
header.num_channels = num_channels; | ||
header.sample_rate = sampling_rate; | ||
header.byte_rate = sampling_rate * num_channels * bits_per_sample / 8; | ||
header.block_align = num_channels * bits_per_sample / 8; | ||
header.bits_per_sample = bits_per_sample; | ||
header.subchunk2_id = 0x61746164; // atad | ||
header.subchunk2_size = n * num_channels * bits_per_sample / 8; | ||
|
||
header.chunk_size = 36 + header.subchunk2_size; | ||
|
||
std::vector<int16_t> samples_int16(n); | ||
for (int32_t i = 0; i != n; ++i) { | ||
samples_int16[i] = samples[i] * 32676; | ||
} | ||
|
||
std::ofstream os(filename, std::ios::binary); | ||
if (!os) { | ||
SHERPA_ONNX_LOGE("Failed to create %s", filename.c_str()); | ||
return false; | ||
} | ||
|
||
os.write(reinterpret_cast<const char *>(&header), sizeof(header)); | ||
os.write(reinterpret_cast<const char *>(samples_int16.data()), | ||
samples_int16.size() * sizeof(int16_t)); | ||
|
||
if (!os) { | ||
SHERPA_ONNX_LOGE("Write %s failed", filename.c_str()); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
} // namespace sherpa_onnx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// sherpa-onnx/csrc/wave-writer.h | ||
// | ||
// Copyright (c) 2023 Xiaomi Corporation | ||
|
||
#ifndef SHERPA_ONNX_CSRC_WAVE_WRITER_H_ | ||
#define SHERPA_ONNX_CSRC_WAVE_WRITER_H_ | ||
|
||
#include <cstdint> | ||
#include <string> | ||
|
||
namespace sherpa_onnx { | ||
|
||
// Write a single channel wave file. | ||
// Note that the input samples are in the range [-1, 1]. It will be multiplied | ||
// by 32767 and saved in int16_t format in the wave file. | ||
// | ||
// @param filename Path to save the samples. | ||
// @param sampling_rate Sample rate of the samples. | ||
// @param samples Pointer to the samples | ||
// @param n Number of samples | ||
// @return Return true if the write succeeds; return false otherwise. | ||
bool WriteWave(const std::string &filename, int32_t sampling_rate, | ||
const float *samples, int32_t n); | ||
|
||
} // namespace sherpa_onnx | ||
|
||
#endif // SHERPA_ONNX_CSRC_WAVE_WRITER_H_ |