I'm trying to load a wav file into a FilePlayer using Processing and Minim Library (later I want to patch a Delay on it). However, the wav file I was given plays too fast, at least at double the speed it is supposed to and it is very high pitched. The file sounds like it is supposed to if I play it in VLC Media Player or in WMP. It is 5 seconds long at a Bit Rate of 20kbps, but the code prints out it is 2299ms long.
Code:
import ddf.minim.*;
import ddf.minim.ugens.*;
import ddf.minim.spi.*;
Minim minim;
AudioOutput out;
FilePlayer filePlayer;
Delay myDelay;
void setup() {
size(100, 100);
minim = new Minim(this);
AudioRecordingStream myFile = minim.loadFileStream( "audio1.wav", 1024, true);
filePlayer = new FilePlayer( myFile );
filePlayer.play();
filePlayer.loop();
out = minim.getLineOut();
// patch the file player to the output
filePlayer.patch(out);
println(filePlayer.length()); //This prints out 2299
}
void draw()
{
background( 0 );
}
Try this with your audio file:
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;
FilePlayer filePlayer;
AudioOutput out;
Delay delay;
void setup(){
size(640, 240);
minim = new Minim(this);
AudioRecordingStream file = minim.loadFileStream( "marcus_kellis_theme.mp3",1024,true);
filePlayer = new FilePlayer( file );
filePlayer.loop(1);//play forever
delay = new Delay( 0.4, .9, true, true );
out = minim.getLineOut();
filePlayer.patch(delay).patch(out);
}
void mousePressed(){
delay.setDelAmp(0);
}
void mouseReleased(){
delay.setDelAmp(.9);
}
void draw(){
background( 0 );
stroke( 255 );
beginShape(LINES);
for( int i = 0; i < out.bufferSize() - 1; i++ ){
// find the x position of each buffer value
float x1 = map( i, 0, out.bufferSize(), 0, width );
float x2 = map( i+1, 0, out.bufferSize(), 0, width );
// draw a line from one buffer position to the next for both channels
vertex( x1, 50 + out.left.get(i)*50);vertex(x2, 50 + out.left.get(i+1)*50);
vertex( x1, 150 + out.right.get(i)*50);vertex( x2, 150 + out.right.get(i+1)*50);
}
endShape();
}
If it doesn't playback correctly try to open it in Audacity and export it as a 16-bit signed wav.
Related
I am just at very beginnig in Java coding, so far I could solve my problems finding solutions on internet, but this time I just stucked.
I want to create a grid(pattern) of filled rectangles, and it works fine, but then I would like to change colour of rectangles on specific position, and this part is just not working. I have no idea why, what am I doing wrong ?
// **file : MainWindow.java **
import java.util.Scanner;
import javax.swing.JFrame;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
public class MainWindow {
JFrame frame = new JFrame();
int pos_X;
int pos_Y;
// constructor for frame
public MainWindow (String title) {
frame.setSize(1000, 1000);
frame.setTitle(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
for (int i=0;i<26;i++){ // works fine
for (int j=0;j<26;j++){
Shape shape = new Shape (110+i*20,110+j*20,19,19,5,100,220); //(x,y, width,height, R-colour, G-colour, B-colour)
frame.add(shape);
frame.setVisible(true); }}
pos_X= 15;
pos_Y = 15;
Shape shape = new Shape (110+pos_X*20,110+pos_Y*20,19,19,250,0,20); // it doesn't work ???
frame.add(shape);
frame.setVisible(true);
}
public static void main(String[] args){
new MainWindow(" my window ");
}
}
// **file : Shape.java **
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Color;
import java.awt.Color.*;
import javax.swing.JComponent;
public class Shape extends JComponent{
int width, height, xcoord, ycoord, col_r, col_g,col_b;
//constructor
public Shape (int x, int y ,int w,int h, int k, int l, int m)
{
this.width = w;
this.height = h;
this.xcoord = x;
this.ycoord = y;
this.col_r = k;
this.col_g = l;
this.col_b = m;
}
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
Color x= new Color( col_r,col_g, col_b );
g.setColor(x);
g.fillRect(xcoord, ycoord, width, height);
}
}
If I understand right, what you want could be done ensuring the shape has drawn after the grid, so
pos_X= 15;
pos_Y = 15;
Shape shape = new Shape (110+pos_X*20,110+pos_Y*20,19,19,250,0,20); // it doesn't work ???
frame.setComponentZOrder(shape,0)
frame.add(shape);
frame.setVisible(true);
...
please note the
frame.setComponentZOrder(shape,0)
which ensure that the colored shape is drawn above the others.
In alternative your
P.S.
if it doesn't work try frame.setComponentZOrder(shape,frame.getComponentCount())
See also here for an alternative
I am using processing-3.2.2 for audio visualization. I have the code to play the visualiser but I don't know how to save it as a video(.mp4) file.
Here's what I wrote:
import ddf.minim.*;
import ddf.minim.analysis.*;
Minim minim;
AudioPlayer player;
AudioMetaData meta;
BeatDetect beat;
int r = 200;
float rad = 70;
void setup()
{
size(500, 500);
//size(600, 400);
minim = new Minim(this);
player = minim.loadFile("son_final.mp3");
meta = player.getMetaData();
beat = new BeatDetect();
player.play();
//player.play();
background(-1);
noCursor();
}
void draw()
{
float t = map(mouseX, 0, width, 0, 1);
beat.detect(player.mix);
fill(#1A1F18,50);
noStroke();
rect(0, 0, width, height);
translate(width/2, height/2);
noFill();
fill(-2, 10);
if (beat.isOnset()) rad = rad*0.9;
else rad = 70;
ellipse(0, 0, 2*rad, 2*rad);
stroke(-1, 50);
int bsize = player.bufferSize();
for (int i = 0; i < bsize - 1; i+=5)
{
float x = (r)*cos(i*2*PI/bsize);
float y = (r)*sin(i*2*PI/bsize);
float x2 = (r + player.left.get(i)*100)*cos(i*2*PI/bsize);
float y2 = (r + player.left.get(i)*100)*sin(i*2*PI/bsize);
line(x, y, x2, y2);
}
beginShape();
noFill();
stroke(-1, 50);
for (int i = 0; i < bsize; i+=30)
{
float x2 = (r + player.left.get(i)*100)*cos(i*2*PI/bsize);
float y2 = (r + player.left.get(i)*100)*sin(i*2*PI/bsize);
vertex(x2, y2);
pushStyle();
stroke(-5);
strokeWeight(2);
point(x2, y2);
popStyle();
}
endShape();
if (flag) showMeta();
}
void showMeta() {
int time = meta.length();
textSize(50);
textAlign(CENTER);
text( (int)(time/1000-millis()/1000)/60 + ":"+ (time/1000-millis()/1000)%60, -7, 21);
}
boolean flag =false;
void mousePressed() {
if (dist(mouseX, mouseY, width/2, height/2)<150) flag =!flag;
}
void keyPressed() {
if(key=='e')exit();
}
I know I can import MovieMaker library but I don't know how to use it in this code. Please suggest some changes.
Thank you.
You can use the Video Export library for that. More info here: http://funprogramming.org/VideoExport-for-Processing/
Then all you'd do is create an instance of VideoExport and then call videoExport.saveFrame() at the end of your draw() function.
import com.hamoid.*;
VideoExport videoExport;
void setup() {
size(600, 600);
videoExport = new VideoExport(this, "basic.mp4");
}
void draw() {
background(#224488);
rect(frameCount * frameCount % width, 0, 40, height);
videoExport.saveFrame();
}
There are a ton of resources online. I recommend googling "Processing video export" for a ton of results. Then try something out and post an MCVE (not your entire project) showing exactly where you're stuck.
I tried to put the source position top and bottom this way:
top:
sourcePos[0]=0f;
sourcePos[1]=-1f;
sourcePos[2]=0f;
bottom:
sourcePos[0]=0f;
sourcePos[1]=1f;
sourcePos[2]=0f
Unfortunately, they seem to be indistinguishable. Moreover, if I change the sourcePos[1] to any other value, I still do not detect any change in the audio.
However, sourcePos[0] and sourcePos[2] work fine. Why the second position in the source position array does not take any effect?
Can anyone help me with this? Thanks in advance.
Here is the full code:
import com.jogamp.openal.*;
import com.jogamp.openal.util.*;
import java.io.*;
import java.nio.ByteBuffer;
public class SingleStaticSource {
static AL al = ALFactory.getAL();
// Buffers hold sound data.
static int[] buffer = new int[1];;
// Sources are points emitting sound.
static int[] source = new int[1];
// Position of the source sound.
static float[] sourcePos = { 0f, 0.0f, 0.0f };
// Velocity of the source sound.
static float[] sourceVel = { 0.0f, 0.0f, 0.0f };
// Position of the listener.
static float[] listenerPos = { 0.0f, 0.0f, 0.0f };
// Velocity of the listener.
static float[] listenerVel = { 0.0f, 0.0f, 0.0f };
// Orientation of the listener. (first 3 elements are "at", second 3 are "up")
static float[] listenerOri = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
static int loadALData() {
// variables to load into
int[] format = new int[1];
int[] size = new int[1];
ByteBuffer[] data = new ByteBuffer[1];
int[] freq = new int[1];
int[] loop = new int[1];
// Load wav data into a buffer.
al.alGenBuffers(1, buffer, 0);
if (al.alGetError() != AL.AL_NO_ERROR)
return AL.AL_FALSE;
ALut.alutLoadWAVFile("wavdata/FancyPants.wav", format, data, size, freq, loop);
al.alBufferData(buffer[0], format[0], data[0], size[0], freq[0]);
// Bind buffer with a source.
al.alGenSources(1, source, 0);
if (al.alGetError() != AL.AL_NO_ERROR)
return AL.AL_FALSE;
al.alSourcei (source[0], AL.AL_BUFFER, buffer[0] );
al.alSourcef (source[0], AL.AL_PITCH, 1.0f );
al.alSourcef (source[0], AL.AL_GAIN, 1.0f );
al.alSourcefv(source[0], AL.AL_POSITION, sourcePos, 0);
al.alSourcefv(source[0], AL.AL_VELOCITY, sourceVel, 0);
al.alSourcei (source[0], AL.AL_LOOPING, loop[0] );
// Do another error check and return.
if(al.alGetError() == AL.AL_NO_ERROR)
return AL.AL_TRUE;
return AL.AL_FALSE;
}
static void setListenerValues() {
al.alListenerfv(AL.AL_POSITION, listenerPos, 0);
al.alListenerfv(AL.AL_VELOCITY, listenerVel, 0);
al.alListenerfv(AL.AL_ORIENTATION, listenerOri, 0);
}
static void killALData() {
al.alDeleteBuffers(1, buffer, 0);
al.alDeleteSources(1, source, 0);
ALut.alutExit();
}
public static void main(String[] args) {
// Initialize OpenAL and clear the error bit.
ALut.alutInit();
al.alGetError();
// Load the wav data.
if (loadALData() == AL.AL_FALSE)
System.exit(-1);
setListenerValues();
// Setup an exit procedure.
Runtime runtime = Runtime.getRuntime();
runtime.addShutdownHook(
new Thread(
new Runnable() {
public void run() {
killALData();
}
}
)
);
char[] c = new char[1];
while(c[0] != 'q') {
try {
BufferedReader buf =
new BufferedReader(new InputStreamReader(System.in));
System.out.println("Press a key and hit ENTER: " +
"'p' to play, 's' to stop, 'h' to pause and 'q' to quit");
buf.read(c);
switch(c[0]) {
case 'p':
// Pressing 'p' will begin playing the sample.
al.alSourcePlay(source[0]);
break;
case 's':
// Pressing 's' will stop the sample from playing.
al.alSourceStop(source[0]);
break;
case 'h':
// Pressing 'n' will pause (hold) the sample.
al.alSourcePause(source[0]);
break;
}
} catch (IOException e) {
System.exit(1);
}
}
}
} // class SingleStaticSource
I am trying to get this to work for sometime and I cannot figure out what wrong with my code. This leads me to believe there is some issues in SubScene Mouse listener. Any idea is appreciated.
Basically I have a scene contains two subscenes, one for the toolbar and one for the floor which has bunch of lines making it looks like tiles. I added mouse listeners so that when I clicked on the floor and move the mouse, the camera will move as if I am walking on the floor.
The problem is that the floor only recognize mouse event when I clicked on the intersection between the first vertical and the first horizontal line (yup, took me a while to figure that out). Mouse event should occur everywhere on entire floor.
Here is the code.
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class FloorTest extends Application {
double mousex, mousey;
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
Group bargroup = new Group();
SubScene bar = new SubScene(bargroup, 300, 20, true, SceneAntialiasing.DISABLED);
bargroup.getChildren().add(btn);
Group floorgroup = new Group();
SubScene floor = new SubScene(floorgroup, 300, 250, true, SceneAntialiasing.DISABLED);
ObservableList<Node> list = floorgroup.getChildren();
for(int i = 0; i < (300/20); i++)
{
double x = i * 20;
Line line = new Line(x, 0, x, 250);
list.add(line);
}
for(int i = 0; i < (250/20); i++)
{
double y = i * 20;
Line line = new Line(0, y, 300, y);
list.add(line);
}
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setNearClip(0.1);
camera.setFarClip(10000.0);
camera.setTranslateZ(-200);
floor.setCamera(camera);
floor.setOnMousePressed((MouseEvent event) -> {
mousex = event.getSceneX();
mousey = event.getSceneY();
});
floor.setOnMouseDragged((MouseEvent event) -> {
double x = event.getSceneX();
double y = event.getSceneY();
camera.relocate(camera.getLayoutX() + (x - mousex), camera.getLayoutY() + (y - mousey));
});
Group mainroot = new Group();
mainroot.getChildren().addAll(floor, bar);
Scene scene = new Scene(mainroot, 300, 250, true);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
It seems that setting the subscene.setPickOnBounds(true) should help in proper recognition of the mouse events for the whole subscene. Tested with javafx 8.
Please try using scene instead of floor variable in event handlers
Example:
scene.setOnMousePressed((MouseEvent event) -> {
mousex = event.getSceneX();
mousey = event.getSceneY();
});
scene.setOnMouseDragged((MouseEvent event) -> {
double x = event.getSceneX();
double y = event.getSceneY();
camera.relocate(camera.getLayoutX() + (x - mousex), camera.getLayoutY() + (y - mousey));
});
That helps me
I found an image online (http://i.stack.imgur.com/y1oT4.png) and I'm trying to take the sun and sky and make them rotate around the center of the screen, such that the sun and its rays appear to be spinning.
I intend to use a timer to control the movement, but I can't figure out how to rotate by an arbitrary angle. In other words, I know how to rotate by increments of 90 (switch the width and height), but what I'm trying to do is group a set of objects and rotate them around a single point.
I've looked around and found the AffineTransform() method, but I can't figure out if this is really what I need or how to use it if it is.
EDIT: Does this solve my problem? How to rotate Graphics in Java I will try it and update.
EDIT: It got me closer, but did not fix it. It returns this runtime error:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at FallScene.rotateBack(FallScene.java:77)
at SceneDriver$1TimerListener.actionPerformed(SceneDriver.java:66)
at javax.swing.Timer.fireActionPerformed(Timer.java:312)
at javax.swing.Timer$DoPostEvent.run(Timer.java:244)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDo
main.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThre
ad.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.
java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Press any key to continue...
The call at FallScene.rotateBack(FallScene.java:77) is:
bg.rotate(Math.toRadians(deg));
...which goes to:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// Get the size of the component window
int w = getWidth();
int h = getHeight();
// The Graphics2D object for the BACKGROUND
Graphics2D bg = (Graphics2D)g;
// Sun
Color solarYellow = new Color(255, 218, 0);
bg.setPaint(solarYellow);
Ellipse2D.Double sun = new Ellipse2D.Double((w / 2) - 150, (h / 2) - 150, 300, 300);
bg.fill(sun); bg.draw(sun);
}
If you still need it, I think this operational and commented code should help you understand how to draw it.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.util.TimerTask;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class SunRotate extends JComponent
{
public static void main(String[] args) {
final SunRotate sunRotate = new SunRotate(45);
JFrame f = new JFrame();
f.setContentPane(sunRotate);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setSize(new Dimension(800, 600));
f.setVisible(true);
new java.util.Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
sunRotate.deltaAngle(.3f);
sunRotate.repaint();
}
}, 16, 16); // every 16 milliseconds
}
private float angle;
public void deltaAngle(float delta) {
angle += delta;
}
public SunRotate(float angle) {
this.angle = angle;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int w = getWidth();
int h = getHeight();
// Recover Graphics2D
Graphics2D g2 = (Graphics2D) g;
// Move and rotate
g2.translate(w/2.0, h/2.0);
g2.rotate(Math.toRadians(angle));
// draw around 0,0
Color solarYellow = new Color(255, 218, 0);
g2.setPaint(solarYellow);
Ellipse2D.Double sun = new Ellipse2D.Double( -150, -150, 300, 300);
g2.fill(sun);
{ // draw some rays because the sun is round so we don't see the rotation
// make a ray (triangle)
Path2D ray = new Path2D.Float();
ray.moveTo(0, 0);
ray.lineTo(1000, 50);
ray.lineTo(1000, -50);
ray.closePath();
// draw N rays, rotating each time
int N = 20;
for (int i = 0; i < N; i++) {
g2.fill(ray);
g2.rotate(Math.PI * 2 / N);
}
}
}
}