11#include < audio-util/Util.h>
2-
32#include < iostream>
3+ #include < memory>
44#include < soxr.h>
55#include " FlacDecoder.h"
66#include " Mp3Decoder.h"
@@ -50,6 +50,10 @@ namespace AudioUtil
5050 const int original_src_channels = srcHandle.channels ();
5151 const int original_src_samplerate = srcHandle.samplerate ();
5252
53+ // 确定输入数据类型
54+ int input_format = sf_vio_in.info .format & SF_FORMAT_SUBMASK;
55+ bool is_float_input = (input_format == SF_FORMAT_FLOAT || input_format == SF_FORMAT_DOUBLE);
56+
5357 SF_VIO sf_vio_out;
5458 sf_vio_out.info = sf_vio_in.info ;
5559 sf_vio_out.info .channels = tar_channel;
@@ -59,21 +63,43 @@ namespace AudioUtil
5963 // 计算估计的输出帧数
6064 const double ratio = static_cast <double >(tar_samplerate) / original_src_samplerate;
6165 const sf_count_t estimated_frames = static_cast <sf_count_t >(srcHandle.frames () * ratio + 0.5 );
62- const size_t estimated_size = estimated_frames * tar_channel * sizeof (float );
66+ const size_t estimated_size = static_cast < size_t >( estimated_frames * tar_channel * sizeof (float ) );
6367
6468 sf_vio_out.data .byteArray .reserve (estimated_size);
6569
6670 // 创建输出VIO的SndfileHandle
67- auto dstHandle = SndfileHandle (sf_vio_out.vio , &sf_vio_out.data , SFM_WRITE, sf_vio_in. info . format , tar_channel ,
68- tar_samplerate);
71+ auto dstHandle = SndfileHandle (sf_vio_out.vio , &sf_vio_out.data , SFM_WRITE, (SF_FORMAT_WAV | SF_FORMAT_FLOAT) ,
72+ tar_channel, tar_samplerate);
6973 if (!dstHandle) {
7074 msg = " Failed to open output VIO: " + std::string (sf_strerror (nullptr ));
7175 return {};
7276 }
7377
74- // 创建 SoX 重采样器
78+ // 创建 SoX 重采样器 - 使用正确的I/O规格
7579 soxr_error_t error = nullptr ;
76- const auto io_spec = soxr_io_spec (SOXR_FLOAT32_I, SOXR_FLOAT32_I);
80+ soxr_io_spec_t io_spec;
81+
82+ // 根据输入数据类型设置正确的I/O规格
83+ if (is_float_input) {
84+ io_spec = soxr_io_spec (SOXR_FLOAT32_I, SOXR_FLOAT32_I);
85+ } else {
86+ // 对于整数格式,使用正确的位深度
87+ int input_bits = 0 ;
88+ if (input_format == SF_FORMAT_PCM_16)
89+ input_bits = 16 ;
90+ else if (input_format == SF_FORMAT_PCM_24)
91+ input_bits = 24 ;
92+ else if (input_format == SF_FORMAT_PCM_32)
93+ input_bits = 32 ;
94+
95+ if (input_bits == 16 ) {
96+ io_spec = soxr_io_spec (SOXR_INT16_I, SOXR_FLOAT32_I);
97+ } else {
98+ // 24位和32位数据都使用INT32处理
99+ io_spec = soxr_io_spec (SOXR_INT32_I, SOXR_FLOAT32_I);
100+ }
101+ }
102+
77103 const auto quality_spec = soxr_quality_spec (SOXR_HQ, 0 );
78104 const auto runtime_spec = soxr_runtime_spec (1 ); // 单线程
79105
@@ -92,21 +118,55 @@ namespace AudioUtil
92118 return {};
93119 }
94120
95- // 使用适当的缓冲区大小
96- constexpr size_t BUFFER_FRAMES = 4096 ;
121+ // 使用较小的缓冲区以避免内存问题
122+ constexpr size_t BUFFER_FRAMES = 2048 ; // 减小缓冲区大小
97123 const size_t input_buffer_size = BUFFER_FRAMES * original_src_channels;
98- const size_t output_buffer_size = static_cast <size_t >(BUFFER_FRAMES * ratio * original_src_channels) + 1024 ;
124+ const size_t output_buffer_size =
125+ static_cast <size_t >((static_cast <double >(BUFFER_FRAMES) * ratio * original_src_channels) + 1024 );
99126
100- std::vector<float > input_buffer (input_buffer_size);
127+ // 根据输入格式分配正确的输入缓冲区
128+ std::unique_ptr<float []> float_input_buffer;
129+ std::unique_ptr<short []> short_input_buffer;
130+ std::unique_ptr<int []> int_input_buffer;
101131 std::vector<float > output_buffer (output_buffer_size);
102132
133+ void *input_buffer_ptr = nullptr ;
134+
135+ if (is_float_input) {
136+ float_input_buffer = std::make_unique<float []>(input_buffer_size);
137+ input_buffer_ptr = float_input_buffer.get ();
138+ } else {
139+ // 检查位深度以决定输入缓冲区类型
140+ if (input_format == SF_FORMAT_PCM_16) {
141+ short_input_buffer = std::make_unique<short []>(input_buffer_size);
142+ input_buffer_ptr = short_input_buffer.get ();
143+ } else {
144+ // 对于24位和32位数据,都使用int缓冲区
145+ int_input_buffer = std::make_unique<int []>(input_buffer_size);
146+ input_buffer_ptr = int_input_buffer.get ();
147+ }
148+ }
149+
103150 sf_count_t total_input_frames = 0 ;
104151 sf_count_t total_output_frames = 0 ;
105152 bool processing_error = false ;
106153
107154 while (!processing_error) {
108155 // 从源文件读取数据
109- const sf_count_t frames_read = srcHandle.readf (input_buffer.data (), BUFFER_FRAMES);
156+ sf_count_t frames_read = 0 ;
157+ if (is_float_input) {
158+ frames_read = srcHandle.readf (static_cast <float *>(input_buffer_ptr), BUFFER_FRAMES);
159+ } else {
160+ if (input_format == SF_FORMAT_PCM_16) {
161+ frames_read = srcHandle.readf (static_cast <short *>(input_buffer_ptr), BUFFER_FRAMES);
162+ } else {
163+ // 对于24位和32位数据,使用read函数而非readf
164+ sf_count_t items_read =
165+ srcHandle.read (static_cast <int *>(input_buffer_ptr),
166+ static_cast <sf_count_t >(BUFFER_FRAMES * original_src_channels));
167+ frames_read = items_read / original_src_channels;
168+ }
169+ }
110170
111171 if (frames_read <= 0 ) {
112172 break ;
@@ -115,7 +175,7 @@ namespace AudioUtil
115175 total_input_frames += frames_read;
116176
117177 // 计算这次读取的实际输入样本数(样本数 = 帧数 × 通道数)
118- const size_t input_samples = frames_read * original_src_channels;
178+ const size_t input_samples = static_cast < size_t >( frames_read) * original_src_channels;
119179
120180 // 处理重采样
121181 size_t input_done_total = 0 ; // 跟踪本次读取的总处理量
@@ -130,8 +190,13 @@ namespace AudioUtil
130190 size_t input_done = 0 ;
131191 size_t output_done = 0 ;
132192
133- error = soxr_process (resampler,
134- input_buffer.data () + input_done_total, // 输入指针
193+ // 确保输入指针偏移正确
194+ void *current_input_ptr = static_cast <char *>(input_buffer_ptr) +
195+ (input_done_total *
196+ (is_float_input ? sizeof (float )
197+ : (input_format == SF_FORMAT_PCM_16 ? sizeof (short ) : sizeof (int ))));
198+
199+ error = soxr_process (resampler, current_input_ptr,
135200 input_to_process, // 输入样本数
136201 &input_done, // 实际处理的输入样本数
137202 output_buffer.data (), // 输出缓冲区
@@ -340,13 +405,13 @@ namespace AudioUtil
340405 }
341406
342407 // 创建输出WAV文件
343- SndfileHandle outBuf (filepath.string (), SFM_WRITE, format , tar_channel, samplerate);
408+ SndfileHandle outBuf (filepath.string (), SFM_WRITE, (SF_FORMAT_WAV | SF_FORMAT_FLOAT) , tar_channel, samplerate);
344409 if (!outBuf) {
345410 std::cerr << " Failed to open output WAV file: " << sf_strerror (nullptr ) << std::endl;
346411 return false ;
347412 }
348413
349- constexpr size_t BUFFER_FRAMES = 4096 ;
414+ constexpr size_t BUFFER_FRAMES = 2048 ; // 减小缓冲区大小
350415 std::vector<float > buffer (BUFFER_FRAMES * channels);
351416 sf_count_t readFrames;
352417
0 commit comments