Skip to content

Instantly share code, notes, and snippets.

@yuriks
Created July 28, 2011 02:53
Show Gist options
  • Save yuriks/1110872 to your computer and use it in GitHub Desktop.
Save yuriks/1110872 to your computer and use it in GitHub Desktop.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.sound.sampled.*;
import java.io.*;
import java.util.concurrent.locks.*;
public class Audio implements KeyListener {
private Lock lock = new ReentrantLock();
private final int[] m; // main memory
public final int AS1 = 0; // audio start
public final int AL1 = 1; // audio length
public final int AC1 = 2; // audio counter
public final int AG1 = 3; // audio gain
public final int AP1 = 4; // audio pitch
public final int APA1 = 5; // audio pitch accumulator
public int sample() {
lock.lock();
try {
int s = m[m[AS1] + m[AC1]] * m[AG1];
m[APA1] += m[AP1];
while (m[APA1] >= 2048) {
m[APA1] -= 2048;
++m[AC1];
if (m[AC1] > m[AL1]) { m[AC1] = 0; }
}
return s;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
JFrame window = new JFrame();
window.setPreferredSize(new Dimension(100, 100));
window.addKeyListener(new Audio());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.pack();
window.setVisible(true);
System.out.println("It takes a licking and keeps on ticking.");
while(true) {
try { Thread.sleep(1000); }
catch(InterruptedException e) {}
System.out.println("...and ticking.");
}
}
public Audio() {
lock.lock();
try {
m = new int[1024 * 512];
m[AS1] = 8;
m[AC1] = 0;
m[AG1] = 1;
m[AL1] = 4*1024*6;
m[AP1] = 2048;
m[APA1] = 0;
// make some sort of waveform.
// I don't even.
/*
for(int y = 0; y < 6; y++) {
for(int x = 0; x < m[AL1]; x++) {
m[m[AS1] + x + (m[AL1] * y)] = (int)(127 * Math.sin(x / (30.0 * y)));
}
}
*/
FileInputStream in = null;
int l = 0;
try {
in = new FileInputStream("hey.raw");
int c, d;
while ((c = in.read()) != -1) {
d = in.read();
m[m[AS1] + l++] = (c) | (d << 8);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
}
}
System.out.println(l);
m[AL1] = l;
} finally {
lock.unlock();
}
Thread pump = new Thread(new AudioPump(this));
pump.start();
}
public void keyPressed(KeyEvent k) {
lock.lock();
try {
// fuck ADSR envelopes we're doing this like a man:
m[AG1] = 1;
if (k.getKeyCode() == KeyEvent.VK_A) { m[AP1] -= 64; }
if (k.getKeyCode() == KeyEvent.VK_S) { m[AP1] += 64; }
/*
if (k.getKeyCode() == KeyEvent.VK_A) { m[AS1] = 4; }
if (k.getKeyCode() == KeyEvent.VK_S) { m[AS1] = 4 + m[AL1] / 2;}
if (k.getKeyCode() == KeyEvent.VK_D) { m[AS1] = 4 + m[AL1] / 3;}
if (k.getKeyCode() == KeyEvent.VK_F) { m[AS1] = 4 + m[AL1] / 4;}
if (k.getKeyCode() == KeyEvent.VK_G) { m[AS1] = 4 + m[AL1] / 5;}
if (k.getKeyCode() == KeyEvent.VK_H) { m[AS1] = 4 + m[AL1] / 6;}
*/
} finally {
lock.unlock();
}
}
public void keyReleased(KeyEvent k) { /*[AG1] = 0;*/ }
public void keyTyped(KeyEvent k) {}
}
class AudioPump implements Runnable {
final Audio audio;
final AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 1, 2, 44100, false);
final DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
final SourceDataLine soundLine;
final int buffSize = 4 * 1024;
public AudioPump(Audio audio) {
this.audio = audio;
try {
soundLine = (SourceDataLine)AudioSystem.getLine(info);
soundLine.open(format, buffSize);
} catch (LineUnavailableException e) {
e.printStackTrace();
throw new Error("unable to initialize output line.");
}
}
public void run() {
soundLine.start();
byte[] buffer = new byte[buffSize];
while(true) {
for(int x = 0; x < buffer.length;) {
int s = audio.sample();
buffer[x++] = (byte)(s);
buffer[x++] = (byte)(s >>> 8);
}
soundLine.write(buffer, 0, buffer.length);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment