Data update
This commit is contained in:
parent
72eb4943cb
commit
4d5544505c
2347 changed files with 62432 additions and 16731 deletions
|
|
@ -1,4 +1,6 @@
|
|||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
|
|
@ -7,48 +9,54 @@ import javax.sound.sampled.SourceDataLine;
|
|||
public final class MusicalScale {
|
||||
|
||||
public static void main(String[] aArgs) {
|
||||
List<Double> frequencies = List.of( 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25 );
|
||||
final int duration = 500;
|
||||
List<Double> frequencies = List.of( 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25 );
|
||||
|
||||
prepareSourceDataLine();
|
||||
|
||||
final int duration = 500; // in milliseconds
|
||||
final int volume = 1;
|
||||
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
IntStream.range(0, 3).forEach( _ -> {
|
||||
for ( double frequency : frequencies ) {
|
||||
musicalTone(frequency, duration, volume);
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
sourceDataLine.close();
|
||||
}
|
||||
|
||||
private static void musicalTone(double aFrequency, int aDuration, int aVolume) {
|
||||
byte[] buffer = new byte[1];
|
||||
AudioFormat audioFormat = getAudioFormat();
|
||||
private static void musicalTone(double frequency, int duration, int volume) {
|
||||
sourceDataLine.start();
|
||||
|
||||
try ( SourceDataLine sourceDataLine = AudioSystem.getSourceDataLine(audioFormat) ) {
|
||||
sourceDataLine.open(audioFormat);
|
||||
sourceDataLine.start();
|
||||
|
||||
for ( int i = 0; i < aDuration * 8; i++ ) {
|
||||
double angle = i / ( SAMPLE_RATE / aFrequency ) * 2 * Math.PI;
|
||||
buffer[0] = (byte) ( Math.sin(angle) * 127 * aVolume );
|
||||
sourceDataLine.write(buffer, BYTE_OFFSET, buffer.length);
|
||||
}
|
||||
|
||||
sourceDataLine.drain();
|
||||
sourceDataLine.stop();
|
||||
sourceDataLine.close();
|
||||
} catch (LineUnavailableException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
IntStream.range(0, 8 * duration).forEach( i -> {
|
||||
final double angle = i / ( SAMPLE_RATE / frequency ) * 2 * Math.PI;
|
||||
byte[] buffer = new byte[] { (byte) ( Math.sin(angle) * 127 * volume ) };
|
||||
sourceDataLine.write(buffer, BYTE_OFFSET, buffer.length);
|
||||
} );
|
||||
|
||||
sourceDataLine.drain();
|
||||
sourceDataLine.stop();
|
||||
}
|
||||
|
||||
private static AudioFormat getAudioFormat() {
|
||||
private static void prepareSourceDataLine() {
|
||||
final int sampleSizeInBits = 8;
|
||||
final int numberChannels = 1;
|
||||
final boolean signedData = true;
|
||||
final boolean isBigEndian = false;
|
||||
|
||||
return new AudioFormat(SAMPLE_RATE, sampleSizeInBits, numberChannels, signedData, isBigEndian);
|
||||
AudioFormat audioFormat = new AudioFormat(
|
||||
SAMPLE_RATE, sampleSizeInBits, numberChannels, signedData, isBigEndian);
|
||||
|
||||
try {
|
||||
sourceDataLine = AudioSystem.getSourceDataLine(audioFormat);
|
||||
sourceDataLine.open(audioFormat);
|
||||
} catch (LineUnavailableException lue) {
|
||||
lue.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static SourceDataLine sourceDataLine;
|
||||
|
||||
private static float SAMPLE_RATE = 8_000.0F;
|
||||
private static final int BYTE_OFFSET = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,36 +1,36 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Sample Page</title>
|
||||
<script>
|
||||
function musicalScale(freqArr){
|
||||
// create web audio api context
|
||||
var AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||
var audioCtx = new AudioContext();
|
||||
const SEMITONE = 2 ** (1 / 12)
|
||||
|
||||
// create oscillator and gain node
|
||||
var oscillator = audioCtx.createOscillator();
|
||||
var gainNode = audioCtx.createGain();
|
||||
|
||||
// connect oscillator to gain node to speakers
|
||||
oscillator.connect(gainNode);
|
||||
gainNode.connect(audioCtx.destination);
|
||||
|
||||
// set frequencies to play
|
||||
duration = 0.5 // seconds
|
||||
freqArr.forEach(function (freq, i){
|
||||
oscillator.frequency.setValueAtTime(freq, audioCtx.currentTime + i * duration);
|
||||
});
|
||||
|
||||
// start playing!
|
||||
oscillator.start();
|
||||
// stop playing!
|
||||
oscillator.stop(audioCtx.currentTime + freqArr.length * duration);
|
||||
function incrementSemitones(root) {
|
||||
return (n) => root * SEMITONE ** n
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<button onclick="musicalScale([261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]);">Play scale</button>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
function playNotes(root, notes, { seconds, wave } = {}) {
|
||||
const ctx = new AudioContext()
|
||||
const oscillator = ctx.createOscillator()
|
||||
const freqs = notes.map(incrementSemitones(root))
|
||||
|
||||
oscillator.connect(ctx.createGain().connect(ctx.destination))
|
||||
oscillator.type = wave ?? 'sine'
|
||||
|
||||
const duration = seconds ?? 0.3
|
||||
|
||||
for (const [i, freq] of freqs.entries()) {
|
||||
oscillator.frequency.setValueAtTime(freq, ctx.currentTime + i * duration)
|
||||
}
|
||||
|
||||
oscillator.start()
|
||||
oscillator.stop(ctx.currentTime + freqs.length * duration)
|
||||
|
||||
return new Promise((res) => oscillator.addEventListener('ended', res))
|
||||
}
|
||||
|
||||
const A = 440
|
||||
const C = incrementSemitones(A)(-9) // ~= 261.63
|
||||
|
||||
const major = [0, 2, 4, 5, 7, 9, 11, 12]
|
||||
const minor = [0, 2, 3, 5, 7, 8, 10, 12]
|
||||
|
||||
void (async function main() {
|
||||
await playNotes(C, major, { seconds: 0.3, wave: 'sine' })
|
||||
await playNotes(A, minor, { seconds: 0.1, wave: 'triangle' })
|
||||
})()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue