Audio Player using Processing

15 06 2014

Minim Player

The following code utilizes the Processing IDE and the Minim audio library to play an mp3 file in Processing. This was created as an example for a lab I was running.

  

import ddf.minim.spi.*;
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.ugens.*;
import ddf.minim.effects.*;

Minim minim;
AudioPlayer player;
AudioMetaData meta;
void setup()
{
size(1024, 200);
minim = new Minim(this);
//This audio file MUST be in the same folder as the saved Processing (.pde) file
player = minim.loadFile(".mp3", 1024);
meta = player.getMetaData();
print("MetaData = " + meta);
print("\nFile Name: " + meta.fileName());
print("\nLength in milliseconds: " + meta.length());
print("\nTitle: " + meta.title());
}
void draw()
{
background(0);
stroke(0, 255, 0);
//player.play();
/****************************************
For loop below is for a stereo waveform
****************************************/
noFill();
for (int i = 0; i < player.bufferSize () -1; i++)
{
line(i, 50+ player.left.get(i), i+1, 50 + player.left.get(i+1)*50);
line(i, 150+ player.right.get(i), i+1, 150 + player.right.get(i+1)*50);
}
/****************************************
For loop below is for a mono waveform
****************************************/
/*
for(int i = 0; i < player.bufferSize() -1; i++)
{
line(i, 100+player.mix.get(i)*100, i+1, 100+player.mix.get(i+1)*100);
}
*/
}
/***************************************************************************
If mouse button is clicked while audio file is playing then pause the song.
If button is clicked while audio file is paused then resume playing.
****************************************************************************/
void mousePressed()
{
if (player.isPlaying())
player.pause();
else
player.play();//Resumes playing the paused audio file
//player.loop(); //starts audio file over from the start
}





World Clock

15 06 2014

World Clock

This project utilizes a Model View Controller and the system time to accomplish the task of creating a world clock.

  
WorldClock.java
 

public class WorldClock {
public static void main(String [] args) {
new WorldClock();
}

public WorldClock() {

ClockModel model = new ClockModel();
ClockController controller = new ClockController(model);
ClockView view = new ClockView();

/***************************************************************
* Sets a default clock which cannot be removed from the list. *
***************************************************************/
model.setCity("System Time");
model.setTimeZoneOffset(0.0);
view.add(model);
}
}

  
ClockModel.java
 

import javax.swing.JTextField;
import javax.swing.border.*;
import javax.swing.*;
import java.awt.*;

/************************************************************
* The following class inherits from the JTextField object. *
************************************************************/
public class ClockModel extends JTextField{
private String city;
private long timeInSeconds;
private Double timeZoneOffset = 0.0;
private Border lineBorder = BorderFactory.createLineBorder(Color.BLACK, 1);
public ClockModel() {
super(8);

Font font = new Font("Bradley Hand ITC", Font.BOLD, 24);
setFont(font);
setEditable(false);
setFocusable(false);
setVisible(true);
setHorizontalAlignment(JTextField.CENTER);
city = "No Input";

}
/****************************************************************
* The following set methods are called individually after *
* the creation of an instance. This method of input was chosen *
* so the clocks could be populated directly with information *
* from the JList opbject in the ClockView class. The *
* setTimeInSeconds() method is called in the ClockController *
* class. *
****************************************************************/
public void setCity(String city) {
this.city = city;
update();
}
/********************************************************************************
* The border is updated either when the city is updated or the timeZoneOffset. *
********************************************************************************/
public void update() {
setBorder(BorderFactory.createTitledBorder(lineBorder, city + " | " + timeZoneOffset + " GMT offset"));
}
/******************************************
* Called from the ClockController class. *
******************************************/
public void setTimeInSeconds(long timeInSeconds) {
this.timeInSeconds = timeInSeconds;
//setText(secondsAsTimeText());
}
/************************************
* Called from the ClockView class. *
************************************/
public void setTimeZoneOffset(Double timeZoneOffset) {
this.timeZoneOffset = timeZoneOffset;
update();
}
/***********************************************
* This method updates the text of the JLabel. *
***********************************************/
public void tick() {
setText(secondsAsTimeText());
}
/********************************************************
* This method formats the String for the time display *
* and also ensures the time stays within a 24 hour *
* period. *
********************************************************/
public String secondsAsTimeText () {
long hours, minutes, seconds;
timeInSeconds += (long)(timeZoneOffset*3600.0);

/**This if statement checks to see if the time is between 0 and 86400 seconds (24 hours)
and corrects otherwise to the correct time format.**/
if (this.timeInSeconds > 86400)
this.timeInSeconds %= 86400;
else if (this.timeInSeconds < 0)
this.timeInSeconds = 86400 + timeInSeconds;
minutes = timeInSeconds/60;
seconds = timeInSeconds%60;
hours = minutes/60;
minutes = minutes%60;

return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
}

  
ClockController.java
 

import java.util.GregorianCalendar;
import java.util.Calendar;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class ClockController implements ActionListener {
private ClockModel model;
GregorianCalendar gCalendar= new GregorianCalendar();
private long timeInSeconds = ((gCalendar.get(Calendar.HOUR_OF_DAY))*3600 + gCalendar.get(Calendar.MINUTE)*60 + gCalendar.get(Calendar.SECOND));;
/**************************************************************
* This constructor utilizes GregorianCalendar & Calendar in *
* order to determine the system's current time of day. *
**************************************************************/
public ClockController(ClockModel model) {
this.model = model;
Timer timer = new Timer(1000, this);
timer.start();
}
/**********************************************************
* This method returns the system time and is used when *
* creating a new clock in order to pass the system time. *
**********************************************************/
public long getTimeInSeconds()
{
return timeInSeconds;
}
/*********************************************************************
* This method advances each clock and is powered by a Timer object. *
*********************************************************************/
public void actionPerformed(ActionEvent evt) {
this.model.setTimeInSeconds(timeInSeconds);
this.model.tick();
timeInSeconds++;
}
}

  
ClockView.java
 

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
import java.util.*;
import javax.swing.event.*;
import java.awt.event.*;

public class ClockView implements ActionListener, ListSelectionListener{
private JPanel clockDisplay, cityListDisplay, mainDisplay;
private ClockController defaultController;
private JList listSource;
private String [] citiesAndTimeOffsets= loadCityTimeOffsets("CityTimeOffsets.txt");
private ArrayList testModelArrayList = new ArrayList();

public ClockView() {

JFrame clockFace = new JFrame("World Time");
clockFace.setSize(400, 400);
clockFace.setLocationRelativeTo(null);
clockFace.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Container contentPane = clockFace.getContentPane();

mainDisplay = new JPanel(new GridLayout(1, 2));
mainDisplay.setVisible(true);
clockDisplay = new JPanel(new GridLayout(0, 1));
cityListDisplay = new JPanel(new BorderLayout());
cityListDisplay.setPreferredSize(new Dimension(400, 200));

JList list = new JList(citiesAndTimeOffsets);
list.addListSelectionListener(this);
JScrollPane listScroll = new JScrollPane(list);

cityListDisplay.setVisible(true);

JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER));
JButton addCity = new JButton("+");
JButton subtractCity = new JButton("-");
buttons.add(addCity);
buttons.add(subtractCity);

addCity.addActionListener(this);
subtractCity.addActionListener(this);

cityListDisplay.add(buttons, BorderLayout.NORTH);
cityListDisplay.add(listScroll, BorderLayout.CENTER);

mainDisplay.add(cityListDisplay);
mainDisplay.add(clockDisplay);
contentPane.add(mainDisplay);

update();
clockFace.setVisible(true);
}
/******************************************************
* This method is taken directly from the example *
* code provided on the CSIS website. *
******************************************************/
public String[] loadCityTimeOffsets(String fileName) {
try {
FileReader aFileReader = new FileReader(fileName);
BufferedReader aBufferReader = new BufferedReader(aFileReader);

String cityName = "";
int separatorPos = 0;
double offset = 0.0;
ArrayList wordList = new ArrayList();

String lineFromFile = aBufferReader.readLine() ;
while (lineFromFile != null) {
// Add the word to the word list
separatorPos = lineFromFile.indexOf(",");
cityName = lineFromFile.substring(0,separatorPos);
offset = Double.parseDouble(lineFromFile.substring(separatorPos+1));
wordList.add(lineFromFile) ;
lineFromFile = aBufferReader.readLine() ;
}
aBufferReader.close();
aFileReader.close();
return wordList.toArray(new String[0]) ;
}
catch(IOException x) {
return null ;
}
}
/*********************************************************************
* This method validates the clockDisplay JPanel whever called upon. *
*********************************************************************/
public void update() {
clockDisplay.validate();
}
/***********************************************
* This method gets the source from the JList. *
***********************************************/
public void valueChanged(ListSelectionEvent d) {
JList source = (JList)d.getSource();
this.listSource = source;
}
/*********************************************************
* The following method detwrmines which button click *
* created the ActionEvent and then either adds or *
* removes a clock. To add, an object of ClockModel *
* type is created and populated with the information *
* given from the JList value that was selected when *
* and "+" button was clicked. That is then added to an *
* ArrayList and also to the clockDisplay JPanel. *
* The remove function simply removes the last entered *
* object from the ArrayList. I was unable to figure *
* out how to remove specific clocks unfortunately *
* or was I able to add/remove multiple clocks. *
* This problem I think has something to do with *
* an array of ClockModels with matching indeces *
* but I was unable to implement this system *
* successfully. *
*********************************************************/
public void actionPerformed(ActionEvent e) {
JButton source = (JButton)e.getSource();
Double timeZone = 0.0;
String selectedValue = (String)this.listSource.getSelectedValue();
ClockModel addRemModel = new ClockModel();
String [] values = selectedValue.split(",");
String cityName = values[0];
timeZone = Double.parseDouble(values[1]);

/**************************************************************
* The following if statement checks which button is clicked. *
**************************************************************/
if ((source.getText()) == "+") {
defaultController = new ClockController(addRemModel);

addRemModel.setCity(cityName);
addRemModel.setTimeZoneOffset(timeZone);
addRemModel.setTimeInSeconds(defaultController.getTimeInSeconds());
addRemModel.setText(addRemModel.secondsAsTimeText());

testModelArrayList.add(addRemModel);
add(testModelArrayList.get(testModelArrayList.size()-1));
}
else if ((source.getText()) == "-") {
testModelArrayList.remove(addRemModel);
addRemModel.setVisible(false);
remove(testModelArrayList.get(testModelArrayList.size()-1));
}
update();
}
/*************************************************
* These final two methods add and remove clocks.*
*************************************************/
public void add(ClockModel c) {
clockDisplay.add(c);
clockDisplay.validate();
}

