cjsdurj
Committed by GitHub

c-api add wave write to buffer. (#1962)

Co-authored-by: jian.chen03 <jian.chen03@transwarp.io>
@@ -136,3 +136,6 @@ kokoro-multi-lang-v1_0 @@ -136,3 +136,6 @@ kokoro-multi-lang-v1_0
136 sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16 136 sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16
137 cmake-build-debug 137 cmake-build-debug
138 README-DEV.txt 138 README-DEV.txt
  139 +
  140 +##clion
  141 +.idea
@@ -1337,6 +1337,16 @@ int32_t SherpaOnnxWriteWave(const float *samples, int32_t n, @@ -1337,6 +1337,16 @@ int32_t SherpaOnnxWriteWave(const float *samples, int32_t n,
1337 return sherpa_onnx::WriteWave(filename, sample_rate, samples, n); 1337 return sherpa_onnx::WriteWave(filename, sample_rate, samples, n);
1338 } 1338 }
1339 1339
  1340 +int64_t SherpaOnnxWaveFileSize(int32_t n_samples) {
  1341 + return sherpa_onnx::WaveFileSize(n_samples);
  1342 +}
  1343 +
  1344 +SHERPA_ONNX_API void SherpaOnnxWriteWaveToBuffer(const float *samples,
  1345 + int32_t n, int32_t sample_rate,
  1346 + char *buffer) {
  1347 + sherpa_onnx::WriteWave(buffer, sample_rate, samples, n);
  1348 +}
  1349 +
1340 const SherpaOnnxWave *SherpaOnnxReadWave(const char *filename) { 1350 const SherpaOnnxWave *SherpaOnnxReadWave(const char *filename) {
1341 int32_t sample_rate = -1; 1351 int32_t sample_rate = -1;
1342 bool is_ok = false; 1352 bool is_ok = false;
@@ -1049,6 +1049,18 @@ SHERPA_ONNX_API int32_t SherpaOnnxWriteWave(const float *samples, int32_t n, @@ -1049,6 +1049,18 @@ SHERPA_ONNX_API int32_t SherpaOnnxWriteWave(const float *samples, int32_t n,
1049 int32_t sample_rate, 1049 int32_t sample_rate,
1050 const char *filename); 1050 const char *filename);
1051 1051
  1052 +// the amount of bytes needed to store a wave file which contains a
  1053 +// single channel and has 16-bit samples.
  1054 +SHERPA_ONNX_API int64_t SherpaOnnxWaveFileSize(int32_t n_samples);
  1055 +
  1056 +// Similar to SherpaOnnxWriteWave , it writes wave to allocated buffer;
  1057 +//
  1058 +// in some case (http tts api return wave binary file, server do not need to
  1059 +// write wave to fs)
  1060 +SHERPA_ONNX_API void SherpaOnnxWriteWaveToBuffer(const float *samples,
  1061 + int32_t n, int32_t sample_rate,
  1062 + char *buffer);
  1063 +
1052 SHERPA_ONNX_API typedef struct SherpaOnnxWave { 1064 SHERPA_ONNX_API typedef struct SherpaOnnxWave {
1053 // samples normalized to the range [-1, 1] 1065 // samples normalized to the range [-1, 1]
1054 const float *samples; 1066 const float *samples;
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 4
5 #include "sherpa-onnx/csrc/wave-writer.h" 5 #include "sherpa-onnx/csrc/wave-writer.h"
6 6
  7 +#include <cstring>
7 #include <fstream> 8 #include <fstream>
8 #include <string> 9 #include <string>
9 #include <vector> 10 #include <vector>
@@ -35,8 +36,12 @@ struct WaveHeader { @@ -35,8 +36,12 @@ struct WaveHeader {
35 36
36 } // namespace 37 } // namespace
37 38
38 -bool WriteWave(const std::string &filename, int32_t sampling_rate,  
39 - const float *samples, int32_t n) { 39 +int64_t WaveFileSize(int32_t n_samples) {
  40 + return sizeof(WaveHeader) + n_samples * sizeof(int16_t);
  41 +}
  42 +
  43 +void WriteWave(char *buffer, int32_t sampling_rate, const float *samples,
  44 + int32_t n) {
40 WaveHeader header{}; 45 WaveHeader header{};
41 header.chunk_id = 0x46464952; // FFIR 46 header.chunk_id = 0x46464952; // FFIR
42 header.format = 0x45564157; // EVAW 47 header.format = 0x45564157; // EVAW
@@ -61,21 +66,26 @@ bool WriteWave(const std::string &filename, int32_t sampling_rate, @@ -61,21 +66,26 @@ bool WriteWave(const std::string &filename, int32_t sampling_rate,
61 samples_int16[i] = samples[i] * 32676; 66 samples_int16[i] = samples[i] * 32676;
62 } 67 }
63 68
  69 + memcpy(buffer, &header, sizeof(WaveHeader));
  70 + memcpy(buffer + sizeof(WaveHeader), samples_int16.data(),
  71 + n * sizeof(int16_t));
  72 +}
  73 +
  74 +bool WriteWave(const std::string &filename, int32_t sampling_rate,
  75 + const float *samples, int32_t n) {
  76 + std::string buffer;
  77 + buffer.resize(WaveFileSize(n));
  78 + WriteWave(buffer.data(), sampling_rate, samples, n);
64 std::ofstream os(filename, std::ios::binary); 79 std::ofstream os(filename, std::ios::binary);
65 if (!os) { 80 if (!os) {
66 SHERPA_ONNX_LOGE("Failed to create %s", filename.c_str()); 81 SHERPA_ONNX_LOGE("Failed to create %s", filename.c_str());
67 return false; 82 return false;
68 } 83 }
69 -  
70 - os.write(reinterpret_cast<const char *>(&header), sizeof(header));  
71 - os.write(reinterpret_cast<const char *>(samples_int16.data()),  
72 - samples_int16.size() * sizeof(int16_t));  
73 - 84 + os << buffer;
74 if (!os) { 85 if (!os) {
75 SHERPA_ONNX_LOGE("Write %s failed", filename.c_str()); 86 SHERPA_ONNX_LOGE("Write %s failed", filename.c_str());
76 return false; 87 return false;
77 } 88 }
78 -  
79 return true; 89 return true;
80 } 90 }
81 91
@@ -22,6 +22,11 @@ namespace sherpa_onnx { @@ -22,6 +22,11 @@ namespace sherpa_onnx {
22 bool WriteWave(const std::string &filename, int32_t sampling_rate, 22 bool WriteWave(const std::string &filename, int32_t sampling_rate,
23 const float *samples, int32_t n); 23 const float *samples, int32_t n);
24 24
  25 +void WriteWave(char *buffer, int32_t sampling_rate, const float *samples,
  26 + int32_t n);
  27 +
  28 +int64_t WaveFileSize(int32_t n_samples);
  29 +
25 } // namespace sherpa_onnx 30 } // namespace sherpa_onnx
26 31
27 #endif // SHERPA_ONNX_CSRC_WAVE_WRITER_H_ 32 #endif // SHERPA_ONNX_CSRC_WAVE_WRITER_H_