Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
{
"configurations": [
{
"type": "java",
"name": "Start",
"request": "launch",
"mainClass": "OOP2023.Start",
"projectName": "java"
},
{
"type": "java",
"name": "AudioVisualizer",
"request": "launch",
"mainClass": "OOP2023.AudioVisualizer",
"projectName": "java"
},
{
"type": "java",
"name": "Main",
"request": "launch",
"mainClass": "OOP2023.Main",
"projectName": "java"
},
{
"type": "java",
"name": "CodeLens (Launch) - Main",
Expand Down
97 changes: 19 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,89 +1,30 @@
# Music Visualiser Project
My music visualizer project

Name:
Name: Mabu chemelie michael

Student Number:
Student Number: D19123717

## 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: this program is like nature as i would like to call it, firstly i adopted a music that plays when you run the program. the music has this ecstaic rave vibe, which is the reason i choose it. However, the music is not where the fun ends, the program is menu-driven with just two options, frist option to exit the program and the other to visualize the project.

# Description of the assignment

# Instructions
Instruction: the instruction of the code is pretty much self explanatory but i will go through it. so when the program runs it initiaties the GUI which shows a menu with calm colours and music playing. in the menu you have a promtp message with two options as mentioned earlier in the description. when 1 is pressed it takes you to the visulaizer primarily designed to visualize an audio input using clouds flowers and other natural elemnts implemented in the program

# How it works

# What I am most proud of in the assignment
The Visualizer program is designed to create a visual representation based on some form of audio input. a liitle summary on how the program works.

for the audio input and amplitude calculation, the program processes audio data to compute an amplitude value using the getAmplitude() method, which converts the audio buffer to an array. the applitude is calaculated by squaring each value in the buffer, summing them up, and then taking the square root of the average of those squared values. The amplitude will typically rise and fall based on the loudness and intensity of the audio.

for visual representation like drawing static components, the method drawsun is used to draw the sun on the canvas as well as the drawGround method which draws a rectangle that visually represents the ground. the render() method is responsible for drawing the entire scene on the canvas. The sequence of drawing is:
Draw the sun.
Draw the flowers.
Draw the ground.
Draw ellipses based on the amplitude (perhaps some visual feedback).
Draw clouds, with sizes influenced by the audio's amplitude.
It seems the render() method is called repeatedly (probably in a loop), which means the visualization will be dynamic and continuously update as the audio plays.

# Markdown Tutorial
finally When audio plays, this program visualizes it by displaying a scene with a sun, ground, flowers, and clouds. The flowers rotate, and the clouds change size based on the audio's amplitude, providing a dynamic visual representation of the audio.

This is *emphasis*
i am proud of many things in this project although some of the methods in the program were very diffcult to implement because of its complexity and also the kind of design i had in mind for the methods. The code is organized using an object-oriented approach. The use of classes, methods, encapsulation, and inheritance (e.g., extending the Visual class) is a clear indication of a structured and modular design. attention to details was one of the great factor that helped me with some design implementaion like having the flowers rotate in opposite directions relative to their stems.
finally this project serves as a learning experience, although i faced some challenges working on the program buh at the same time i gained some skills that i would be adding in my arsenal.

This is a bulleted list

- Item
- Item

This is a numbered list

1. Item
1. Item

This is a [hyperlink](http://bryanduggan.org)

# Headings
## Headings
#### Headings
##### Headings

This is code:

```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);
}
```

So is this without specifying the language:

```
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);
}
```

This is an image using a relative URL:

![An image](images/p8.png)

This is an image using an absolute URL:

![A different image](https://bryanduggandotorg.files.wordpress.com/2019/02/infinite-forms-00045.png?w=595&h=&zoom=2)

This is a youtube video:

[![YouTube](http://img.youtube.com/vi/J2kHSSFA4NU/0.jpg)](https://www.youtube.com/watch?v=J2kHSSFA4NU)

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 |

Binary file added images/bread.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/cheese.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/ham.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/lettuce.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mayo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mustard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/tomato.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions java/.project
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
</natures>
<filteredResources>
<filter>
<id>1616413840733</id>
<id>1692362523697</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
Expand Down
Binary file added java/data/rave.mp3
Binary file not shown.
74 changes: 74 additions & 0 deletions java/src/OOP2023/Start.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package OOP2023;

import ie.tudublin.Visual;

public class Start extends Visual {
Anne anne = new Anne(this);

//For menu buttons
int mode = 0;



public void keyPressed()
{
if(key == '0')
{
mode = 0;
}

if(key == '1')
{
mode = 1;
}
}

public void setup()
{
startMinim();
loadAudio("rave.mp3");
getAudioPlayer().play();

colorMode(RGB);
}

public void settings()
{
size(600, 600, P3D);
}

public void draw() {
switch (mode) {
// For the main menu
case 0:
background(50, 50, 70); // Dark Blue-Gray background
fill(210, 210, 230); // Light Blue-Gray for text
textAlign(CENTER);
textSize(width / 20.0f);

// Title with a bit of shadow for a modern touch
text("Ecstatic song", width / 2.0f, height / 4.0f);
textSize(width / 30.0f);
fill(220, 220, 240); // Slightly lighter shade for options

text("Press 0: MENU", width / 2.0f, (height / 2.0f));
text("Press 1: Nature", width / 2.0f, (height / 2.0f) + 50);

break;

// Audio
case 1:
background(153, 204, 255);
anne.render();

}







}

}
122 changes: 122 additions & 0 deletions java/src/OOP2023/Visualizer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package OOP2023;

import ie.tudublin.Visual;

public class Anne extends Visual {
private Start anne;

// Constants
private static final int PETAL_COUNT = 5;
private static final int PETAL_ANGLE = 72;

public Anne(Start anne) {
this.anne = anne;
}

public float getAmplitude() {
float[] flowers = getAudioBuffer().toArray();
float sum = 0;
for (float flower : flowers) {
sum += flower * flower;
}
return (float) Math.sqrt(sum / flowers.length);
}

public void drawCloud(int a, int b, int c, float d) {
anne.noStroke();
anne.fill(255);

int[] ellipseOffsetsX = {530, 510, 460, 480, 470, 510, 490};
int[] ellipseOffsetsY = {295, 305, 295, 305, 285, 285, 280};
int[] ellipseWidths = {60, 40, 40, 40, 40, 40, 40};
int[] ellipseHeights = {30, 30, 30, 30, 30, 30, 30};

for (int i = 0; i < ellipseOffsetsX.length; i++) {
anne.ellipse(a + ellipseOffsetsX[i], b + ellipseOffsetsY[i], c + ellipseWidths[i], d + ellipseHeights[i]);
}
}

public void drawGround() {
anne.stroke(114, 180, 58);
anne.fill(65, 101, 34);
anne.rect(0, 850, 2000, 500);
}

public void drawSun() {
anne.pushMatrix();
anne.smooth();
anne.noSmooth();
anne.fill(245, 187, 87);
anne.ellipse(224, 184, 220, 220);
anne.popMatrix();
}

private void drawFlower(int translateX, int translateY, float rotateFactor, int[] flowerColor, int[] flowerCenterColor) {
float amplitude = getAmplitude();
anne.pushMatrix();
anne.smooth();
anne.noStroke();
anne.translate(anne.width / 2, anne.height / 2);
anne.translate(translateX, translateY);
anne.rotate(radians(amplitude * rotateFactor));

anne.fill(flowerColor[0], flowerColor[1], flowerColor[2]);
for (int i = 0; i < PETAL_COUNT; i++) {
anne.ellipse(0, -40, 50, 50);
anne.rotate(radians(PETAL_ANGLE));
}

anne.pushMatrix();
anne.rotate(-radians(amplitude * rotateFactor));
anne.stroke(41, 63, 22);
anne.strokeWeight(3);
anne.line(0, 44, 0, 255);
anne.popMatrix();

anne.stroke(flowerCenterColor[0], flowerCenterColor[1], flowerCenterColor[2]);
anne.fill(flowerCenterColor[0], flowerCenterColor[1], flowerCenterColor[2]);
anne.ellipse(0, 0, 50, 50);

anne.popMatrix();
}

public void drawFlowers() {
drawFlower(-100, 100, 180, new int[]{191, 155, 48}, new int[]{141, 85, 36});
drawFlower(-200, -100, 360, new int[]{141, 158, 199}, new int[]{195, 227, 220});
drawFlower(200, 200, 60, new int[]{246, 234, 219}, new int[]{255, 200, 109});
drawFlower(-400, 50, 250, new int[]{149, 125, 173}, new int[]{255, 223, 211});
}

public void render() {
float avg = 0;
for (int i = 0; i < ab.size(); i++) {
avg += Math.abs(ab.get(i));
}
avg /= ab.size();
float smoothedavg = lerp(0, avg, 0.01f);

anne.colorMode(RGB);
drawSun();
drawFlowers();
drawGround();

anne.fill(0, 10);
anne.fill(255);
anne.noStroke();

if (anne.frameCount % 30 == 0) {
anne.ellipse(anne.width, anne.height, smoothedavg, smoothedavg);
}

anne.translate(anne.width / 2, anne.height / 2, 0);

// Cloud rendering calls
drawCloud(-600, -544, 10, 30 * smoothedavg * 200);
drawCloud(-800, -644, 10, 30 * smoothedavg * 200);
drawCloud(-1000, -644, 10, 30 * smoothedavg * 200);
drawCloud(-100, -544, 10, 30 * smoothedavg * 200);
drawCloud(-300, -600, 10, 30 * smoothedavg * 200);
drawCloud(0, -644, 10, 30 * smoothedavg * 200);

}
}
6 changes: 2 additions & 4 deletions java/src/ie/tudublin/Main.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package ie.tudublin;

import example.CubeVisual;
import example.MyVisual;
import example.RotatingAudioBands;
import OOP2023.*;

public class Main
{

public void startUI()
{
String[] a = {"MAIN"};
processing.core.PApplet.runSketch( a, new MyVisual());
processing.core.PApplet.runSketch( a, new Start());
}

public static void main(String[] args)
Expand Down
2 changes: 1 addition & 1 deletion java/src/ie/tudublin/Visual.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public abstract class Visual extends PApplet
private Minim minim;
private AudioInput ai;
private AudioPlayer ap;
private AudioBuffer ab;
protected AudioBuffer ab;
private FFT fft;

private float amplitude = 0;
Expand Down