diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 55c1fcbeb..000000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index 9ca780152..6bb034cc4 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + + +# OS generated files +.DS_Store diff --git a/.vscode/launch.json b/.vscode/launch.json index 5f0c7af3b..cfb644b9b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,5 +1,12 @@ { "configurations": [ + { + "type": "java", + "name": "CiaraVisual1", + "request": "launch", + "mainClass": "C22787471.CiaraVisual1", + "projectName": "java" + }, { "type": "java", "name": "CodeLens (Launch) - Main", diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..38c7634b2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.project.explorer.showNonJavaResources": false +} \ No newline at end of file diff --git a/README.md b/README.md index 19ba88c75..e99bf478a 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,75 @@ # Music Visualiser Project -Name: +Audio Name: Crazy Frog - Axel F -Student Number: - -## Instructions -- Fork this repository and use it a starter project for your assignment -- Create a new package named your student number and put all your code in this package. -- You should start by creating a subclass of ie.tudublin.Visual -- There is an example visualiser called MyVisual in the example package -- Check out the WaveForm and AudioBandsVisual for examples of how to call the Processing functions from other classes that are not subclasses of PApplet - -# Description of the assignment - -# Instructions - -# How it works - -# What I am most proud of in the assignment - -# Markdown Tutorial - -This is *emphasis* - -This is a bulleted list - -- Item -- Item - -This is a numbered list - -1. Item -1. Item +| Name | Student Number | +|-----------|-----------| +|Amy Ibourk | C22308773 | +|Roxana Rakhmatullina | C21374751 | +|Ciara Trani | C22787471 | +|Aleena Mattathil | C22790201 | -This is a [hyperlink](http://bryanduggan.org) +## Video +[![YouTube](images/AleenaVisual2.png)](https://youtu.be/r7nN0u-_N_8) -# Headings -## Headings -#### Headings -##### Headings +# Screenshots +### Visual 1 +![An image](images/AmyVisual.png) -This is code: +### Visual 2 +![An image](images/RoxanaVisual1-1.png) +![An image](images/RoxanaVisual1-2.png) -```Java -public void render() -{ - ui.noFill(); - ui.stroke(255); - ui.rect(x, y, width, height); - ui.textAlign(PApplet.CENTER, PApplet.CENTER); - ui.text(text, x + width * 0.5f, y + height * 0.5f); -} -``` +### Visual 3 +![An image](images/CiaraVisual1-1.png) +### Visual 4 +![An image](images/AleenaVisual2.png) -So is this without specifying the language: +### Visual 5 +![An image](images/AleenaVisual1.png) -``` -public void render() -{ - ui.noFill(); - ui.stroke(255); - ui.rect(x, y, width, height); - ui.textAlign(PApplet.CENTER, PApplet.CENTER); - ui.text(text, x + width * 0.5f, y + height * 0.5f); -} -``` +# Description of the Project +Using Processing, our team created visuals for our chosen audio Axel F by Crazy Frog. Aleena had to have 2 visuals as the music repeated and also so we all had a similar limit of time to work on. Her visual shows a swirl. Ciaras visual shows rainbow scribbles moving around.Amys visual shows a rose like flower shape and then exposes another abstract shape inside it. It expands to the beat.Roxanas visual is of a frog image that bounces up and down the screen bouncing off the wall and every time it lands on the ground it squishes. There is a rainow aura around the frog and also rainbow grass at the bottom of the screen hip hop . -This is an image using a relative URL: +# How it works +There is a switch statement with the number keys allowing us to switch between each visual. Amy's visual is 1, Roxana's is 2, Ciara's is 3 and Aleena's are 4 and 5. We also implemented the visuals automatically changing according to the timing of the song. Time stamps : 0-27s Amy, 28-42s Aleena, 43-1.10s Roxana, 1.11-1.24s Aleena, 1.24-1.50s Ciara -![An image](images/p8.png) +### AmyVisual1 +In this visual, there are 3 elements: +1. There are 24 rotating cubes displayed using a for loop to create a visual in the centre of the screen. The size and colour are dependant on the amplitude of the audio. The rotation variable gives it a spinning effect as it increments by 0.1 each time render() is called (60 times per second). +1. Then there is a lines from centre visual. 30 lines are created using a for loop. The lines start from the centre and radiate outwards. The colour and length of each line is based on the amplitude. +1. The outer pattern is created by an array of squares. It begins by every square being initialised, each one being slightly bigger and rotated more than the previous. In render() it calls the method display() from the square class to change the colour and sized depending on the almplitude and spin the squares around. -This is an image using an absolute URL: +### AleenaVisual1 +This visual displays 4 waveforms. +3 waveforms make the background layer. The screen is divided into 3 sections - one for each waveform. Each section of the screen displays a waveform representing a different portion of the audio signal. The waveform color changes based on the audio amplitude, creating a dynamic visual representation of the audio input. +The foreground layer renders a spectrum analyzer by dividing the screen into bars, each representing a frequency range, and dynamically changing their height and color based on the audio input -![A different image](https://bryanduggandotorg.files.wordpress.com/2019/02/infinite-forms-00045.png?w=595&h=&zoom=2) +### AleenaVisual2 +The first element in this visual are the colour changing spirals. They are rendered by calculating their size, position, and color based on the audio amplitude and drawing them using trigonometric functions +The second element features a radial burst which is rendered by drawing lines that radiate outward from the center of the screen. The brightness of the lines is determined by the amplitude of the audio signal -This is a youtube video: +### RoxanaVisual1 +I am also happy with how my visual turned out. Though, I had a few issues throughout the process of making it perfect, I managed to do what I aimed to do. RoxanaVisual1.java works by firstly declaring the package in this instance C21374751 student number,after import statements and class declaration it declares the fields such as ourvisual ov, images and floats variables which will be used in RoxanaVisual1 . Then I constructed the body for the frog image and grass such as positioning and moveent like the frog hopping then with render i set the background colours to fade, and make it so the frog bounces back when it reaches the walls and changes directions and change and crates the raimbow aura around the frog image by altering an ellipse , also im render i coded the squish effect and the grass to alter in height -[![YouTube](http://img.youtube.com/vi/J2kHSSFA4NU/0.jpg)](https://www.youtube.com/watch?v=J2kHSSFA4NU) +### CiaraVisual1 +The way my code works is that it iterates over the audio buffer to draw dynamic visualizations. By adjusting stroke colors, drawing ellipses based on audio amplitudes, and rotating lines around them, it creates engaging visual representations of the audio input. -This is a table: -| Heading 1 | Heading 2 | -|-----------|-----------| -|Some stuff | Some more stuff in this column | -|Some stuff | Some more stuff in this column | -|Some stuff | Some more stuff in this column | -|Some stuff | Some more stuff in this column | +# What I am most proud of in the assignment +### Amy +- Firstly, I am proud of how well our group worked together. We met up a few times to work on our project together, as well as asked eachother for help when we needed it. +- I am also happy with how my visual turned out. Though, I had a few issues throughout the process of making it perfect, I managed to do what I aimed to do. + +### Aleena +- At first this assignment had me very overwhelmed. The fact that it was a group project really alienated the stress, knowing that 4 of us would be working together to achieve this common goal. I am really proud of how the 4 of us worked together - meeting up on our days off and, if we were stuck or had an issue, our communication in the groupchat where we would work together to solve one person's bug. +- While coding my own visuals, I really had a creative block and imaginitave visuals were not coming to me. I'm proud at how I tackled this obstacle. I started with basic visuals - a waveoform and a spiral, and just trialed and errorred different visuals that would add to the base visual + +### Roxana +- I chose the song for this and im half proud of myself and half hate myself for choosing such an upbeat, classic and fun yet such an annoying somewhat repetitive song, +- I also notes the time stamps for the code which we then changed it to just have a switch case but its the thought that counts +- I am also proud of how I got the frog to squish whever it landed while hopping, I found it quite hard to do and it did have issues with it like it would stay squished the whole time or not be there at all. To fix this i had to fix the statement so that the size changed on the frogs vertical posotion. + +### Ciara +- I'm most proud of how this project showcases our creative individuality. I like how different and unique each of our visuals are from each other and I think it suits the music that we've chosen. The aspect I love the most about my part is the fast movement of the shapes and lines. It goes well with the upbeat song in the background. diff --git a/images/AleenaVisual1.png b/images/AleenaVisual1.png new file mode 100644 index 000000000..2f32f3c0c Binary files /dev/null and b/images/AleenaVisual1.png differ diff --git a/images/AleenaVisual2.png b/images/AleenaVisual2.png new file mode 100644 index 000000000..f0e24e86e Binary files /dev/null and b/images/AleenaVisual2.png differ diff --git a/images/AmyVisual.png b/images/AmyVisual.png new file mode 100644 index 000000000..02c446c3c Binary files /dev/null and b/images/AmyVisual.png differ diff --git a/images/CiaraVisual1-1.png b/images/CiaraVisual1-1.png new file mode 100644 index 000000000..558e20375 Binary files /dev/null and b/images/CiaraVisual1-1.png differ diff --git a/images/CiaraVisual1-2.png b/images/CiaraVisual1-2.png new file mode 100644 index 000000000..98888511a Binary files /dev/null and b/images/CiaraVisual1-2.png differ diff --git a/images/RoxanaVisual1-1.png b/images/RoxanaVisual1-1.png new file mode 100644 index 000000000..3ef06fb1e Binary files /dev/null and b/images/RoxanaVisual1-1.png differ diff --git a/images/RoxanaVisual1-2.png b/images/RoxanaVisual1-2.png new file mode 100644 index 000000000..ff3bbb60a Binary files /dev/null and b/images/RoxanaVisual1-2.png differ diff --git a/images/frog.png b/images/frog.png new file mode 100644 index 000000000..f6234fd8f Binary files /dev/null and b/images/frog.png differ diff --git a/java/.DS_Store b/java/.DS_Store deleted file mode 100644 index 629e3335c..000000000 Binary files a/java/.DS_Store and /dev/null differ diff --git a/java/.project b/java/.project index 0d5afed93..e33b6507d 100644 --- a/java/.project +++ b/java/.project @@ -21,7 +21,7 @@ 30 org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ diff --git a/java/data/CrazyFrog.mp3 b/java/data/CrazyFrog.mp3 new file mode 100644 index 000000000..aa83a085c Binary files /dev/null and b/java/data/CrazyFrog.mp3 differ diff --git a/java/lib/.DS_Store b/java/lib/.DS_Store deleted file mode 100644 index 40b58cc58..000000000 Binary files a/java/lib/.DS_Store and /dev/null differ diff --git a/java/src/C21374751/RoxanaVisual1.java b/java/src/C21374751/RoxanaVisual1.java new file mode 100644 index 000000000..3505be01a --- /dev/null +++ b/java/src/C21374751/RoxanaVisual1.java @@ -0,0 +1,79 @@ +package C21374751; + +import ie.tudublin.OurVisual; +import processing.core.*; + +public class RoxanaVisual1 +{ + OurVisual ov; + PImage frogImage; + float xPos; // Horizontal position of the frog image + float yPos; // Vertical position of the frog image + float hopSpeed; // Horizontal speed of the frog + float angle; // Angle for rainbow colors + int numGrassLines; // Number of grass lines + float grassSpacing; // Spacing between grass lines + + public RoxanaVisual1(OurVisual ov) + { + this.ov = ov; + frogImage = ov.loadImage("images/frog.png"); // Load the frog image from the "images" folder + frogImage.resize(120, 0); // Resize the image width to 120 pixels, keep aspect ratio (slightly bigger) + xPos = frogImage.width / 2; // Start the frog at the left edge of the screen + yPos = ov.height - frogImage.height / 2; // Start the frog at the bottom of the screen + hopSpeed = 5; // Horizontal speed of the frog + angle = 0; // Initialize angle for rainbow colors + numGrassLines = 30; // Number of grass lines + grassSpacing = ov.width / numGrassLines; // Calculate spacing between grass lines + } + + public void render() + { + // Calculate background color based on time + float bgBrightness = PApplet.abs(PApplet.sin((float)(ov.frameCount * 0.02))) * 255; + ov.background(0, 0, bgBrightness); // Set background to fade from black to blue and back to black + + // Update frog position + xPos += hopSpeed; + + // Check if frog reaches edges of the screen + if (xPos > ov.width - frogImage.width / 2 || xPos < frogImage.width / 2) { + // Reverse direction when frog reaches the right or left wall + hopSpeed = -hopSpeed; + } + + // Draw rainbow aura around the frog + ov.noFill(); + for (int i = 0; i < 6; i++) { + ov.stroke((i * 60) % 255, 255, 255); // Rainbow colors + float auraSize = 50 + 20 * PApplet.sin(angle + i * PApplet.TWO_PI / 6); + ov.ellipse(xPos, yPos, frogImage.width + auraSize, frogImage.height + auraSize); + } + + // Calculate squish factor based on frog's vertical position relative to the bottom of the screen + float squishFactor = 1.0f - (yPos / (ov.height - frogImage.height / 2)); + float squishedHeight = frogImage.height * squishFactor; + + // Draw frog image + ov.imageMode(PApplet.CENTER); // Set image mode to center + ov.image(frogImage, xPos, yPos, frogImage.width, squishedHeight); // Display frog image with squish effect + + // Make the frog jump higher + float hopAmount = 20 * PApplet.sin((float)(ov.frameCount * 0.1)); // Adjust the hop amount as needed + yPos = ov.constrain(yPos + hopAmount, 0, ov.height - frogImage.height / 2); // Ensure the frog stays within the screen + + angle += 0.05; // Increment angle for rainbow colors + + + + + // Draw grass lines at the bottom of the screen + for (int i = 0; i < numGrassLines; i++) { + float grassX = i * grassSpacing; // Calculate x position for each grass line + float grassHeight = ov.random(40, 100); // Randomize grass height + ov.strokeWeight(10); // Set grass line thickness + ov.stroke((i * 60) % 225, 255, 225); // Rainbow colors // Set grass color to green + ov.line(grassX, ov.height, grassX, ov.height - grassHeight); // Draw a vertical grass line + } + } +} diff --git a/java/src/C22308773/AmyVisual1.java b/java/src/C22308773/AmyVisual1.java new file mode 100644 index 000000000..d42fdc3bd --- /dev/null +++ b/java/src/C22308773/AmyVisual1.java @@ -0,0 +1,126 @@ +package C22308773; + +import ddf.minim.AudioBuffer; +import ie.tudublin.OurVisual; +import processing.core.*; + +public class AmyVisual1 +{ + OurVisual ov; + float cy = 0; + float cx = 0; + float hue = 0f; + + //cube variables + float rotation; + float numCubes = 24f; + float offset = (float)((float)ov.PI/(numCubes * 2)); + + //lines from centre visual variables + int numLines = 30; + float angleStep = ov.TWO_PI / numLines; //spacing of the lines + + //square pattern variables + Square[] squares; + int numSquares = 12; + + + public AmyVisual1(OurVisual ov) + { + this.ov = ov; + cy = this.ov.height / 2; + cx = this.ov.width / 2; + + + squares = new Square[numSquares]; + for (int i = 0; i < numSquares; i++) + { + squares[i] = new Square(); + squares[i].rotation = i * 24; + squares[i].size = i * 25; + squares[i].squareNum = i; + + } + + } + + + public void render() + { + + ov.colorMode(PApplet.HSB); + ov.lights(); + ov.background(0); + + //calling square pattern + for (Square square : squares) + { + square.display(); + } + + + //calling lines from centre visual + for (int i = 0; i < numLines; i++) + { + ov.noFill(); + + hue = ov.map(ov.getSmoothedAmplitude(), 0, 1, 0, 256); + ov.stroke(hue, 175, 255); + float angle = i * angleStep; + float x1 = cx + ov.cos(angle) * (ov.getSmoothedAmplitude() * (ov.height/2) * 1.5f); + float y1 = cy + ov.sin(angle) * (ov.getSmoothedAmplitude() * (ov.height/2) * 1.5f); + + ov.line(cx, cy, x1, y1); + + } + + ov.translate(ov.width/2, ov.height/2); + + //calling cube centre visual + for(int i = 0; i < numCubes; i++) + { + float hue = ov.map(ov.getSmoothedAmplitude(), 0, 1, 0, 256); + ov.fill(hue, 175, 255); + ov.stroke(hue, 100, 100); + ov.pushMatrix(); + ov.rotateY(rotation + offset*i); + ov.rotateX(rotation/2 + offset*i); + ov.box(200 * (ov.getSmoothedAmplitude() * 3)); + ov.popMatrix(); + } + rotation += 0.01f; + + + } + + + class Square + { + float side = 100; + float rotation = 0; + float halfH = ov.height / 2; + int size = 0; + int squareNum; + + + public void display() + { + hue = ov.map(ov.getSmoothedAmplitude()+(squareNum/100), 0, 1, 0, 256); + side = (ov.getSmoothedAmplitude() * halfH * 3) + size; + + ov.stroke(hue, 175, 255); + ov.noFill(); + ov.strokeWeight(3); + + ov.pushMatrix(); + ov.translate(cx, cy); + ov.rotate(rotation); + ov.rectMode(ov.CENTER); + ov.rect(0, 0, side, side, 25); + ov.popMatrix(); + + rotation += 0.01f; + } + } +} + diff --git a/java/src/C22787471/CiaraVisual1.java b/java/src/C22787471/CiaraVisual1.java new file mode 100644 index 000000000..564cbd295 --- /dev/null +++ b/java/src/C22787471/CiaraVisual1.java @@ -0,0 +1,54 @@ +package C22787471; + +import processing.core.*; +import ddf.minim.*; +import ie.tudublin.OurVisual; + +public class CiaraVisual1 +{ + OurVisual ov; + float cy = 0; + + + // public WaveForm(MyVisual mv) + public CiaraVisual1(OurVisual ov) + { + this.ov = ov; + cy = this.ov.height / 2; + + } + + public void render() + { + ov.colorMode(PApplet.HSB); + for(int i = 0 ; i < ov.getAudioBuffer().size() ; i ++) + { + ov.stroke( + PApplet.map(i, 0, ov.getAudioBuffer().size(), 0, 255) + , 255 + , 255 + ); + + float y1 = cy + cy * ov.getAudioBuffer().get(i); // Calculating y1 + float cy1 = i; // Setting cx1 to the current index + + ov.ellipse(i, cy, i, cy + cy * ov.getAudioBuffer().get(i)); + + ov.strokeWeight(10); + //ov.pushMatrix(); // Save the current transformation matrix + ov.translate(cy1, y1); // Move the origin to the current position + + ov.rotate(ov.radians(ov.random(360))); + //ov.popMatrix(); // Restore the original transformation matrix + + ov.rotate(ov.radians(ov.random(360))); // Rotate the line with a random angle + ov.line(0, 0, 300, 300); // Draw the line + //ov.popMatrix(); // Restore the original transformation matrix + + ov.fill(0); // Fill the shapes with black + + } + } +} + + diff --git a/java/src/C22787471/CiaraVisual2.java b/java/src/C22787471/CiaraVisual2.java new file mode 100644 index 000000000..190878f61 --- /dev/null +++ b/java/src/C22787471/CiaraVisual2.java @@ -0,0 +1,35 @@ +package C22787471; + +import processing.core.*; +import ddf.minim.*; +import ie.tudublin.OurVisual; + +public class CiaraVisual2 { + + OurVisual ov; + float cy = 0; + + public CiaraVisual2(OurVisual ov) + { + this.ov = ov; + cy = this.ov.height / 2; + + } + + public void render() + { + ov.colorMode(PApplet.HSB); + for(int i = 0 ; i < ov.getAudioBuffer().size() ; i ++) + { + ov.stroke( + PApplet.map(i, 0, ov.getAudioBuffer().size(), 0, 255) + , 255 + , 255 + ); + + ov.ellipse(i, cy, i, cy + cy * ov.getAudioBuffer().get(i)); + } + + } + +} diff --git a/java/src/C22790201/AleenaVisual1.java b/java/src/C22790201/AleenaVisual1.java new file mode 100755 index 000000000..4f21b01c3 --- /dev/null +++ b/java/src/C22790201/AleenaVisual1.java @@ -0,0 +1,100 @@ +package C22790201; + +import ie.tudublin.OurVisual; +import processing.core.*; +import ddf.minim.*; + +public class AleenaVisual1 +{ + OurVisual ov; + float[] smoothedBuffer; // Smoothed audio buffer + float smoothingFactor = 0.2f; // Adjust the smoothing factor as needed, 'f' added to specify float literal + + public AleenaVisual1(OurVisual ov) + { + this.ov = ov; + } + + public void render() + { + ov.colorMode(PApplet.HSB); + + // Set the color and stroke weight for the waveform + ov.stroke(255); + ov.strokeWeight(1); + + // Get the audio buffer from OurVisual + AudioBuffer audioBuffer = ov.getAudioBuffer(); + + // Smooth the audio buffer + if (smoothedBuffer == null || smoothedBuffer.length != audioBuffer.size()) { + smoothedBuffer = new float[audioBuffer.size()]; + } + for (int i = 0; i < audioBuffer.size(); i++) { + smoothedBuffer[i] += (audioBuffer.get(i) - smoothedBuffer[i]) * smoothingFactor; + } + + // Calculate the width and height of the waveform + float waveformWidth = ov.width / 2; // Width of the waveform + float waveformHeight = ov.height / 2; // Height of the waveform + + // Top edge + renderWaveform(0, 0, ov.width, waveformHeight, 0, 0); + + // Right edge + renderWaveform(ov.width - waveformWidth, 0, waveformWidth, ov.height, 0, 0); + + // Bottom edge + renderWaveform(0, ov.height - waveformHeight, ov.width, waveformHeight, 0, 0); + + // Left edge + renderWaveform(0, 0, waveformWidth, ov.height, 0, 0); + + renderSpectrumAnalyzer(); + } + + private void renderWaveform(float xStart, float yStart, float width, float height, float xOffset, float yOffset) + { + ov.beginShape(); + for (int i = 0; i < smoothedBuffer.length; i++) { + float x = PApplet.map(i, 0, smoothedBuffer.length, xStart, xStart + width); + float y = PApplet.map(smoothedBuffer[i], -1f, 1f, yStart, yStart + height); + + // Calculate hue based on audio amplitude + float hue = PApplet.map(smoothedBuffer[i], -1f, 1f, 0, 255); + + // Set the fill color based on hue, with full saturation and brightness + ov.fill(hue, 255, 255); + + ov.vertex(x + xOffset * width, y + yOffset * height); + } + ov.endShape(); + } + + public void renderSpectrumAnalyzer() { + ov.colorMode(PApplet.HSB); + ov.noStroke(); + + // Get the audio buffer from OurVisual + AudioBuffer audioBuffer = ov.getAudioBuffer(); + + // Calculate the width and height of each bar in the spectrum analyzer + float barWidth = ov.width / (float) audioBuffer.size(); + float barHeight; + + // Draw the spectrum analyzer bars + for (int i = 0; i < audioBuffer.size(); i++) { + // Calculate the height of the bar based on audio amplitude + barHeight = PApplet.map(audioBuffer.get(i), -1, 1, ov.height, 0); + + // Calculate hue based on audio amplitude + float hue = PApplet.map(audioBuffer.get(i), -1, 1, 0, 255); + + // Set the fill color based on hue, with full saturation and brightness + ov.fill(hue, 255, 255); + + // Draw the bar + ov.rect(i * barWidth, ov.height - barHeight, barWidth, barHeight); + } + } +} diff --git a/java/src/C22790201/AleenaVisual2.java b/java/src/C22790201/AleenaVisual2.java new file mode 100644 index 000000000..59d4226a2 --- /dev/null +++ b/java/src/C22790201/AleenaVisual2.java @@ -0,0 +1,76 @@ +package C22790201; + +import ie.tudublin.OurVisual; +import processing.core.*; + +public class AleenaVisual2 +{ + OurVisual ov; + float angle = 0; + float rotationSpeed = 0.01f; + float amplitudeScale = 100; + int numSpirals = 10; + + public AleenaVisual2(OurVisual ov) + { + this.ov = ov; + } + + public void render() { + ov.colorMode(PApplet.HSB); + ov.background(0); + + float amplitude = ov.getAmplitude(); // Get the amplitude of the audio + + ov.translate(ov.width / 2, ov.height / 2); // Translate origin to center of the screen + + // Render spirals + renderSpirals(amplitude); + + // Render radial burst + renderRadialBurst(amplitude); + } + + private void renderSpirals(float amplitude) { + ov.strokeWeight(3); + for (int i = 0; i < numSpirals; i++) { + float size = amplitude * amplitudeScale * (i + 1); // Scale size with amplitude + float x = size * PApplet.cos(angle); + float y = size * PApplet.sin(angle); + + // Set color based on frequency bands + int hue = (int) PApplet.map(i, 0, numSpirals, 0, 255); + ov.stroke(hue, 255, 255); + ov.noFill(); + + ov.beginShape(); + for (float a = 0; a < PApplet.TWO_PI; a += 0.1) { + float sx = x + size * PApplet.cos(a); + float sy = y + size * PApplet.sin(a); + ov.vertex(sx, sy); + } + ov.endShape(PConstants.CLOSE); + + angle += rotationSpeed; + } + } + + public void renderRadialBurst(float amplitude) { + int numPoints = 100; // Number of points in the burst + float step = PApplet.TWO_PI / numPoints; // Angle step between each point + + for (int i = 0; i < numPoints; i++) { + float x1 = 0; + float y1 = 0; + float x2 = amplitude * PApplet.cos(i * step) * 200; // Scale with amplitude + float y2 = amplitude * PApplet.sin(i * step) * 200; // Scale with amplitude + + // Set color based on amplitude + int brightness = (int) PApplet.map(amplitude, 0, 1, 100, 255); + ov.stroke(255, brightness); + + ov.line(x1, y1, x2, y2); + } + } + +} \ No newline at end of file diff --git a/java/src/example/AudioBandsVisual.java b/java/src/example/AudioBandsVisual.java index b6b99d6e5..686f1c817 100644 --- a/java/src/example/AudioBandsVisual.java +++ b/java/src/example/AudioBandsVisual.java @@ -1,25 +1,28 @@ package example; +import ie.tudublin.OurVisual; import processing.core.*; // This is an example of a visual that uses the audio bands public class AudioBandsVisual { - MyVisual mv; + // MyVisual mv; + OurVisual ov; - public AudioBandsVisual(MyVisual mv) + // public AudioBandsVisual(MyVisual mv) + public AudioBandsVisual(OurVisual ov) { - this.mv = mv; + this.ov = ov; } public void render() { - float gap = mv.width / (float) mv.getBands().length; - mv.noStroke(); - for(int i = 0 ; i < mv.getBands().length ; i ++) + float gap = ov.width / (float) ov.getBands().length; + ov.noStroke(); + for(int i = 0 ; i < ov.getBands().length ; i ++) { - mv.fill(PApplet.map(i, 0, mv.getBands().length, 255, 0), 255, 255); - mv.rect(i * gap, mv.height, gap,-mv.getSmoothedBands()[i] * 0.2f); + ov.fill(PApplet.map(i, 0, ov.getBands().length, 255, 0), 255, 255); + ov.rect(i * gap, ov.height, gap,-ov.getSmoothedBands()[i] * 0.2f); } } } \ No newline at end of file diff --git a/java/src/example/CubeVisual.java b/java/src/example/CubeVisual.java index ff8e58798..3154f9a90 100644 --- a/java/src/example/CubeVisual.java +++ b/java/src/example/CubeVisual.java @@ -1,7 +1,9 @@ package example; + import ie.tudublin.Visual; + public class CubeVisual extends Visual { boolean twocubes = false; diff --git a/java/src/example/MyVisual.java b/java/src/example/MyVisual.java index 8a71fe3f6..7208fd997 100644 --- a/java/src/example/MyVisual.java +++ b/java/src/example/MyVisual.java @@ -20,13 +20,13 @@ public void setup() { startMinim(); // Call loadAudio to load an audio file to process - // loadAudio("heroplanet.mp3"); + loadAudio("java/data/CrazyFrog.mp3"); // Call this instead to read audio from the microphone - startListening(); + // startListening(); - wf = new WaveForm(this); - abv = new AudioBandsVisual(this); + // wf = new WaveForm(this); + // abv = new AudioBandsVisual(this); } public void keyPressed() { diff --git a/java/src/example/WaveForm.java b/java/src/example/WaveForm.java index 5d38aa700..12c6506f8 100644 --- a/java/src/example/WaveForm.java +++ b/java/src/example/WaveForm.java @@ -1,31 +1,35 @@ package example; +import ie.tudublin.OurVisual; import processing.core.*; // This is an example of a visual that renders the waveform public class WaveForm { - MyVisual mv; + // MyVisual mv; + OurVisual ov; + float cy = 0; - public WaveForm(MyVisual mv) + // public WaveForm(MyVisual mv) + public WaveForm(OurVisual ov) { - this.mv = mv; - cy = this.mv.height / 2; + this.ov = ov; + cy = this.ov.height / 2; } public void render() { - mv.colorMode(PApplet.HSB); - for(int i = 0 ; i < mv.getAudioBuffer().size() ; i ++) + ov.colorMode(PApplet.HSB); + for(int i = 0 ; i < ov.getAudioBuffer().size() ; i ++) { - mv.stroke( - PApplet.map(i, 0, mv.getAudioBuffer().size(), 0, 255) + ov.stroke( + PApplet.map(i, 0, ov.getAudioBuffer().size(), 0, 255) , 255 , 255 ); - mv.line(i, cy, i, cy + cy * mv.getAudioBuffer().get(i)); + ov.line(i, cy, i, cy + cy * ov.getAudioBuffer().get(i)); } } } \ No newline at end of file diff --git a/java/src/ie/tudublin/Main.java b/java/src/ie/tudublin/Main.java index 67e93d892..80b8d2717 100644 --- a/java/src/ie/tudublin/Main.java +++ b/java/src/ie/tudublin/Main.java @@ -1,14 +1,20 @@ package ie.tudublin; + import example.CubeVisual; import example.MyVisual; +// import ie.tudublin.OurVisual; import example.RotatingAudioBands; +import C21374751.RoxanaVisual1; +import C22308773.AmyVisual1; +import C22787471.CiaraVisual1; +import C22790201.AleenaVisual1; public class Main { public void startUI() { String[] a = { "MAIN" }; - processing.core.PApplet.runSketch(a, new MyVisual()); + processing.core.PApplet.runSketch(a, new OurVisual()); } public static void main(String[] args) { diff --git a/java/src/ie/tudublin/OurVisual.java b/java/src/ie/tudublin/OurVisual.java new file mode 100644 index 000000000..50a6fd794 --- /dev/null +++ b/java/src/ie/tudublin/OurVisual.java @@ -0,0 +1,134 @@ +package ie.tudublin; + +import C22308773.AmyVisual1; +import C21374751.RoxanaVisual1; +import C22787471.CiaraVisual1; +import C22787471.CiaraVisual2; +import C22790201.AleenaVisual1; +import C22790201.AleenaVisual2; +import example.AudioBandsVisual; +import example.WaveForm; +import ie.tudublin.*; +import ddf.minim.*; + + +public class OurVisual extends Visual { + WaveForm wf; + AudioBandsVisual abv; + AmyVisual1 ai1; + AleenaVisual1 am1; + CiaraVisual1 ct1; + RoxanaVisual1 rr1; + AleenaVisual2 am2; + CiaraVisual2 ct2; + char selectedVisual = ' '; + public int color; + + public boolean isPlaying = false; + + + public void settings() { + // size(1024, 500); + + // Use this to make fullscreen + // fullScreen(); + + // Use this to make fullscreen and use P3D for 3D graphics + fullScreen(P3D, SPAN); + } + + public void setup() { + startMinim(); + + // Call loadAudio to load an audio file to process + loadAudio("java/data/CrazyFrog.mp3"); + + // Call this instead to read audio from the microphone + // startListening(); + + + wf = new WaveForm(this); + abv = new AudioBandsVisual(this); + ai1 = new AmyVisual1(this); + am1 = new AleenaVisual1(this); + ct1 = new CiaraVisual1(this); + rr1 = new RoxanaVisual1(this); + am2 = new AleenaVisual2(this); + } + + public void keyPressed() { + if (key == ' ') { + getAudioPlayer().cue(0); + getAudioPlayer().play(); + isPlaying = true; + + } + else { + selectedVisual = key; + } + } + + + public void draw() { + background(0); + //timestamp method + /* + if(getAudioPlayer().position() <= 27000) + { + ai1.render(); + } + else if(getAudioPlayer().position() >= 27001 && getAudioPlayer().position() <= 42000) + { + am1.render(); + } + else if(getAudioPlayer().position() >= 42001 && getAudioPlayer().position() <= 70000) + { + rr1.render(); + } + else if(getAudioPlayer().position() >= 70001 && getAudioPlayer().position() < 84000) + { + am2.render(); + } + else if(getAudioPlayer().position() >= 84001 && getAudioPlayer().position() < 110000) + { + ct1.render(); + } + */ + + //switch case method + switch(selectedVisual) { + case '1': + ai1.render(); + break; + case '2': + rr1.render(); + break; + case '3': + ct1.render(); + break; + case '4': + am1.render(); + break; + case '5': + am2.render(); + break; + default: + break; + } + + try { + // Call this if you want to use FFT data + calculateFFT(); + } catch (VisualException e) { + e.printStackTrace(); + } + // Call this is you want to use frequency bands + calculateFrequencyBands(); + + // Call this is you want to get the average amplitude + calculateAverageAmplitude(); + // wf.render(); + // abv.render(); + + } +} diff --git a/java/src/ie/tudublin/Visual.java b/java/src/ie/tudublin/Visual.java index 927fe57b1..8d078f1bb 100644 --- a/java/src/ie/tudublin/Visual.java +++ b/java/src/ie/tudublin/Visual.java @@ -3,6 +3,12 @@ import processing.core.PApplet; import ddf.minim.*; import ddf.minim.analysis.FFT; +import example.AudioBandsVisual; +import example.WaveForm; +import C22308773.AmyVisual1; +import C22787471.CiaraVisual1; +import C22790201.AleenaVisual1; +import C21374751.RoxanaVisual1; public abstract class Visual extends PApplet { @@ -19,10 +25,9 @@ public abstract class Visual extends PApplet private FFT fft; private float amplitude = 0; - private float smothedAmplitude = 0; + public float smoothedAmplitude = 0; - public void startMinim() { minim = new Minim(this); @@ -34,6 +39,13 @@ public void startMinim() } + public void setup() + { + startMinim(); + + loadAudio("java/data/CrazyFrog.mp3"); + } + float log2(float f) { return log(f) / log(2.0f); } @@ -60,7 +72,7 @@ public void calculateAverageAmplitude() total += abs(ab.get(i)); } amplitude = total / ab.size(); - smothedAmplitude = PApplet.lerp(smothedAmplitude, amplitude, 0.1f); + smoothedAmplitude = PApplet.lerp(smoothedAmplitude, amplitude, 0.1f); } @@ -133,7 +145,7 @@ public float getAmplitude() { } public float getSmoothedAmplitude() { - return smothedAmplitude; + return smoothedAmplitude; } public AudioPlayer getAudioPlayer() { @@ -143,4 +155,6 @@ public AudioPlayer getAudioPlayer() { public FFT getFFT() { return fft; } + + } diff --git a/java/src/ie/tudublin/tempCodeRunnerFile.java b/java/src/ie/tudublin/tempCodeRunnerFile.java new file mode 100644 index 000000000..e69de29bb