Минута програмиране за възрастни как да разтегнете звука и как да промените ключа
Не е тайна, че ако пуснете звук по-бързо, тогава тонът на звука му ще се промени и, разбира се, продължителността ще намалее.
Това е една от най-простите трансформации, които могат да бъдат направени със звук. Но какво ще стане, ако трябва да промените темпото на възпроизвеждане на звука, но да оставите тона същия? Или обратното, сменете тона, без да докосвате продължителността?
Тъй като височината и продължителността могат да се променят едновременно чрез регулиране на темпото на възпроизвеждане, двете задачи могат да бъдат сведени до една: ако например е възможно да се промени произволно темпото, като се поддържа височината, тогава обратно пропорционална промяна в скоростта на възпроизвеждане ще промени височината съответно, връщайки темпото в първоначалното му състояние.
Тук публикувах пояснителна снимка:
Мисля, че всичко е ясно от снимката, но за всеки случай ще напиша обяснения:
1.Оригиналният сигнал е разделен на фрагменти и фрагментите се припокриват в по-голямата си част. Важно е да се подходи към избора на дължината на всеки фрагмент: ако фрагментът е твърде кратък, тогава преобразуването няма да повлияе на ниските честоти на звука, който не е попаднал във фрагмента, ако е твърде дълъг, тогава ще се появи неприятен тръбен звук, поради факта, че ухото ще има време да различи промените във фрагментите. Идеалната продължителност на фрагмента е около 50 ms. Но използването на FFT силно ни ограничава до избора на продължителността на фрагментите като кратно на степен две. Според моя опит, за скорост на възпроизвеждане от 44100 проби в секунда, най-добрият резултат се получава с фрагменти с дължина 2048 проби.
Лесно е да се изчисли, че за обработка на звук в реално време, с такива параметри, ще е необходимо да се извършват около 345 пълни цикъла на обработка на звук всяка секунда.
2.И така, един от фрагментите на оригиналния звук е избран и цикълът от трансформации започва с него.
3.Тъй като най-големите FFT грешки се натрупват в краищата на прозореца, сигналът трябва да бъде филтриран чрез намаляване на амплитудата му в краищата чрез умножаване по функцията за филтър на прозореца.
Преди да възстановите звука, в стъпка 10 ще бъде приложен и прозоречен филтър, така че функциите на входния и изходния филтър трябва да бъдат избрани така, че сумата от техните продукти във всяка точка, като се вземе предвид степента на припокриване, винаги да е равна на единица.
Без да навлизам в подробности, ще кажа, че с помощта на функцията се получава добър резултат
f(i) = sin((Π / 2) * sin(Π * (i / N))²)
където Π е pi (3.14159…); N - дължина на прозореца, i - номер на пробата в прозореца (от 0 до N - 1)
4.FFT работи с комплексни числа и оригиналният сигнал е реален. За да се подготви масив за трансформация, оригиналната извадка просто се копира в реалната част на комплексното число, докато имагинерната част остава нула.
Сега можете да извършите преобразуването.
5.Тъй като всички наши въображаеми части бяха нула, полученият спектър се оказа симетричен. Само имагинерната част в дясната половина има обратен знак. Следователно дясната страна на спектъра може безопасно да бъде изхвърлена.
Като цяло реалната част на i-тия елемент на масива (хармоници) означава амплитудата на косинуса на честотата 2 * Π * i / N, а въображаемата част означава синуса.
Лесно е да се види, че за нулевия хармоник в целия този косинус ще бъде равен на единица, а синусът ще бъде нула. С други думи, имагинерната част на нулевия хармоник винаги е равна на нула, а реалната част е средноаритметичното на оригиналния сигнал за целия прозорец, т.е. показва неговото отместване.
6.За всеки хармоник от спектъракомплексното число трябва да се преобразува в полярни координати. Сега l е амплитудата на съответния честотен компонент, а α е фазовото отместване, т.е. колко далеч е горната точка на синусоидата от началото на прозореца.
7.Нека си представим следната ситуация: имаме продължителен звук, например синусоида. Ако честотата на синусоидата съвпада с честотата на един от хармониците, тогава само този хармоник ще присъства в спектъра, но фазата α ще се променя при всяка итерация в зависимост от това върху коя част от синусоидата попада началото на прозореца. Не е трудно да се досетите, че разликата между фазите в две съседни итерации ще бъде постоянна.
Ако искаме да разтегнем монотонното си бръмчене във времето, тогава картината не трябва да се променя, пак ще си остане същото бръмчене и скоростта на промяна на фазата ще бъде абсолютно същата.
Представете си сега, че амплитудата на бръмчаща синусоида нараства с времето. Сега разтягането му във времето ще означава интерполиране на стойностите на амплитудите (l), но разликата между фазите в две съседни итерации отново ще се промени със същата скорост.
Всъщност тази идея е в основата на алгоритъма: 1) за всеки хармоник при всяка итерация разглеждаме скоростта на промяна на фазата - т.е. разликата с фазата от предишната итерация. 2) получената стойност на скоростта се добавя към фазовата стойност на същия хармоник от предишната итерация на изходния спектър, независимо дали ускоряваме или забавяме възпроизвеждането. 3) стойността на хармоничната амплитуда в изходния спектър се получава чрез интерполация.
В параграф 2 са възможни варианти - например да се получи стойността на фазовата скорост също чрез интерполация, но същността остава същата: не фазата играе важна роля, а скоростта на нейното изменение, което се възпроизвежда в изходния спектър.
8.След получаване на изходния спектър, ние възстановяваме дясната му страна по огледален начин. В този случай имагинерната част се взема с обратен знак.
9.След това можете да извършите обратна бърза трансформация на Фурие върху получения спектър, поради факта, че спектърът е огледален, имагинерните части на резултата ще бъдат нула, а изходният сигнал ще бъде реален.
10.Тогава изходният сигнал трябва да бъде умножен по филтъра на прозореца. Тук използвам същата формула като в стъпка 3, последвана от разделяне на половината от степента на припокриване.
11.Полученият сигнал се добавя, като се вземе предвид степента на припокриване, с резултатите от предишни и следващи итерации
12.Изходният сигнал е готов, можете да го изведете на аудио устройство или да го запишете във файл - каквото ви е по-близо.
За да промените тона с N пъти, звукът се разтяга (т.е. забавя) със същите N пъти и след това възпроизвеждането се ускорява с N пъти, което води до промяна на тона, като същевременно се запазва оригиналното темпо на възпроизвеждане.