IxLab Recitation 7: Neopixel Music Visualization
Building Process
In this recitation, the work we’ve done is related to the data sync between software and hardware. Firstly, I install the provided libraries and codes. The installation process and the initial codes have no problems occurred.
Then I was trying to modify the codes. Firstly, I used the frequency analysis code that have been provided in class as my initial code. Then I used the sample code that has been provided in the recitation to connect the Arduino to the processing. I want to let the LEDs be lit up and showed the same color but have different brightness for different frequencies. So I directly add one more variable to push to the Arduino. After the modification of the codes to push the amplitude level to the Arduino as the brightness, I started my first attempt. When running the program, the problem that occurred was the LEDs were displaying colorful light which is not the effect that I want since I’ve already set the parameters as a fixed number.
After asking for help, we figured it out by changing the setting parameters from 4 to 5. Then the color works properly. At this time, I decided to change my plan and let the amplitude decide how many LEDs will be lit up.
I change the audio source from the microphone to my own mp3 file. It works quite except the code needs several seconds to get started. After some modifications of the codes, I started to run the code. Then I found two problems. First, the interface of the processing is very laggy which is about 2 fps at most. Then, the LEDs will not change when the amplitude changes from high level to low. For the first problem, I haven’t found a proper way to solve it till now. Jason has reported the same problem as mine. The second problem, I realized that is caused by the feature of the LEDs which is the LED will only change when it receives a new order. In this case, my code will only send information to the LEDs that need to be lit up, so the LEDs that have been lit up before will still keep the light-up status. So add new lines of code to refresh the whole LEDs after a light period. And finally, reach the following effect.
Code Sharing
Here’s the Processing code that I use to do the project:
import processing.sound.*; import processing.serial.*; import osteele.processing.SerialRecord.*; Serial serialPort; SerialRecord serialRecord; int W; //width of the tiles int NUM = 60; //amount of pixels int[] r = new int[NUM]; //red of each tile int[] g = new int[NUM]; //red of each tile int[] b = new int[NUM]; //red of each tile // declare an AudioIn object AudioIn microphone; SoundFile sound; // declare an Frequency analysis object to detect the frequencies in a sound FFT freqAnalysis; // declare a variable for the amount of frequencies to analyze // should be a multiple of 64 for best results int frequencies = 1024; // Define the frequencies wanted for our visualization. Above that treshold frequencies are rarely atteigned and stay flat. int freqWanted = 60; // declare an array to store the frequency anlysis results in float[] spectrum = new float[freqWanted]; // Declare a drawing variable for calculating the width of the float circleWidth; void setup() { size(512, 480); // Calculate the width of the circles depending on how the bands we want to display. circleWidth = width/float(freqWanted); // create the AudioIn object and select the mic as the input stream microphone = new AudioIn(this, 0); sound = new SoundFile(this, "Outro.mp3"); // start the mic input without routing it to the speakers microphone.start(); // create the Frequency analysis object and tell it how many frequencies to analyze freqAnalysis = new FFT(this, frequencies); // use the microphone as the input for the analysis freqAnalysis.input(sound); sound.loop(); String serialPortName = SerialUtils.findArduinoPort(); serialPort = new Serial(this, serialPortName, 9600); serialRecord = new SerialRecord(this, serialPort, 5); serialRecord.logToCanvas(false); } void draw() { // analyze the frequency spectrum and store it in the array freqAnalysis.analyze(spectrum); printArray(spectrum); background(0); fill(200, 0, 100, 150); noStroke(); // draw circles based on the values stored in the spectrum array // adjust the scale variable as needed float scale = 600; for (int i=0; i<freqWanted; i++) { circle(i*circleWidth, height/2, spectrum[i]*scale); serialRecord.values[0] = i; // which pixel we change (0-59) serialRecord.values[1] = 87; // how much red (0-255) serialRecord.values[2] = 6; // how much green (0-255) serialRecord.values[3] = 150; // how much blue (0-255) serialRecord.values[4] = 50; // how much blue (0-255) serialRecord.send(); // send it! } }
Reflection
The whole process is not as fluent as I thought. I think I still have a lot of work to do on the cooperation between hardware and software. Perhaps after I spend more time on the codes and the theories of coordination, I’ll have a further understanding and produce some better works in the future.
In addition, I’ve come up with some ways to solve the problem. Perhaps updating the LEDs that need to be updated(turn on or turn off) only can optimize the visual effect. Since it won’t make every LEDs light up again when the amplitude has changed.