public void remove(ClockModel c) {
clockDisplay.remove(c);
clockDisplay.validate();
}
}

  
CityTimeOffsets.txt
 

Accra,-1.0
Addis Ababa,+2.0
Adelaide,+8.5
Algiers,+0.0
Almaty,+5.0
Amman*,+2.0
Amsterdam*,+1.0
Anadyr,+11.0
Anchorage*,-9.0
Ankara*,+2.0
Antananarivo,+2.0
Asuncion,-5.0
Athens*,+2.0
Atlanta*,-5.0
Auckland,+11.0
Baghdad,+2.0
Bangalore,+4.5
Bangkok,+6.0
Barcelona*,+1.0
Beijing,+7.0
Beirut*,+2.0
Belgrade*,+1.0
Berlin*,+1.0
Bogota,-6.0
Boston*,-5.0
Brasilia,-4.0
Brisbane,+9.0
Brussels*,+1.0
Bucharest*,+2.0
Budapest*,+1.0
Buenos Aires,-4.0
Cairo,+1.0
Calgary*,-7.0
Canberra,+9.0
Cape Town,+1.0
Caracas,-5.5
Casablanca*,+0.0
Chicago*,-6.0
Columbus*,-5.0
Copenhagen*,+1.0
Dallas*,-6.0
Dar es Salaam,+2.0
Darwin,+8.5
Denver*,-7.0
Detroit*,-5.0
Dhaka,+5.0
Doha,+2.0
Dubai,+3.0
Dublin*,+0.0
Edmonton*,-7.0
Frankfurt*,+1.0
Guatemala,-7.0
Halifax*,-4.0
Hanoi,+6.0
Harare,+1.0
Havana*,-5.0
Helsinki*,+2.0
Hong Kong,+7.0
Honolulu,-11.0
Houston*,-6.0
Indianapolis*,-5.0
Islamabad,+4.0
Istanbul*,+2.0
Jakarta,+6.0
Jerusalem*,+2.0
Johannesburg,+1.0
Kabul,+3.5
Karachi,+4.0
Kathmandu,+4.8
Khartoum,+2.0
Kingston,-6.0
Kinshasa,+0.0
Kiritimati,+13.0
Kolkata,+4.5
Kuala Lumpur,+7.0
Kuwait City,+2.0
Kyiv*,+2.0
La Paz,-5.0
Lagos,+0.0
Lahore,+4.0
Las Vegas*,-8.0
Lima,-6.0
Limerick,+0.0
Lisbon*,+0.0
London*,+0.0
Los Angeles*,-8.0
Madrid*,+1.0
Managua,-7.0
Manila,+7.0
Melbourne,+9.0
Mexico City*,-6.0
Miami*,-5.0
Minneapolis*,-6.0
Minsk,+2.0
Montevideo,-4.0
Montreal*,-5.0
Moscow,+3.0
Mumbai,+4.5
Nairobi,+2.0
Nassau*,-5.0
New Delhi,+4.5
New Orleans*,-6.0
New York*,-5.0
Oslo*,+1.0
Ottawa*,-5.0
Paris*,+1.0





