基本概念
重采样器设计原理:
- 支持重采样参数的设置
- 支持不同形式的源输入,如frame ,int**
data - 支持不同形式的输出,如frame, int ** ou
- 支持pts (显示时间戳)
- 支持获取指定采样点数
- 支持flush
流程
读取采样点----> SwrContext------> AVAudioFifo----> 输出修改后采样点
若不需要调整音频格式,需调整采样点,直接将输入数据存储到AVAudioFifo
api
// 重采样的参数
typedef struct audio_resampler_params;
// 封装的重采样器
typedef struct audio_resample;
/**
* @brief 分配重采样器
* @param resampler_params 重采样的设置参数
* @return 成功返回重采样器;失败返回NULL
*/
audio_resampler_t *audio_resampler_alloc(const audio_resampler_params_t resampler_params);
void audio_resampler_free(audio_resampler_t *resampler);
/**
* @brief 发送要进行重采样的帧
* @param resampler
* @param frame
* @return 这次重采样后得到的采样点数
*/
int audio_resampler_send_frame(audio_resampler_t *resampler, AVFrame *frame);
/**
* @brief 获取重采样后的数据
* @param resampler
* @param nb_samples 我们需要读取多少采样数量: 如果nb_samples>0,只有audio fifo>=nb_samples才能获取到数据;nb_samples=0,有多少就给多少
* @return 如果获取到采样点数则非NULL
*/
AVFrame *audio_resampler_receive_frame(audio_resampler_t *resampler, int nb_samples);
code
// 重采样的参数
typedef struct audio_resampler_params {
// 输入参数
enum AVSampleFormat src_sample_fmt;
int src_sample_rate;
uint64_t src_channel_layout;
// 输出参数
enum AVSampleFormat dst_sample_fmt;
int dst_sample_rate;
uint64_t dst_channel_layout;
}audio_resampler_params_t;
// 封装的重采样器
typedef struct audio_resampler {
struct SwrContext *swr_ctx; // 重采样的核心
audio_resampler_params_t resampler_params; // 重采样的设置参数
int is_fifo_only; // 不需要进行重采样,只需要缓存到 audio_fifo
int is_flushed; // flush的时候使用
AVAudioFifo *audio_fifo; // 采样点的缓存
int64_t start_pts; // 起始pts
int64_t cur_pts; // 当前pts
uint8_t **resampled_data; // 用来缓存重采样后的数据
int resampled_data_size; // 重采样后的采样数
int src_channels; // 输入的通道数
int dst_channels; // 输出通道数
int64_t total_resampled_num; // 统计总共的重采样点数,目前只是统计
}audio_resampler_t;
int main()
{
//重采样
do {
/* generate synthetic audio */
// 生成输入源
fill_samples((double *)src_data[0], src_nb_samples, src_nb_channels, src_rate, &t);
int ret_size = audio_resampler_send_frame2(resampler, src_data, src_nb_samples, in_pts);
in_pts += src_nb_samples;
ret_size = audio_resampler_receive_frame2(resampler, dst_data, dst_nb_samples, &out_pts);
if(ret_size > 0) {
dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
ret_size, dst_sample_fmt, 1);
if (dst_bufsize < 0) {
fprintf(stderr, "Could not get sample buffer size\n");
goto end;
}
printf("t:%f in:%d out:%d, out_pts:%"PRId64"\n", t, src_nb_samples, ret_size, out_pts);
fwrite(dst_data[0], 1, dst_bufsize, dst_file);
} else {
printf("can't get %d samples, ret_size:%d, cur_size:%d\n", dst_nb_samples, ret_size,
audio_resampler_get_fifo_size(resampler));
}
} while (t < 10); // 调整t观察内存使用情况
// ...
}
本文详细介绍了音频重采样器在iOS开发中的基本概念、参数设置、API使用以及流程,包括AVAudioFifo和AVSampleFormat在音频格式调整中的作用。
585

被折叠的 条评论
为什么被折叠?



