Created
July 28, 2011 02:53
-
-
Save yuriks/1110872 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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