Compare commits

...

3 Commits

Author SHA1 Message Date
Emilien Bauer a0515ae626 Try linking GUI to sound 2 years ago
Anton Lydike 20bbc7e843 fixed gui stuff 2 years ago
Anton Lydike f3c678f589 added gui and stuff like that 2 years ago

@ -1,9 +1,15 @@
import Params.PI
import Params.SAMPLES
import Params.TWO_PI
import Params.as_samples
import filter.Compressor
import filter.EchoFilter
import filter.Limiter
import java.lang.StrictMath.pow
import gui.SimpleEx
import random.RandomDisplacementFractal
import java.awt.event.WindowAdapter
import javax.swing.JSlider
import kotlin.math.cos
import kotlin.math.pow
import kotlin.math.sin
@ -39,9 +45,10 @@ class SineWaveGenerator(var tone: Float) : StepGenerator() {
class RandomGenerator(var tone: Float) :StepGenerator() {
val N = 200
val loudness = fun(i:Int): Double {
return i.toDouble().pow(-0)
return i.toDouble().pow(power)
}
var loudnessSum = 0.0
var power:Double = -1.0
init {
for (i in 1 .. N)
loudnessSum+=loudness(i)
@ -54,26 +61,58 @@ class RandomGenerator(var tone: Float) :StepGenerator() {
return (p/loudnessSum).toFloat()
}
}
class RandomDisplacementFractalNoiseGenerator(private val period: Float, val repetitions: Int): StepGenerator() {
val width = (period * SAMPLES).toInt()
val rng = RandomDisplacementFractal( 4f, width, repetitions)
var pos: Int = 0
override fun generateSingle(time: Float): Float {
val x = pos % width
val y = (pos / width) % repetitions
pos ++
return rng.get(x, y)
}
}
fun main(args: Array<String>) {
val sink = AudioSink()
val machine = SoundMachine()
SoundMachine.State.bpm = 1024F
machine.globalEffects.add(Compressor(as_samples(.4f).toInt())::apply)
machine.globalEffects.add(Limiter(.9f)::apply)
val gen = RandomGenerator(0f)
machine.generators.add(Chain(gen::generate, ArrayList()))
val gen = SoundMachine()
sink.enqueueChunk(machine.nextChunk())
gen.globalEffects.add(Compressor(as_samples(.4f).toInt())::apply)
gen.globalEffects.add(Limiter(.9f)::apply)
sink.start()
gen.generators.add(Chain(RandomGenerator(0f)::generate, ArrayList()))
val close = false
sink.enqueueChunk(gen.nextChunk())
Thread {
while (!close) {
sink.enqueueChunk(machine.nextChunk())
while (sink.queueSize > 1) {
Thread.sleep(1)
}
}
}.start()
sink.start()
val frame = SimpleEx("Play!")
for (i in 1..100) {
sink.enqueueChunk(gen.nextChunk())
frame.add_slider("Property 1", 0, 10000, 50).addChangeListener { e ->
val value = (e.source as JSlider).value
gen.power = -value.toDouble()/100.0
println("Switching power to " + gen.power.toString())
}
sink.terminate()
frame.isVisible = true
}

@ -2,6 +2,9 @@ package filter
import java.lang.Float.max
import java.lang.Float.min
import java.util.*
import kotlin.math.absoluteValue
import kotlin.math.pow
import kotlin.math.sign
fun clamp(min_val: Float, value: Float, max_val: Float) : Float{
return max(min(value, max_val), min_val)
@ -12,8 +15,9 @@ class EchoFilter(size: Int, private val volume: Float = 0.5f) : StepFilter() {
private val cache: Queue<Float> = LinkedList(List(size) { 0f })
override fun step(value: Float): Float {
val effect = value + cache.remove() * volume
cache.add(effect)
val effect = value + cache.remove()
cache.add(effect.absoluteValue.pow(volume) * effect.sign)
return effect
}
}

@ -0,0 +1,40 @@
package gui
import java.awt.GridLayout
import java.awt.Label
import javax.swing.JFrame
import javax.swing.JSlider
class SimpleEx(title: String) : JFrame() {
init {
createUI(title)
}
private fun createUI(title: String) {
setTitle(title)
defaultCloseOperation = EXIT_ON_CLOSE
setSize(400, 300)
setLocationRelativeTo(null)
layout = GridLayout(20, 2)
}
fun add_slider(name: String, min: Int, max: Int, value: Int): JSlider {
add(Label(name))
val slider = JSlider(min, max, value)
slider.minorTickSpacing = 10;
slider.paintTicks = true;
add(slider)
return slider
}
}
fun main() {
}

@ -1,107 +0,0 @@
package random;
import java.util.Random;
public class RandomDisplacementFractal {
/** Source of entropy */
private Random rand_;
/** Amount of roughness */
float roughness_;
/** Plasma fractal grid */
private float[][] grid_;
/** Generate a noise source based upon the midpoint displacement fractal.
*
* @param rand The random number generator
* @param roughness a roughness parameter
* @param width the width of the grid
* @param height the height of the grid
*/
public RandomDisplacementFractal(Random rand, float roughness, int width, int height) {
roughness_ = roughness / width;
grid_ = new float[width][height];
rand_ = (rand == null) ? new Random() : rand;
}
public void initialise() {
int xh = grid_.length - 1;
int yh = grid_[0].length - 1;
// set the corner points
grid_[0][0] = rand_.nextFloat() - 0.5f;
grid_[0][yh] = rand_.nextFloat() - 0.5f;
grid_[xh][0] = rand_.nextFloat() - 0.5f;
grid_[xh][yh] = rand_.nextFloat() - 0.5f;
// generate the fractal
generate(0, 0, xh, yh);
}
// Add a suitable amount of random displacement to a point
private float roughen(float v, int l, int h) {
return v + roughness_ * (float) (rand_.nextGaussian() * (h - l));
}
// generate the fractal
private void generate(int xl, int yl, int xh, int yh) {
int xm = (xl + xh) / 2;
int ym = (yl + yh) / 2;
if ((xl == xm) && (yl == ym)) return;
grid_[xm][yl] = 0.5f * (grid_[xl][yl] + grid_[xh][yl]);
grid_[xm][yh] = 0.5f * (grid_[xl][yh] + grid_[xh][yh]);
grid_[xl][ym] = 0.5f * (grid_[xl][yl] + grid_[xl][yh]);
grid_[xh][ym] = 0.5f * (grid_[xh][yl] + grid_[xh][yh]);
float v = roughen(0.5f * (grid_[xm][yl] + grid_[xm][yh]), xl + yl, yh
+ xh);
grid_[xm][ym] = v;
grid_[xm][yl] = roughen(grid_[xm][yl], xl, xh);
grid_[xm][yh] = roughen(grid_[xm][yh], xl, xh);
grid_[xl][ym] = roughen(grid_[xl][ym], yl, yh);
grid_[xh][ym] = roughen(grid_[xh][ym], yl, yh);
generate(xl, yl, xm, ym);
generate(xm, yl, xh, ym);
generate(xl, ym, xm, yh);
generate(xm, ym, xh, yh);
}
/**
* Dump out as a CSV
*/
public void printAsCSV() {
for(int i = 0;i < grid_.length;i++) {
for(int j = 0;j < grid_[0].length;j++) {
System.out.print(grid_[i][j]);
System.out.print(",");
}
System.out.println();
}
}
/**
* Convert to a Boolean array
* @return the boolean array
*/
public boolean[][] toBooleans() {
int w = grid_.length;
int h = grid_[0].length;
boolean[][] ret = new boolean[w][h];
for(int i = 0;i < w;i++) {
for(int j = 0;j < h;j++) {
ret[i][j] = grid_[i][j] < 0;
}
}
return ret;
}
}

@ -0,0 +1,105 @@
package random
import java.util.*
class RandomDisplacementFractal(val roughness: Float,val width: Int,val height: Int) {
/** Source of entropy */
private var rand_: Random = Random()
/** Amount of roughness */
val roughness_ = roughness / width
/** Plasma fractal grid */
private val grid_: Array<FloatArray> = Array(width) { FloatArray(height) }
init {
println("Creating fractal...")
initialise()
println("fractal created")
}
fun initialise() {
val xh = grid_.size - 1
val yh = grid_[0].size - 1
// set the corner points
grid_[0][0] = rand_.nextFloat() - 0.5f
grid_[0][yh] = rand_.nextFloat() - 0.5f
grid_[xh][0] = rand_.nextFloat() - 0.5f
grid_[xh][yh] = rand_.nextFloat() - 0.5f
// generate the fractal
generate(0, 0, xh, yh)
}
// Add a suitable amount of random displacement to a point
private fun roughen(v: Float, l: Int, h: Int): Float {
return v + roughness_ * (rand_.nextGaussian() * (h - l)).toFloat()
}
operator fun get(i: Int, j: Int): Float {
if (i >= 0 && i < grid_.size) {
if (j >= 0 && j < grid_[0].size) {
return grid_[i][j]
}
}
throw IndexOutOfBoundsException("Out of bounds access detected!")
}
// generate the fractal
private fun generate(xl: Int, yl: Int, xh: Int, yh: Int) {
val xm = (xl + xh) / 2
val ym = (yl + yh) / 2
if (xl == xm && yl == ym) return
grid_[xm][yl] = 0.5f * (grid_[xl][yl] + grid_[xh][yl])
grid_[xm][yh] = 0.5f * (grid_[xl][yh] + grid_[xh][yh])
grid_[xl][ym] = 0.5f * (grid_[xl][yl] + grid_[xl][yh])
grid_[xh][ym] = 0.5f * (grid_[xh][yl] + grid_[xh][yh])
val v = roughen(
0.5f * (grid_[xm][yl] + grid_[xm][yh]), xl + yl, yh
+ xh
)
grid_[xm][ym] = v
grid_[xm][yl] = roughen(grid_[xm][yl], xl, xh)
grid_[xm][yh] = roughen(grid_[xm][yh], xl, xh)
grid_[xl][ym] = roughen(grid_[xl][ym], yl, yh)
grid_[xh][ym] = roughen(grid_[xh][ym], yl, yh)
generate(xl, yl, xm, ym)
generate(xm, yl, xh, ym)
generate(xl, ym, xm, yh)
generate(xm, ym, xh, yh)
}
/**
* Dump out as a CSV
*/
fun printAsCSV() {
for (floats in grid_) {
for (j in grid_[0].indices) {
print(floats[j])
print(",")
}
println()
}
}
/**
* Convert to a Boolean array
* @return the boolean array
*/
fun toBooleans(): Array<BooleanArray>? {
val w = grid_.size
val h = grid_[0].size
val ret = Array(w) { BooleanArray(h) }
for (i in 0 until w) {
for (j in 0 until h) {
ret[i][j] = grid_[i][j] < 0
}
}
return ret
}
}
Loading…
Cancel
Save