реклама на сайте
подробности

 
 
> [MatLab] Модель полосного вокодера (channel vocoder), Куда копать?
Оксюморон
сообщение Sep 27 2010, 08:00
Сообщение #1





Группа: Новичок
Сообщений: 3
Регистрация: 22-09-10
Пользователь №: 59 645



Добрый день! Понемногу делаю модель простейшего полосного вокодера. Собственно, идея заключается в:
1. Сигнал нарезается по 20 мс не перекрывающихся сегменты;
2. Для каждого сегмента проводим БПФ (кол-во точек определяет точность);
3. Спектр каждого сегмента "нарезается" на заданное кол-во полос;
4. Огибающая усредняется и готова к передаче;

Восстановление:
1. "Собираем" спектр сегмента назад;
2. Проводим обратное БПФ;
3. "Склеиваем" сегменты назад во временной области;

Код матлабовской функции:
Код
function [ y ] = channel( x, seg_length, F_orig, N_chan, N_points )
%CODEC полосный кодер
%   x - массив входящих отсчетов
%   seg_length - длина сегмента для обработки [с]
%   F_orig - частота отсчетов оригинального сигнала
%   N_chan - количество подполос
%   N_points - кол-во точек преобразования

% Определяем длину оригинального сигнала
overall_length = length(x);

% Определяем кол-во отсчетов в сегменте обработки
seg_samples = F_orig*seg_length;

% Приводим кол-во отсчетов оригинального сигнала к кратному длине сегмента
x(overall_length+1:ceil(overall_length/seg_samples)*seg_samples) = 0;
i = 0;

% Индексы подполос

bands = 1:round(N_points/N_chan):N_points;
bands(end) = N_points;

% Задаем длину обработанного сигнала и заполняем его нулями
y = zeros(size(x));

% Перебираем сегменты
while i*seg_samples < overall_length
    % Проводим БПФ текущего сегмента
    index = 1+i*seg_samples:seg_samples*i+seg_samples;
    spectrum = real(fft( x(index), N_points*2 ));
  
    % Для каждой подполосы
    for j = 1:N_chan-1
        % Текущие индексы подполосы
        band_cur = [bands(j):bands(j+1)-1];
        % Получем усредненную энергию подполосы
        band_avg = mean(spectrum(band_cur));
        % Собираем спектр назад здесь же
        ench_spectrum(j) = band_avg;
    end
    ench_sample = real(ifft(ench_spectrum, seg_samples, 'symmetric'));
    y(index) = ench_sample;
    
    % Переходим к следующему сегменту
    i = i+1;
end

y = y/max(abs(y))*0.8;
end



Моменты, связанные с непосредственной передачей опущены, т.к. задача это исследование субъективного качества голоса при кодировании.

Столкнулся со следующими проблемами:
При увеличении кол-ва полос спектр относительно исходного "размывается", полагаю, что это может быть связано с тем, что при восстановлении мы в конце концов получаем ступенчатую функцию, состоящую из 20 мс отрезков.
Становится что-то слышно только на 64 каналах, хотя и на 16 уже должно быть возможным разобрать хотя бы отдельные слова.

Куда копать? Кодер простейший, но реализаций похожих не видел к сожалению.

PS Задачи производительности кода сейчас не рассматриваю и поэтому в коде много вещей, которые можно было бы сократить, но они оставлены для наглядности процесса =)
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 17th June 2025 - 10:59
Рейтинг@Mail.ru


Страница сгенерированна за 0.0137 секунд с 7
ELECTRONIX ©2004-2016