Подготовка
Куб
При исследовании подобных проектов была обнаружена реализация под названием «Чарликуб» («Charliecube») за авторством Эшера Глика (Asher Glick) и Кевина Бэйкера (Kevin Baker). Данный вариант примечателен тем, что, в отличие от других реализаций, не предусматривает наличие счётчиков, регистров сдвига либо каких-либо других компонентов для построения куба с целью его последующего программирования и задействует только 16 выводов микроконтроллера (позволяя при этом адресовать 64 светодиода). В основе этой реализации лежит конструкция светодиодной индикации под названием «Чарлиплексинг».
Чарлиплексинг
Цифровые выводы микроконтроллеров имеют трёхзначную логику: присоединён к питанию, присоединён к «земле» и не посоединён ни к чему. Если нам надо зажечь светодиод, необходимо подать "+" на X и "-" на «Y», только в таком случае он будет гореть. Если на Y ничего не подавать, до светодиод не загорится. Подробнее о методе можно почитать в одноимённой статье на Википедии, ниже приведено описание работы конкретно в нашем случае.
схема столбика светодиодов
Предположим, что мы хотим зажечь LED1 зелёным цветом. Если проследить по синей линии, видно, что необходимо подать "+" на вход 1. Проследив за красной линией, понимаем, что нужно подать "-" на вход 3. На остальные входы ничего не подаётся.
Визуализация
Было решено, что весь анализ музыки будет производится на подключённом к кубу ПК. Основная идея: ПК анализирует канал записи звука, преобразует звук в информацию о частотах и передаёт данные о ритме музыки в Arduino.Далее микроконтроллер на основе этой информации подсвечивает определённые светодиоды.
Поскольку у авторов проекта большой опыт работы с Ruby, в рамках проекта хотелось прибегнуть именно к этому языку программирования. Была обнаружена статья Дэвида Гутмана (David Guttman), описывающая визуализацию звука на JRuby с помощью гема ruby-processing и java-библиотеки Minim. Найденная статья была взята за основу для написания визуализатора.
Сборка
Собираем столбик
Перед соединением светодиодов в столбец необхобходимо в каждом из четырёх светодиодов выгнуть ноги так, чтобы каждая нога составляла с с соседней 90°.
Затем каждый из светодиодов нужно вращать поочерёдно на 90° (каждый последующий должен быть повёрнут на 90° по часовой стрелке по отношению к предыдущему). Предварительно одну из ног можно пометить (у нас она помечена зелёным лаком), чтобы не запутаться.
Соединяем наши светодиоды в столбик. После соединения светодиодов обрезаем выступающие концы ног.
Размещаем столбики
Оставшиеся 15 столбиков собираются аналогичным образом.
Столбики расставляются на плате на одинаковом расстоянии друг от друга, формируя таким образом куб со стороной, равной 4 светодиодам. Все столбики должны быть повёрнуты в одинаковом направлении (тут очень пригодится предварительная маркировка «опорной» ноги).
Соединяем столбики между собой
Переворачиваем конструкцию и начинаем присоединять провода. Всего проводов 16, соединение проводилось в 4 этапа.
Осталось подключить к Arduino — и можно приступать к программированию.
Подключаем к Arduino
Авторы Чарликуба предусмотрели библиотеку cubeplex для удобного программирования куба с Arduino. Для того, чтобы данную библиотеку можно было использовать без модификаций, необходимо подключать наши провода в следующем порядке (нумерация соответствует проводам на изображениях из предыдущего раздела):
Программируем Arduino
Базовый функционал
Как было сказано выше, авторы воспользовались библиотекой charlieplex, которая предоставляет функцию drawLed(), принимающая цвет и позицию светодиода в координатах XYZ.
#include "cubeplex.h"
const int cubeSides = 4;
void setup() {
initCube();
}
void loop() {
for (int xpos = 0; xpos < cubeSides; xpos++) {
for (int ypos = 0; ypos < cubeSides; ypos++) {
for (int zpos = 0; zpos < cubeSides; zpos++) {
drawLed(red, xpos, ypos, zpos);
}
}
}
}
Обмен сообщениями с ПК
Обмен сообщениями реализуется посредством последовательного ввода-вывода в порт, через который контроллер соединяется с машиной. Работа с такими событиями реализована в Arduino через SerialEvent.
#include "cubeplex.h"
String inputString = "";
boolean stringComplete = false;
// Ввод каждого символа в порт сопровождается вызовом SerialEvent, который накапливает введённые символы в строку inputString.
// Как только пользователь вводит Enter, меняется значение флага inputComplete и выполняется дальнейший код из loop().
int color = red;
void setup() {
Serial.begin(9600);
inputString.reserve(200);
initCube();
}
void loop() {
if (stringComplete) {
Serial.println(inputString);
drawString(inputString);
resetBuffer();
inputString = "";
stringComplete = false;
}
}
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n') {
stringComplete = true;
}
}
}
// Очистка буфера куба; перед последующей подсветкой диодов куб полностью погаснет.
void resetBuffer() {
flushBuffer();
clearBuffer();
}
// Закодируем три кординаты светодиода трёмя цифрами.
// Каждая координата - каждые три символа из строки, которая пришла в порт.
// То есть строка "000001002003" подсветит столбик с координатами { x: 0, y: 0 }.
void drawString(String inputString) {
int xpos = -1;
int ypos = -1;
int zpos = -1;
for (int i = 0; inputString[i + 3]; i += 3) {
xpos = charToInt(inputString[i]);
ypos = charToInt(inputString[i + 1]);
zpos = charToInt(inputString[i + 2]);
drawLed(color, xpos, ypos, zpos);
}
}
void charToInt(char value) {
return (value - '0');
}
Программирование для светомузыки
Предполагается, что куб будет мигать в такт музыке. Соответственно, можно упростить формат сообщения до одной цифры. Алгоритм такой: как только анализатор музыки «ловит» такт, кубик должен полностью загореться. После этого кубик будет медленно (слой за слоем) гаснуть. Как только анализатор словит следующий такт, кубик снова загнорается полностью. То есть кубику достаточно передать одну цифру: сколько слоёв необходимо подсветить в данный момент. Также при каждой итерации будем случайным образом определять новый цвет.
void drawBeat(String inputString) {
int height = charToInt(inputString[0]);
int color = random(red, white);
for (int xpos = 0; xpos < cubeSides; xpos++) {
for (int ypos = 0; ypos < cubeSides; ypos++) {
for (int zpos = 0; zpos < height; zpos++) {
drawLed(color, xpos, ypos, zpos);
}
}
}
}
Анализ звука на JRuby
В набор библиотеки Minim входит класс BeatDetect, который предоставляет инструменты для определения ритма музыки. Вообще с помощью этой библиотеки предельно просто подключиться к каналу приёма звука и произвести его частотный анализ. Для наших целей подошёл частотный метод определения ритма.
Код тестировался на Ubuntu 15.10; версия JRuby, использованная авторами — jruby 9.0.5.0. Для запуска скрипта необходимо установить Processing и подключить библиотеку Minim.
require 'ruby-processing'
require_relative 'translator'
require_relative 'serial_writer'
class SoundProcessor < Processing::App
load_library "minim"
import "ddf.minim"
import "ddf.minim.analysis"
def setup
@minim = Minim.new self
@input = @minim.get_line_in
@beat = BeatDetect.new @input.mix.size, 44100
@beat_value = 0.001
@beat.set_sensitivity 300
end
def draw
process_beat
SerialWriter.instance.write(Translator.instance.translate(@beat_value))
end
private
def process_beat
@beat.detect @input.mix
@beat_value = @beat.is_kick ? 1 : @beat_value * 0.95
end
end
SoundProcessor.new
Демонстрация работы
Средствами PulseAudio визуализатору в качестве audio input был присвоен audio output, т.е. получаем визуализацию всего звука, который у нас идёт из динамиков. После записи на видео был наложен звук, который воспроизводился в момент создания ролика.
Посесловие
Нам удалось получить визуализатор звука в связке с пк. В дальнейшем можно улучшить алгоритм определения ритма (стандартные средства определения ритма библиотеки Minim далеки от идеала), также на куб можно выводить информацию о частотах. Как видите, куб несложен в построении и программировании; кроме того, он задействует минимум компонентов.
Ссылки:
- Charliecube — Asher Glick
- Чарлиплексинг — Википедия
- Create a Music Visualizer in 7 Steps with Ruby — David Guttman
- Код для Arduino
- Код визуализатора
Авторы
Макоед Виктор и Евгений Куница, студенты 3 курса БГУиР ВМСиС
Комментарии (13)
kedobear
21.06.2016 20:44+5Астрологи объявили неделю БГУИРа. Количество постов про светодиодные кубы на Geektimes увеличено вдвое.
https://geektimes.ru/post/268166/
https://geektimes.ru/post/269162/
https://geektimes.ru/sandbox/3678/Samal
28.06.2016 11:21Да, ладно, вам. Два куба зимой, один летом…
Скоро наиграются… :)
Кстати последняя ваша ссылка — и не про куб вообще… https://geektimes.ru/sandbox/3678/
ilyaplot
22.06.2016 09:53Возможностей у этого куба куда больше, чем просто визуализация звука. Я собирал на обычных светодиодах куб 5х5 и выводил на нем текст с анимацией, введенный в программе на ноутбуке. В качестве визуализации звука хорошо смотрелся эффект «дождь»
madf
22.06.2016 15:50Вот меня всегда удивляли люди, которые делают что-то 3D, а потом пытаются "это" передать путем простой записи на видео (где естественно "вау эффект" не передаётся), потому как снимать надо в динамике угла…
В общем, потрачено было уйму сил, а лично для меня так и остаётся загадкой ради чего это всё делалось. (
roboq6
22.06.2016 16:55-2Это визуализация музыки? Как любитель Anime Music Video (AMV), а также прочих музыкальных видеороликов, фи и ещё раз фи.
Для меня музыка, как правило, должна иметь какую-то историю и/ли идею. Видеоряд как раз эту функцию и выполняет, он в той или иной степени визуализирует музыку раскрывая идею, историю. Может этот кубик передать идею/историю музыки? Нет и ещё раз нет.
Вот примеры того как выглядит настоящая визуализация музыки:
https://www.youtube.com/watch?v=_9FKoD1K6Yw
https://www.youtube.com/watch?v=PJvPyH8WnMwmadf
22.06.2016 18:04чот ваши видео — не о чем, какое отношение они имеют вообще к этой теме, я ещё понимаю, если дать ссылку на нечто подобное: https://youtu.be/4ldsFIbf8aU?t=1m28s
основная идея вся сводится к цветомузыке, а когда цветомузыка умела передавать "какую-то историю"? никогда)roboq6
22.06.2016 18:27-1Отношение тут в том, что визуализацией музыки здесь даже не пахнет, а ведь именно в этом была цель создания оного устройства. Просто есть кубик который красиво мигает цветными огоньками. При этом ему абсолютно неважно соответствует ли настроению музыки его огоньки или нет.
Цвет для передачи настроения музыки (и настроения вообще) я видет в диснеевском мультфильме «Алладин». Например сцена где Джафар приказывает Джину сделать его султаном насыщена фиолетовым цветом.madf
22.06.2016 18:31вы видели постановку, свет носил вспомогательную суть к атмосфере
здесь, да, кубик даже к цветомузыки не имеет никакого отношения, слабовато (соглашусь), но вот к творчеству руками и усидчивости — тоже немаловажно :Droboq6
23.06.2016 06:33-1Думаю кубик всё-таки можно было бы использовать для визуализации музыки в двух случаях:
1.Некий ИИ (скорее всего нейросеть) путём анализа тэгов, частот и прочей информации пытается угадать какое настроение передаёт музыка и соответствующим образом меняет цвет и яркость кубика. В случае неудачи получает feedback от пользователя.
2.Вместе со звуковым файлом плэйер читает специальный файл в котором расписано какой цвет и яркость должен иметь кубик в том или ином месте мелодии. Файл создаётся вручную автором музыки либо кем-нибудь из фанатов.
DeleteOne
Отличный проект!
В идеале подключить это все к NodeMCU, чтобы получить внешний визуализатор. Кроме того, вроде сама плата способна справиться с анализом звука, судя по этому посту https://m.geektimes.ru/post/277276/.
А вообще, давно мечтаю собрать подобный куб, только опыта в пайке недостаточно.
Кстати, из чего делались ножки, которыми соединяли светодиоды?
ekunitsa
вообще это медная проволока, мы использовали кабель ВВГ 3*1,5