Друзья, сегодня потрясающий подарок для любителей помузицировать! На этой страничке Вы найдете лучшие виртуальные синтезаторы онлайн. Играть на них можно как при помощи клавиатуры, так и при помощи компьютерной мыши.
Попробуйте хотя бы несколько из них, и Вы непременно откроете в себе талант композитора. Приятное времяпрепровождение тоже гарантировано!
Внимание! Для отображения интерактивных элементов в статье вам понадобится установленный в системе (браузере) Adobe Flash Player.
Электронный орган
Хотите поиграть на органе онлайн? Это именно то, что Вам нужно. Данный инструмент имитирует звук органа, который так нравится многим людям.
Попробуйте сыграть вот этот отрывок из Менуэта Баха (клавиши, взятые в квадратные скобки надо играть одновременно):
[rsfh] lq[wd]e[rf] l l [tg] ert*[fu] l l [ed] rewq[sw] ewql[#h] [fl]q[sw]l[hw] [.q]
Чтобы отобразить подсказки к клавишам, нажмите «Notes» — «Computer Keyboard».
Ну как, получилось? Если нет – просто скопируйте эти ноты в верхнее окошко электронного органа и нажмите «Play».
Программный синтезатор
И так господа, решил наконец разобраться с программным синтезом музыки, а именно с практической частью реализации подобной задачи. Давайте посмотрим что из это вышло и как оно реализовано…
Создаем волны
Все мы прекрасно понимаем что звук это волна и что частота колебаний волны в от нулевого уровня соответствует частоте звуковой волны, а амплитуда этой волны отвечает за его силу или попросту говоря громкость, но в машинном представлении звук записанный в виде импульсно-кодовой модуляции это массив данных, каждый элемент которого представляет позицию волны в конкретный момент времени. Давайте рассмотрим простую звуковую волну в формате PCM лучше, для этого сначала напишем функцию которая будет моделью синусоидальной волны. Принимать она будет два значения — смещение и частоту. public static double Sine(int index, double frequency) { return Math.Sin(frequency * index); } А теперь добавим ее в класс Program и напишем главную функцию Main которая будет инициализировать массив данных длиной в 75 элементов который будет представлять наш звук и циклично заполним каждую его ячейку используя для этого только что написанную нами модель синусоиды. Чтобы рассчитать значение функции для конкретного смещения нам надо учесть период синусоиды равный 2 * Пи и умножить этот период на требующуюся нам частоту волны. Но для того чтобы понять какой же результирующей частоты выйдет звук в формате PCM нужно знать его частоту дискретизации. Частота дискретизации — частота выборки элементов за единицу времени, ну а если совсем упрощенно то это количество элементов массива на секунду, это значит что частота звука в формате PCM это частота волны разделенная на частоту его дискретизации. Давайте сгенерируем звуковую волну частотой 2 Гц при этом условимся что частота дискретизации будет равна 75 Гц. class Program { public static void Main(string[] args) { double[] data = new double[75]; // Инициализируем массив. for (int index = 1; index < 76; index++) { // Вычисляем данные для всего массива. data[index-1] = Sine(index, Math.PI * 2 * 2.0 / 75); // Период разделенный на частоту дискретизации. } Console.ReadKey(true); // Ждем нажатия любой клавиши. } public static double Sine(int index, double frequency) { return Math.Sin(frequency * index); } } И теперь чтобы увидеть результат нашей работы добавим в класс Program новую функцию способную визуализировать нашу функцию прямо в консоле (Так выйдет быстрее всего) поэтому вдаваться в ее подробности не будем. public static void Draw (double[] data) { Console.BufferHeight = 25; // Изменяем длину буфера консоли чтобы избавиться от ползунка. Console.CursorVisible = false; // отключаем курсор для красоты. for (int y = 0; y < 19; y++) {// Выписываем индексы уровня звука. Console.SetCursorPosition(77, y + 5);// Устанавливаем курсор в нужную позицию. Console.Write(9 — y); // Выписываем номер индекса уровня. } for (int x = 0; x < 75; x++) { // Перебираем все элементы массива Console.SetCursorPosition(x, x % 3); //Устанавливаем курсор в нужную точку. Console.Write(x + 1); // пишем индексы элемента. int point = (int)(data[x] * 9); // Вычисляем уровень и приводим его к амплитуде от -9 до 9. int step = (point > 0)? -1 : 1; // Узнаем в какую сторону 0. for (int y = point; y != step; y += step) {// перебираем столбик Console.SetCursorPosition(x, point + 14 — y); //Устанавливаем курсор в нужную позицию. Console.Write(«█»); // Рисуем точку. } } } Теперь мы можем увидеть как же выглядит наши два герца в машинном представлении.
Но ведь это только один вид волны в то время как существует множество других видов волн, давайте опишем функции способные моделировать основные типы волн и рассмотрим как они выглядят.
private static double Saw(int index, double frequency) { return 2.0 * (index * frequency — Math.Floor(index * frequency )) -1.0; }
Результат работы функции Saw
private static double Triangle(int index, double frequency) { return 2.0 * Math.Abs (2.0 * (index * frequency — Math.Floor(index * frequency + 0.5))) — 1.0; }
Результат работы функции Triangle
private static double Flat(int index, double frequency) { if (Math.Sin(frequency * index ) > 0) return 1; else return -1; }
Результат работы функции Flat
Учитывайте что период функции Sine и Flat равен 2 * Пи, а период функций Saw и Triangle равен единице.
Записываем Wav файл
Когда мы смогли создавать и даже рассмотреть наш звук хотелось бы его еще и услышать для этого давайте запишем его в контейнере .wav и прослушаем. Правда пока мы не знаем как устроен контейнер Wave, надо исправить эту досадную ошибку! Итак wave файл очень простой он состоит из трех частей, первая это блок-заголовок, вторая это блок формата, третья это блок данных. Все вместе это выглядит так:
Собственно все предельно ясно, подробности по каждому из пунктов описаны здесь. Поскольку наша задача предельно простая мы будем использовать всегда разрядность равную 16 битам и только одну дорожку. Функция которую я сейчас напишу будет сохранять наш PCM звук в контейнере Wav внутрь потока, что позволит сделать работу более гибкой. Итак вот как она выглядит. public static void SaveWave(Stream stream, short[] data, int sampleRate) { BinaryWriter writer = new BinaryWriter(stream); short frameSize = (short)(16 / 8); // Количество байт в блоке (16 бит делим на 8). writer.Write(0x46464952); // Заголовок «RIFF». writer.Write(36 + data.Length * frameSize); // Размер файла от данной точки. writer.Write(0x45564157); // Заголовок «WAVE». writer.Write(0x20746D66); // Заголовок «frm «. writer.Write(16); // Размер блока формата. writer.Write((short)1); // Формат 1 значит PCM. writer.Write((short)1); // Количество дорожек. writer.Write(sampleRate); // Частота дискретизации. writer.Write(sampleRate * frameSize); // Байтрейт (Как битрейт только в байтах). writer.Write(frameSize); // Количество байт в блоке. writer.Write((short)16); // разрядность. writer.Write(0x61746164); // Заголовок «DATA». writer.Write(data.Length * frameSize); // Размер данных в байтах. for (int index = 0; index < data.Length; index++) { // Начинаем записывать данные из нашего массива. foreach (byte element in BitConverter.GetBytes(data[index])) { // Разбиваем каждый элемент нашего массива на байты. stream.WriteByte(element); // И записываем их в поток. } } } Видите как все просто, а главное теперь мы можем услышать наш звук, давайте сгенерируем 1 секунду ноты ля первой октавы, его частота 440 Гц, при такой задаче функция Main будет иметь такой вид public static void Main(string[] args) { int sampleRate = 8000; // наша частота дискретизации. short[] data = new short[sampleRate]; // Инициализируем массив 16 битных значений. double frequency = Math.PI * 2 * 440.0 / sampleRate; // Рассчитываем требующуюся частоту. for (int index = 0; index < sampleRate; index++) { // Перебираем его. data[index] = (short)(Sine(index, frequency) * short.MaxValue); // Приводим уровень к амплитуде от 32767 до -32767. } Stream file = File.Create(«test.wav»); // Создаем новый файл и стыкуем его с потоком. SaveWave(file, data, sampleRate); // Записываем наши данные в поток. file.Close(); // Закрываем поток. } Запускаем программу и о чудо! У нас появился test.wav загрузив его в плеере слушаем пищание до достижения катарсиса и двигаемся дальше. Давайте рассмотрим нашу волну со всех сторон на осцилографе и спектрограмме чтобы убедиться что мы получили именно тот результат которого добивались.
Но в жизни звуки звучат не бесконечно, а стихают давайте напишем модификатор который будет глушить наш звук со временем. Ему потребуются абсолютные величины поэтому передадим ему коэффициент, текущую позицию, частоту, множитель коэффициента и частоту дискретизации, а абсолютные величины он вычислит сам, коэффициент всегда должен быть отрицательным.
public static double Length(double compressor, double frequency, double position, double length, int sampleRate){ return Math.Exp(((compressor / sampleRate) * frequency * sampleRate * (position / sampleRate)) / (length / sampleRate)); } Строку которая вычисляет уровень звука тоже нужно изменить. data[index] = (short)(Sine(index, frequency) * Length(-0.0015, frequency, index, 1.0, sampleRate) * short.MaxValue); Теперь на осцилографе мы увидим совсем другую картину.
Пишем музыку
Раз уж нам удалось сыграть ноту la четвертой октавы нам никто не мешает играть разные ноты. А вам никогда не было интересно как узнать частоты нот? Оказываться есть прекрасная формула 440 * 2 ^ (абсолютный индекс ноты / 12). Если вы взгляните на любой пиано-подобный инструмент то вспомните что на нем есть блоки по 7 белых клавиш и 5 черных, блоки это октавы, белые клавиши это основные ноты (до, ре, ми, фа, соль, ля, си) а черные их полутона, то есть всего 12 звуков в октаве это называется равномерно темперированный строй. Давайте рассмотрим график этой функции.
Но записывать ноты мы будем в научной нотации поэтому немного изменим формулу опустив ее на 4 октавы и запишем ее в родном для нас виде. private static double GetNote(int key, int octave) { return 27.5 * Math.Pow(2, (key + octave * 12.0) / 12.0); } Теперь когда мы собрали базовый функционал и отладили его работу давайте продумаем архитектуру будущего синтезатора. Синтезатор будет представлять из себя некий набор объектов elements которые будут синтезировать звук и накладывать его на пустой массив данных в нужном месте, этот массив и объекты elements будут содержаться в объекте track. Классы описывающие их будут содержаться в пространстве имен Synthesizer, давайте опишем класс Element и Track public class Element { int length; int start; double frequency; double compressor; public Element(double frequency, double compressor, double start, double length, int sampleRate) { this.frequency = Math.PI * 2 * frequency / sampleRate ; this.start = (int)(start * sampleRate); this.length = (int)(length * sampleRate); this.compressor = compressor / sampleRate; } public void Get(ref short[] data, int sampleRate) { double result; int position; for (int index = start; index < start + length * 2; index++) { position = index — start; result = 0.5 * Sine(position, frequency) ; result += 0.4 * Sine(position, frequency / 4); result += 0.2 * Sine(position, frequency / 2); result *= Length(compressor, frequency, position, length, sampleRate) * short.MaxValue * 0.25; result += data[index]; if (result > short.MaxValue) result = short.MaxValue; if (result < -short.MaxValue) result = -short.MaxValue; data[index] = (short)(result); } } private static double Length(double compressor, double frequency, double position, double length, int sampleRate){ return Math.Exp((compressor * frequency * sampleRate * (position / sampleRate)) / (length / sampleRate)); } private static double Sine(int index, double frequency) { return Math.Sin(frequency * index); } } public class Track { private int sampleRate; private List elements = new List(); private short[] data; private int length; private static double GetNote(int key, int octave) { return 27.5 * Math.Pow(2, (key + octave * 12.0) / 12.0); } public Track(int sampleRate) { this.sampleRate = sampleRate; } public void Add(double frequency, double compressor, double start, double length) { if (this.length < (start+ length * 2 + 1) * sampleRate) this.length = (int)(start + length * 2 +1) * sampleRate; elements.Add(new Element(frequency, compressor, start, length, sampleRate)); } public void Synthesize() { data = new short[length]; foreach (var element in elements) { element.Get(ref data, sampleRate); } } } Теперь мы пришли к последней функции которая будет читать строку с нотами и генерировать нашу мелодию Для этого создадим Dictionary который будет ассоциировать названия нот с индексами, а также будет содержать управляющие ключи/индексы. Сама функция будет разбивать строку на слова и дальше обрабатывать каждое слово по отдельности разделяя его на две части — левую и правую, правая часть всегда состоит из одного символа (цифры) которая записывается в переменную октава как число, а длина первой части это длина слова — 1 (то есть слово минус правая часть) и дальше служит ключом к нашему словарю который возвращает индекс ноты, после того как мы разобрали слово мы решим что делать, если индекс управляющий то мы выполним соответствующую индексу функцию, а если нет то это значит что мы имеем индекс ноты и мы добавим к нашему треку новый звук нужной нам длины и частоты нашей ноты. public void Music (string melody, double temp = 60.0) { string[] words = melody.Split(‘ ‘); foreach (string word in words) { int note = notes[word.Substring(0, word.Length — 1)]; int octave = Convert.ToInt32(word.Substring(word.Length — 1, 1)); if (note > 2){ switch (note) { case 3: dtime = Math.Pow(0.5, octave + 1) * 8 * (60.0 / temp); break; case 4: length += (int)(Math.Pow(0.5, octave + 1) * 8 * (60.0 / temp)); position += Math.Pow(0.5, octave + 1) * 8 * (60.0 / temp); break; } } else { Add(GetNote(note, octave), -0.51, position, dtime); position += dtime; } } }
С этого момента мелодию можно записать в виде L4 B6 S4 D7 B6 F#6 S4 B6 F#6 Где L команда задающая длину ноты, а S создает паузу, остальные символы это ноты. Собственно на этом написание программного синтезатора закончено и мы можем проверить результат прослушав отрезочек «шутки Баха»
Бинарный файл Исходный код
Синтезатор космической музыки
Этот синтезатор сам по себе выглядит космически – хрустальный куб, нажатие граней которого запускает воспроизведение звуков. Много говорить о нем не буду – пробуйте сами и получайте удовольствие
Напоследок еще парочка онлайн синтезаторов с возможностью игры на клавиатуре, которые чем-то схожи между собой, но каждый из них обладает рядом своих неповторимых «фишек»:
Если Вам понравилось, поиграйте также на виртуальных гитарах и онлайн пианино.
Виртуальный синтезатор — Tone2 — Gladiator 2 2.6 VSTi (x64)
Tone2 — Gladiator 2
— мощный виртуальный синтезатор заслуживающий особого внимания от компании Tone2. Этот инструмент, пожалуй, самый лучший среди инструментов подобного размера. Синт Tone2 имеет новый тип синтеза, позволяющий получить плотный широкий звук. Доступны HCM, FM, и AM искажения. Имеется огромное количество пресетов распределенных по категориям, содержащие весь ряд синтезированных инструментов и эффектов. Звук его очень мягкий, теплый и что не мало важно — профессиональный. На ряду с такими монстрами как Nexus, Atmosphere и другими объемными синтезаторами, Tone2 Gladiator звучит так же сочно и серьезно. При этом в новой, последней версии синтезатора Gladiator 2 доступно множество визуальных настроек, позволяющих изменить выбранный звук до не узнаваемости. Метод синтеза — HCM. Рекомендуем, версия от всеми любимого AiR. В завершении хочется сказать, что данный синтезатор является самым популярным на нашем сайте, этот инструмент скачивается вами самое большое количество раз.
Системные требования:
Процессор :
Multicore processor in excess of 2GHz is recommended
Windows :
7/8/8.1/10
Оперативная память :
2GB or more
DAW :
FL Studio / Cakewalk Sonar / Steinberg Cubase и т.д.
Торрент Виртуальный синтезатор — Tone2 — Gladiator 2 2.6 VSTi (x64) подробно:
• Огромный звуковой диапазон: уникальный аналоговый тёплый прозрачный и жирный звук. • Низкая загрузка процессора. • Полумодульный состав: гибкий и расширяемый. • Более 1000 пресетов. • Декодирование полного стерео и Dolby Prologic II. • До 18 осцилляторов на голос. 4х стерео-унисон. • 110 различный типов осцилляторов с 36865-ю волноформами. • 162-кратная передискретизация. • Психоакустическая обработка. • 41 уникальный фильтр (аналоговый, вокальный, комбинированный, типа Moog, фейзер, эквалайзер и т. д.). • 20 различных эффектов. • 7 типов искажения для получения тёплого аналогового звучания. • Программируемый арпеджиатор, шаговый LFO и транс-гейт. • Синхронизация по темпу. • IQM для более чистых аккордов (intelligent microtuning).
Процедура лечения: 1. Хостс
1. Открываем командную строку(от имени администратора). 2. Вписываем notepad C:\Windows\System32\drivers\etc\hosts и жмём Enter. 3. Добавляем в открывшийся файл hosts:
127.0.0.1 tone2.com 127.0.0.1 www.tone2.com 127.0.0.1 tone2.net 127.0.0.1 www.tone2.net 127.0.0.1 www.tone2.org
И сохраняем изменения.
2. Папку Gladiator 2.6 x64 копируем в C:\Program Files\VSTPlugins 3. Сканируем свой DAW на наличие новых плагинов.
Demo: