Created
November 1, 2019 14:56
-
-
Save ayaysir/a65618d6e315b69a258a6061a8b2e5de to your computer and use it in GitHub Desktop.
Jacob Collier's Microtonal Game
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
package blog.freq; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javax.sound.sampled.AudioFormat; | |
import javax.sound.sampled.AudioSystem; | |
import javax.sound.sampled.LineUnavailableException; | |
import javax.sound.sampled.SourceDataLine; | |
public class Freq { | |
public static float SAMPLE_RATE = 8000f; | |
private AudioFormat af; | |
private SourceDataLine sdl; | |
// Constructor | |
public Freq() throws LineUnavailableException { | |
af = new AudioFormat(SAMPLE_RATE, 8, 1, true, false); | |
sdl = AudioSystem.getSourceDataLine(af); | |
} | |
public void tone(double hz, double ms) throws LineUnavailableException{ | |
tone(hz, ms, 1.0); | |
} | |
public void tone(double hz, double ms, double vol) throws LineUnavailableException { | |
byte[] buf = new byte[1]; | |
sdl.open(af); | |
sdl.start(); | |
// Speicify playback time from SAMPLE_RATE | |
int sizePerMs = (int)(SAMPLE_RATE / 1000); | |
for(int i = 0; i < ms * sizePerMs; i++) { | |
double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI; | |
buf[0] = (byte) (Math.sin(angle) * 127.0 * vol); | |
sdl.write(buf, 0, 1); | |
} | |
sdl.drain(); | |
} | |
public void tones(List<Double> freqs, double ms) throws LineUnavailableException { | |
tones(freqs, ms, 1.0); | |
} | |
public void tones(List<Double> freqs, double ms, double vol) throws LineUnavailableException { | |
byte[] buf = new byte[1]; | |
sdl.open(af); | |
sdl.start(); | |
// Speicify playback time from SAMPLE_RATE | |
int sizePerMs = (int)(SAMPLE_RATE / 1000); | |
for(double hz : freqs) { | |
for(int i = 0; i < ms * sizePerMs; i++) { | |
double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI; | |
buf[0] = (byte) (Math.sin(angle) * 127.0 * vol); | |
sdl.write(buf, 0, 1); | |
} | |
} | |
sdl.drain(); | |
} | |
public void close() { | |
sdl.stop(); | |
sdl.close(); | |
} | |
public static void main(String[] args) throws Exception { | |
Freq f = new Freq(); | |
// double a4 = 452; | |
// for(int i = 1; i <= 16; i++) { | |
// System.out.println(a4 / 6.727 * i); | |
// f.tone(a4 / 6.727 * i, 500); | |
// } | |
System.out.println("== Microtonal Game (Ascending) ==\n"); | |
double startFreq = 329.63, // E4 ~ G4 | |
endFreq = 392; | |
int startDiv = 2, endDiv = 8; | |
for(int i = startDiv; i <= endDiv; i++) { | |
System.out.printf("--[%d]--\n", i); | |
double eachFreq = (endFreq - startFreq) / i; | |
List<Double> freqs = new ArrayList<Double>(); | |
for(int j = 0; j <= i; j++) { | |
double freq = startFreq + eachFreq * j; | |
freqs.add(freq); | |
} | |
// Display each frequency on time | |
new Thread(() -> { | |
try { | |
for(Double hz : freqs) { | |
System.out.printf("%.2f\t", hz); | |
Thread.sleep(200); | |
} | |
}catch(InterruptedException e) {} | |
}).start(); | |
f.tones(freqs, 200); | |
Thread.sleep(500); | |
System.out.print("\n\n"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment