@@ -581,7 +581,7 @@ static sherpa_onnx::OfflineRecognizerConfig GetOfflineRecognizerConfig(
581581
582582 recognizer_config.model_config .fire_red_asr_ctc .model =
583583 SHERPA_ONNX_OR (config->model_config .fire_red_asr_ctc .model , " " );
584-
584+
585585 recognizer_config.model_config .qwen3_asr .conv_frontend =
586586 SHERPA_ONNX_OR (config->model_config .qwen3_asr .conv_frontend , " " );
587587 recognizer_config.model_config .qwen3_asr .encoder =
@@ -2026,60 +2026,51 @@ void SherpaOnnxFreeWave(const SherpaOnnxWave *wave) {
20262026 }
20272027}
20282028
2029- struct SherpaOnnxMultiChannelWaveImpl {
2030- std::vector<std::vector<float >> samples;
2031- };
2032-
2033- // Internal wrapper that pairs the public C struct with its C++ implementation
2034- // so that SherpaOnnxFreeMultiChannelWave can recover the impl pointer.
2035- struct SherpaOnnxMultiChannelWaveInternal {
2036- SherpaOnnxMultiChannelWave pub;
2037- SherpaOnnxMultiChannelWaveImpl *impl;
2029+ struct SherpaOnnxMultiChannelWaveInternal : SherpaOnnxMultiChannelWave {
2030+ std::vector<float > flat_samples;
2031+ std::vector<const float *> channel_ptrs;
20382032};
20392033
20402034const SherpaOnnxMultiChannelWave *SherpaOnnxReadWaveMultiChannel (
20412035 const char *filename) {
20422036 int32_t sample_rate = -1 ;
20432037 bool is_ok = false ;
2044- auto samples =
2038+
2039+ auto samples_2d =
20452040 sherpa_onnx::ReadWaveMultiChannel (filename, &sample_rate, &is_ok);
2046- if (!is_ok || samples.empty ()) {
2041+
2042+ if (!is_ok || samples_2d.empty ()) {
20472043 return nullptr ;
20482044 }
20492045
2050- int32_t num_channels = samples .size ();
2051- int32_t num_samples = samples [0 ].size ();
2046+ int32_t num_channels = static_cast < int32_t >(samples_2d .size () );
2047+ int32_t num_samples = static_cast < int32_t >(samples_2d [0 ].size () );
20522048
2053- // Allocate the internal storage that owns the data.
2054- auto *impl = new SherpaOnnxMultiChannelWaveImpl;
2055- impl->samples = std::move (samples);
2049+ auto *w = new SherpaOnnxMultiChannelWaveInternal ();
20562050
2057- // Allocate the arrays of pointers visible to the C caller.
2058- const float **channel_ptrs = new const float *[num_channels];
2059- for ( int32_t c = 0 ; c < num_channels; ++c) {
2060- channel_ptrs[c] = impl-> samples [c]. data ( );
2051+ w-> flat_samples . reserve (num_channels * num_samples);
2052+ for ( const auto &channel : samples_2d) {
2053+ w-> flat_samples . insert (w-> flat_samples . end (), channel. begin (),
2054+ channel. end () );
20612055 }
20622056
2063- // Pack everything into the public struct.
2064- auto *w = new SherpaOnnxMultiChannelWaveInternal;
2065- w->pub .samples = channel_ptrs;
2066- w->pub .num_channels = num_channels;
2067- w->pub .num_samples = num_samples;
2068- w->pub .sample_rate = sample_rate;
2069- w->impl = impl;
2057+ w->channel_ptrs .resize (num_channels);
2058+ for (int32_t c = 0 ; c != num_channels; ++c) {
2059+ w->channel_ptrs [c] = w->flat_samples .data () + (c * num_samples);
2060+ }
2061+
2062+ w->samples = w->channel_ptrs .data ();
2063+ w->num_channels = num_channels;
2064+ w->num_samples = num_samples;
2065+ w->sample_rate = sample_rate;
20702066
2071- return &w-> pub ;
2067+ return w ;
20722068}
20732069
20742070void SherpaOnnxFreeMultiChannelWave (const SherpaOnnxMultiChannelWave *wave) {
2075- if (!wave) return ;
2076- // The SherpaOnnxMultiChannelWave is the first member of
2077- // SherpaOnnxMultiChannelWaveInternal, so the pointer values are identical.
2078- auto *iw = reinterpret_cast <SherpaOnnxMultiChannelWaveInternal *>(
2079- const_cast <SherpaOnnxMultiChannelWave *>(wave));
2080- delete[] iw->pub .samples ;
2081- delete iw->impl ;
2082- delete iw;
2071+ if (wave) {
2072+ delete static_cast <const SherpaOnnxMultiChannelWaveInternal *>(wave);
2073+ }
20832074}
20842075
20852076struct SherpaOnnxSpokenLanguageIdentification {
0 commit comments