diff --git a/.gitignore b/.gitignore index 28bf143c..1c8e95b7 100644 --- a/.gitignore +++ b/.gitignore @@ -136,3 +136,6 @@ kokoro-multi-lang-v1_0 sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16 cmake-build-debug README-DEV.txt + +##clion +.idea \ No newline at end of file diff --git a/sherpa-onnx/c-api/c-api.cc b/sherpa-onnx/c-api/c-api.cc index eab473fb..0dd7fe0c 100644 --- a/sherpa-onnx/c-api/c-api.cc +++ b/sherpa-onnx/c-api/c-api.cc @@ -1337,6 +1337,16 @@ int32_t SherpaOnnxWriteWave(const float *samples, int32_t n, return sherpa_onnx::WriteWave(filename, sample_rate, samples, n); } +int64_t SherpaOnnxWaveFileSize(int32_t n_samples) { + return sherpa_onnx::WaveFileSize(n_samples); +} + +SHERPA_ONNX_API void SherpaOnnxWriteWaveToBuffer(const float *samples, + int32_t n, int32_t sample_rate, + char *buffer) { + sherpa_onnx::WriteWave(buffer, sample_rate, samples, n); +} + const SherpaOnnxWave *SherpaOnnxReadWave(const char *filename) { int32_t sample_rate = -1; bool is_ok = false; diff --git a/sherpa-onnx/c-api/c-api.h b/sherpa-onnx/c-api/c-api.h index 43567406..01177f6f 100644 --- a/sherpa-onnx/c-api/c-api.h +++ b/sherpa-onnx/c-api/c-api.h @@ -1049,6 +1049,18 @@ SHERPA_ONNX_API int32_t SherpaOnnxWriteWave(const float *samples, int32_t n, int32_t sample_rate, const char *filename); +// the amount of bytes needed to store a wave file which contains a +// single channel and has 16-bit samples. +SHERPA_ONNX_API int64_t SherpaOnnxWaveFileSize(int32_t n_samples); + +// Similar to SherpaOnnxWriteWave , it writes wave to allocated buffer; +// +// in some case (http tts api return wave binary file, server do not need to +// write wave to fs) +SHERPA_ONNX_API void SherpaOnnxWriteWaveToBuffer(const float *samples, + int32_t n, int32_t sample_rate, + char *buffer); + SHERPA_ONNX_API typedef struct SherpaOnnxWave { // samples normalized to the range [-1, 1] const float *samples; diff --git a/sherpa-onnx/csrc/wave-writer.cc b/sherpa-onnx/csrc/wave-writer.cc index 069b6276..dbd947fe 100644 --- a/sherpa-onnx/csrc/wave-writer.cc +++ b/sherpa-onnx/csrc/wave-writer.cc @@ -4,6 +4,7 @@ #include "sherpa-onnx/csrc/wave-writer.h" +#include #include #include #include @@ -35,8 +36,12 @@ struct WaveHeader { } // namespace -bool WriteWave(const std::string &filename, int32_t sampling_rate, - const float *samples, int32_t n) { +int64_t WaveFileSize(int32_t n_samples) { + return sizeof(WaveHeader) + n_samples * sizeof(int16_t); +} + +void WriteWave(char *buffer, int32_t sampling_rate, const float *samples, + int32_t n) { WaveHeader header{}; header.chunk_id = 0x46464952; // FFIR header.format = 0x45564157; // EVAW @@ -61,21 +66,26 @@ bool WriteWave(const std::string &filename, int32_t sampling_rate, samples_int16[i] = samples[i] * 32676; } + memcpy(buffer, &header, sizeof(WaveHeader)); + memcpy(buffer + sizeof(WaveHeader), samples_int16.data(), + n * sizeof(int16_t)); +} + +bool WriteWave(const std::string &filename, int32_t sampling_rate, + const float *samples, int32_t n) { + std::string buffer; + buffer.resize(WaveFileSize(n)); + WriteWave(buffer.data(), sampling_rate, samples, n); 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(&header), sizeof(header)); - os.write(reinterpret_cast(samples_int16.data()), - samples_int16.size() * sizeof(int16_t)); - + os << buffer; if (!os) { SHERPA_ONNX_LOGE("Write %s failed", filename.c_str()); return false; } - return true; } diff --git a/sherpa-onnx/csrc/wave-writer.h b/sherpa-onnx/csrc/wave-writer.h index bae4c504..054d9eaf 100644 --- a/sherpa-onnx/csrc/wave-writer.h +++ b/sherpa-onnx/csrc/wave-writer.h @@ -22,6 +22,11 @@ namespace sherpa_onnx { bool WriteWave(const std::string &filename, int32_t sampling_rate, const float *samples, int32_t n); +void WriteWave(char *buffer, int32_t sampling_rate, const float *samples, + int32_t n); + +int64_t WaveFileSize(int32_t n_samples); + } // namespace sherpa_onnx #endif // SHERPA_ONNX_CSRC_WAVE_WRITER_H_