FYP Final Report

4 07 2013

Results were released last week and I received the second highest grade possible for my FYP. Quite happy with it given all the hours I invested in it. The report can be found here for anyone who is interested. Thank you to everyone who helped me through this process especially my sister.





FYP Demonstration Video

7 04 2013

This is a demonstration/walkthrough of my Final Year Project in the University of Limerick. The application takes in OSC messages from an iPad running TouchOSC and then converts them into DMX control messages to be sent to a lighting system. This application was built using Max/MSP 6.0





FYP Lighting Demonstration

6 04 2013

This is a performance of my Final Year Project in the University of Limerick. The application takes in OSC messages from an iPad running TouchOSC and then converts them into DMX control messages to be sent to the lights. This application was built using Max/MSP 6.0





New Equipment and First Tests

24 09 2012

Picked up a LanBox LCX and a ShowTec 4 channel dimmer from the department the other day and I built a few cables that I needed in order to get some lights working with the dimmer today. Lots to do really but I said I’d get a start at it and see what kind of control I would be able to get on my first try. I am now able to control up to four channels of dimming wirelessly from my laptop! It’s only small but once I am able to get some fixtures rented it is all I have. Did I mention I only have two small desk lamps to control at the moment? I suppose now is a good time to ask if anyone has any DMX controlled lights that they could lend me for a bit to please contact me!

 

Here’s some pictures:





Final Year Project

17 09 2012

This is where I will be posting all of the updates for my final year project in the University of Limerick.

Check back here from time to time to see how this process goes!








%d bloggers like this: