pitch_freqs = freqs[peak_indices]
时间: 2024-05-18 09:16:01 浏览: 69
这行代码从频率数组 `freqs` 中提取了每个帧的基频频率,并将这些频率存储在 `pitch_freqs` 变量中。具体来说,这个代码使用了前面计算得到的每个帧中振幅最大的频率分量的索引数组 `peak_indices`,并使用它来索引 `freqs` 数组,提取每个帧的基频频率。由于 `peak_indices` 是针对每行而言的,因此 `pitch_freqs` 是一个长度为帧数的一维数组,其中每个元素表示对应帧的基频频率。
相关问题
for i = 1:fn % 提取当前帧 current_frame = y(:,i); % 计算当前帧的 Stockwell 变换,将频率范围限制在 0 到 4000 Hz [st_matrix, ~,~] = st(current_frame,0,fs/2,fs,1); % 将当前帧的 Stockwell 变换结果存储到 st_matrices st_matrices{i} = st_matrix; b = abs(st_matrix); % 计算帧的能量 frame_energy = sum(b.^2); if frame_energy > energy_threshold % 寻找模值最大的位置 [~, max_peak_idx] = max(b); max_peak_idx = max_peak_idx(1); % 计算基频 pitch_frequency = fs /max_peak_idx; if pitch_frequency > 1000 || pitch_frequency < 70 pitch_frequencies(i)=0; continue; end % 估计基音周期 pitch_period = 1/pitch_frequency; % 存储基音周期和基频 pitch_periods(i) = pitch_period; pitch_frequencies(i) = pitch_frequency; end end优化计算基频的代码
可以使用自相关函数来进行基频的估计,具体实现可以将信号进行自相关,然后找到自相关函数的第一个峰值,该峰值对应的位置即为基音周期,基音频率即为采样率除以基音周期。
下面是使用自相关函数进行基频估计的代码示例:
```
for i = 1:fn
% 提取当前帧
current_frame = y(:,i);
% 计算自相关函数
autocorr_values = xcorr(current_frame);
% 找到自相关函数的第一个峰值
[~, max_peak_idx] = max(autocorr_values);
pitch_period = max_peak_idx - 1;
% 计算基频
pitch_frequency = fs / pitch_period;
if pitch_frequency > 1000 || pitch_frequency < 70
pitch_frequencies(i) = 0;
continue;
end
% 存储基音周期和基频
pitch_periods(i) = pitch_period;
pitch_frequencies(i) = pitch_frequency;
end
```
这样的实现可以大大减少计算量,提高基频估计的效率。
b是个矩阵,这段代码是否有误 [max_value, max_peak_idx] = max(b); max_v = max(max_value(:)); [row, col] = find(max_value == max_v); max_peak_idx = col; pitch_frequency = fs /(max_peak_idx-1);
这段代码可能有误。根据代码来看,首先使用`max`函数获取矩阵`b`的最大值和最大值所在的下标,然后再使用`max`函数获取最大值,接着使用`find`函数查找最大值在矩阵`max_value`中的行列下标,最后计算基频。
问题在于,在使用`[row, col] = find(max_value == max_v)`查找最大值在矩阵`max_value`中的行列下标时,可能存在多个最大值,而这段代码只返回了其中一个最大值的列下标,忽略了其他可能存在的最大值,因此可能会导致计算基频的结果不正确。
如果你想要找到所有最大值及其对应的行列下标,可以使用`find`函数的输出形式:`[row, col, max_value] = find(b == max(b(:)))`。这将返回所有最大值的行、列和值。
阅读全文