Ignotus-mago / PixelAudio

PixelAudio maps arrays of audio samples onto arrays of pixel values.
Other
0 stars 0 forks source link

WaveSynth enhancements #16

Open Ignotus-mago opened 2 months ago

Ignotus-mago commented 2 months ago

In addition to using mapSize as the sampling frequency, put in hooks to use other frequencies, including audio recording frequencies. Then WaveSynth really will be an additive synthesis/color organ hybrid.

While we're at it, provide the same methods for gamma and histo correction that are being used in the PixelAudio example software.

JSON file read, anyhow. Maybe write (with interface) will arrive later. Read and write w/o interface, implemented. See JSONWaveSynth and BigWaveSynth example code.

Use WaveSynth with continuous gens over a multi-gen image. See BigWaveSynth.

Use WaveSynth with live audio layering -- i.e., different recordings modulate different colors.

Create a WaveSynth child class that accepts a signal for each color. WaveSynth requests the next value from each signal as it renders. Signals can be pre-calculated and cyclic.

Ignotus-mago commented 2 months ago

Rather than necessarily "Create a WaveSynth child class that accepts a signal for each color," we can hand off calculation of signal values to WaveData objects, that will in effect act like signals. So, in WaveSynth.renderPixel, we replace the commented out code with a call to a new method, waveValue, in WaveData:

// float val = (float) (Math.sin(wd.phaseTwoPi - frame * wd.phaseInc + wd.freq * freqShift * pos * mapInc) + woff)
//  * wscale + wd.dc;
float val = (wd.waveValue(frame, pos, freqShift, mapInc) + woff) * wscale + wd.dc;
weights[j] = val * wd.amp * this.gain;

We can call WaveData objects to do their own calculation for a WaveSynth:

public float waveValue(int frame, int pos, float freqShift, float mapInc) {
    return (float) Math.sin(this.phaseTwoPi - frame * this.phaseInc + this.freq * freqShift * pos * mapInc);
}

This way child classes of WaveData can produce all sorts of signals besides a sine. They can also use lookup tables, random variables, etc.

If we want a stream or a buffer as source for the waveValue, we may consider if this should be down by child classes of WaveData or by a new sort of WaveSynth.

Ignotus-mago commented 2 months ago

The argosy pattern maker could implement a waveValue method. It could also just copy its pixels directly to a WaveSynth's mapImage.