CodeWhiz & Kompot
CodeWhiz CodeWhiz
Привет, я тут что-то мутил, приложение, которое на ходу аккорды для импровизации генерит. Хочешь послушать, как оно работает?
Kompot Kompot
Отлично! Давай посмотрим, что у тебя получилось, я в деле.
CodeWhiz CodeWhiz
Вот небольшой скетч на JavaScript, который строит последовательность аккордов и проигрывает её с помощью Tone.js. Я расскажу тебе о тех частях, которые делают её "магической". ```javascript // 1. Базовая настройка import * as Tone from 'tone' const synth = new Tone.PolySynth(Tone.Synth).toDestination() // 2. Определяем простой словарь аккордов const chords = { I: [0, 4, 7], // тоника, большая терция, чистая квинта ii: [2, 5, 9], iii: [4, 8, 11], IV: [5, 9, 12], V: [7, 11, 14], vi: [9, 12, 16], vii: [11, 14, 17] } // 3. Помощник для получения полутоновых смещений от основной ноты const scale = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] function getChord(root, chordName) { const rootIdx = scale.indexOf(root) const offsets = chords[chordName] return offsets.map(o => scale[(rootIdx + o) % 12]) } // 4. Генератор случайной последовательности function randomProgression(length = 4) { const chordNames = Object.keys(chords) let prog = [] for (let i = 0; i < length; i++) { const idx = Math.floor(Math.random() * chordNames.length) prog.push(chordNames[idx]) } return prog } // 5. Воспроизведение последовательности async function playProgression(root = 'C') { const seq = new Tone.Sequence( (time, chordName) => synth.triggerAttackRelease(getChord(root, chordName), '8n', time), randomProgression(), '4n' ) seq.start(0) Tone.Transport.start() } // 6. Нажимай кнопку playProgression('D') // Меняй основную ноту на ту, что тебе нравится ``` **Как это работает** 1. *Данные аккордов*: Я веду простой словарь из семи диатонических аккордов. Каждый аккорд выражен как полутоновые смещения от его тоники. 2. *Ориентировано на тонику*: Помощник `getChord` подбирает нужные ноты для любой тоники. Это значит, что ты можешь играть в любой тональности, просто меняя строку тоники. 3. *Рандомизатор*: `randomProgression` выбирает случайную горстку аккордов - не больше четырех по умолчанию. Если хочешь больше вариаций, подкорректируй аргумент `length`. 4. *Секвенсирование*: `Sequence` от Tone.js занимается таймингом. Каждый четверть-такт вызывает синтезатор с восьмой-нотной отработкой. 5. *Мгновенное воспроизведение*: Просто вызови `playProgression` с тоникой, и ты услышишь свежий четырех-аккордовый цикл каждый раз. Если тебе удобно в консоли браузера, вставь скрипт, нажимай `playProgression('E')` и пусть искусственный интеллект создает гармонию. Не стесняйся корректировать список аккордов, добавлять септаккорды или заменять синтезатор другим голосом — этот скелет намеренно легкий, чтобы ты мог быстро экспериментировать. Дай знать, как звучат циклы и хочешь ли ты более сложной логики прогрессии. Приятного джеминга!
Kompot Kompot
Звучит круто! Давай запустим и посмотрим, какие там аккорды выпадают — может, подкинем другой синтезатор или добавим септаккорды для изюминки. Какую атмосферу хочешь создать?
CodeWhiz CodeWhiz
Конечно. Если хочешь более насыщенное, джазовое звучание, замени обычный синтезатор на Tone.Sampler с классическим семплом Rhodes, или используй Tone.PolySynth с эффектом Pizzicato. Чтобы добавить септимы, просто подправь словарь аккордов: I: [0, 4, 7, 10] // мажорная септима ii: [2, 5, 9, 12] … и так далее. Это даст тебе плавные, расширенные гармонии, создающие атмосферу меланхоличного, ночного настроения. Скажи, какую тональность выберешь, и я попробую сделать для тебя.
Kompot Kompot
Крутая идея! Давай в соль мажоре – там как-то по-домашнему, но и светло для импровизации. Бери свой сэмплер, включай Rhodes, попробуй эти расширенные аккорды. Я готов, как только нажмёшь кнопку воспроизведения!
CodeWhiz CodeWhiz
Вот небольшой отрывок, использующий сэмплер Rhodes и расширенный список аккордов в тональности G. Просто скопируй это в консоль браузера, где загружен Tone.js, и нажми Enter. ```js // Load the Rhodes sample const rhodes = new Tone.Sampler({ urls: { A1: 'A1.mp3', A2: 'A2.mp3', A3: 'A3.mp3' }, baseUrl: 'https://example.com/rhodes/', // put your sample folder here onload: () => { console.log('Rhodes ready') playProgression('G') } }).toDestination() // Extended chord dictionary const chords = { I: [0, 4, 7, 10], ii: [2, 5, 9, 12], iii: [4, 8, 11, 15], IV: [5, 9, 12, 16], V: [7, 11, 14, 18], vi: [9, 12, 16, 19], vii: [11, 14, 17, 21] } // Helper for root‑based chords const scale = ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'] function getChord(root, name){ const rootIdx = scale.indexOf(root) return chords[name].map(o => scale[(rootIdx+o)%12]) } // Random progression function randomProg(len=4){ const keys = Object.keys(chords) return Array.from({length:len},()=>keys[Math.floor(Math.random()*keys.length)]) } // Play it function playProgression(root){ const seq = new Tone.Sequence( (time, name)=>rhodes.triggerAttackRelease(getChord(root,name), '8n', time), randomProg(), '4n' ) seq.start(0) Tone.Transport.start() } ``` Получится уютный G-мажорный луп с приятными септимами. Дай знать, как звучит.
Kompot Kompot
Вот это классная аппаратура – представь, как рояль заполняет комнату этим тёплым ночным светом. Запускай же трек, дай циклу пойти и скажи, хочешь ли ты свинга или более плавного переключения. Я готов к любому развитию событий!