Overview

Introduction

Grainstorm has four tracks that continuously loop when active and a sound is loaded.

While the tracks loop, short snippets (grains) are extracted from the loaded sound, an envelope is applied to them, and they are written to an output buffer.

If the READ OFFSET, which is the position from where the current grain is read, moves along the sound at the same velocity (SPEED 1.0) as the velocity at which output is sent to Digital to Analog Conversion, and there are no gaps between successive grains, the resulting sound is identical to the original sound. When the velocities are unequal (SPEED unequal to 1.0) and overlapping grains are written to the output buffer, periodic phase interferences of the frequency components of the grains occur in the resulting sound, with the period determined by the DENSITY parameter.

A significant aspect of Grainstorm and granular synthesis, in general, involves generating evolving spectra by modulating parameters that affect how grains are read from the input sound, how they are written to the output buffer, and how their phases align when overlapped. Most of these parameters can be modulated by LFOs.

Grainstorm includes effects that manipulate individual grains in both the time and spectral domains. Effects in the spectral domain are known as Phase Vocoder and Cross Synthesis effects. Cross Synthesis blends two sounds into one hybrid sound.

Application Structure

Each of the four tracks has three LFOs and three Envelope Followers.

It is possible to synchronize the loop durations of all tracks and LFOs.

Each track has three effect queues: one for grain-by-grain effects (2), one for mono effects (6), and one for stereo effects (7). Each effect is appended to the corresponding queue when activated. The last activated effect will be the last one to be processed.

Here is what happens when a track computes sound:

1. Read the grain, apply PRE GAIN -> Pass it through grain-by-grain effects -> Phase Vocoder if active -> Cross Synthesis if active -> Apply grain envelope -> Write grain to outputbuffer -> Repeat for next grain until all grains are processed.
2. Apply Mono Effects on outputbuffer
3. Apply Stereo Effects on outputbuffer, apply POST GAIN

Note: Stereo effects have been separated from the mono effects for performance reasons.

Interface

The four tracks can be accessed via the upper horizontal buttons, numbered 1 - 4.

Track-specific synthesis parameters are accessed via the vertical buttons numbered 1 - 7 inside the track. They are arranged in sections in the order by which the tracks read parameters when computing sound.

Sections have subsections which can be browsed by the arrows or entered directly by tapping the text inside the arrows:

back
GRANULATION
forw
Sections and subsections Track1
waveform
granulation1
pv
env
lfo
followers
fx
stereofx

General Controls

Power Button
The power button located outside the track in the upper right corner turns audio engine on/off.
Settings Button
General Settings
Short double tap on rotary controls and sliders resets their current value to its initial state.
Tap on the title of a control opens an input field.
Short double tap on waveform changes the loop mode.
Waveform can be pinch zoomed.

Track and LFO Specific Controls

Eject Button
Opens the Android file picker to load a sound. Decoding can be interrupted by pressing the back button on your device.
Mic Button
Starts and stops microphone recording.
Sync Button
Activates or deactivates syncing on the specific track, LFO or delay.
back
2
forw
Syncfactor
Settings Button
Some track-specific settings are accessed by the settings button located inside the track.
Power Button
Activates/Deactivates track or LFO.
Skip Back
Jumps to loop start.
Stop Button
Sets playback speed to zero. Stops looping.
Play Button
Sets playback speed to its last positive value. Starts looping.
Skip Forward
Jumps to loop end.
Rev
Reverses loop direction.
Slow
Slows down times syncfactor.
Fast
Speeds up times syncfactor.
Fast
SYNC

Loop Modes

Loop Mode is changed by a short double tap on the waveform.

Three Loop Modes are available:

When the offset position marker is blue, the read offset is set to the beginning of the loop if it passes the end of the loop. If it passes the beginning of the loop, it is set to the end of the loop.
When it is orange, looping is in ping-pong mode, and the playback direction is reversed when the read offset passes either of the loop boundaries. Additionally, the read direction of the sound data is reversed.
When it is green, looping is in ping-pong mode, but the read direction is not reversed when the read offset passes loop boundaries.

The second mode provides smoother loops when random read or write offset is inactive (and playback speed is 1.0), while the third mode provides smoother loops when it is active.

When TAPE MODE is active and looping is in the third mode (green loop endpoints), bidirectional looping is performed.

Syncing

Fast
SYNC
Sync Button
Activates or deactivates Syncing on the specific track, LFO or delay.
back
2
forw
Syncfactor

SYNC modifies playback speed, LFO rate, or delay of all tracks, LFOs, and delays with syncing enabled, such that their loop durations match the loop duration of the calling track, LFO, or delay. If the resulting playback speed, LFO rate, or delay would be too small or too large, it is multiplied or divided by the sync factor of the calling track, LFO, or delay until it is in the appropriate range.

If STOP, PLAY, VEL DOWN, VEL UP, SKIP, or REV is pressed on a track, LFO, or delay that has syncing enabled, the same event is sent to all tracks, LFOs, and delays that have syncing enabled.

Sharing of Sound Input between Tracks

By default, each track routes what has been imported from a sound file or recorded to itself. Inside the track settings, the input routing can be changed. DENSITY, SPEED, and loop positions are shared, while all other parameters and effects can be independently adjusted for each track that operates on the same sound. This may be useful for processing different parts of the spectrum individually, such as low-pass filtering on one track and high-pass filtering on another, or for layering different pitches.

Synthesis Parameters

The following descriptions are in the order in which synthesis parameters appear in the UI from top to bottom for the main sections and left to right for the subsections. The UI is arranged in the order in which parameters are read by the tracks for sound synthesis.

Granulation 1

GRAINSIZE determines the size of the grain. Range is from 5 ms to 1 s.

DENSITY sets the rate at which new grains are triggered in Hz. Range is from 1 to 500 Hz.

RND READ adds a random offset to the current read position inside the sampled sound. DEVIATION (See Grain Generation) adds randomness to grain triggering. Both cancel the periodicity of phase interferences of overlapping grains in the output buffer. The tradeoff is the introduction of noise.

PANNING sets the gain for left (L) and right (R) channels on a grain-by-grain basis, similar to PREGAIN but unlike POSTGAIN, which sets the output gain sample by sample. This parameter is active only when the app is in stereo mode.

ENV CYCLES refers to envelope cycles. This parameter can be LFO modulated. Determines how often the wavetable containing ENV1 is iterated through when it is applied to the grain. Values higher than 20 (or less with small grainsizes) result in a kind of ring modulation. For ENV2 this parameter is ignored. ENV2 is always read a single time. Please also see Grain Envelopes.

ENV PHASE adds an offset when reading ENV1. This parameter can also be modulated by an LFO. For ENV2 this parameter is ignored. ENV2 is always read a single time. Please also see Grain Envelopes.

PITCH changes the overall pitch of the resulting sound by simple resampling of individual grains. For a pitch increase of one octave, the grain is read from twice the samples as its grain size, with every second sample skipped.

GLISS: Grain glissando.

REVERSE: At 0, no grains are reversed. At 1.0, all grains are reversed. At 0.5, there is a 50:50 probability for normal/reversed grains.

Granulation 2

BANDLIMITED ENVELOPE: A bandlimited grain envelope is computed. Please also see Grain Envelopes.

ENVELOPE ONLY / NO INPUT means the grain is not filled with samples and consists solely of the grain envelope. Please also see Grain Envelopes.

INTEGER ENVCYCLES represents integer envelope cycles. The UI displays a rounded value for ENV CYCLES, but if this parameter is deactivated, fractions of ENV1 may be applied, adding energy to the spectrum. For ENV2, this parameter is ignored. ENV2 is always read a single time.

WSOLA stands for Waveform Similarity Overlap Add. It is a time stretching algorithm that computes the read position of the grain so that it best matches the grain that would have been read at the original speed of 1.0. Try different grain sizes and densities at speeds down to 0.25 (4x stretch factor).

HQ RESAMPLING: Use a higher quality resampling algorithm for grain pitch shifting. Adds computational overhead.

Grain Generation

Randomized granulation parameters in stereo mode create a stereo effect due to different randomized values for each channel. If SYNC L/R is active, the grains in the left and right channels have the same write offset.

SWING adds rhythmic variation to grain generation.

RND1 adds a uniformly distributed write offset to the grains. The offset is uniformly distributed within [0, DEVIATION * SAMPLERATE / DENSITY] samples.

RND2 adds a Gaussian (normal) distributed write offset to the grains.

BOUNCE attempts to generate grains in a manner similar to a bouncing ball.

SPLINE modifies grain density according to a random spline curve.

FOLLOW modifies density according to the gain envelope of the input signal.

Sequencer1 / Sequencer2 / Arpeggiator

Simple sequencer/arpeggiator which can be used to build sequences of grains, each with individual pitch/grainsize/gain.

STEPS determines the length of the sequence.

VEL UP/DOWN adjusts DENSITY, which is multiplied or divided by sync factor. This changes the rate at which grains are triggered, making the sequence run faster or slower.

GRAINS, SILENCE: Use to skip grains.

There are 8 slots available to save and load a sequence. A new sequence is loaded when the current sequence ends.

Note: Use the slider at the bottom of SEQUENCER2 to scroll the screen.

Random Pitch

Adds a random offset to the current pitch. For example, when SEMITONES is set to 6, MIN to -1 and MAX to 1, the pitch of the current grain is randomly chosen to be one tritone below the current pitch, the current pitch itself and one tritone above the current pitch.

PITCH MIN AND PITCH MAX additionally add a random pitch offset that is not restricted to semitones.

Grain by Grain Effects

RESON: A basic resonant bandpass filter. Filters each grain with randomized center frequency and bandwidth (Q).

RINGMOD ring modulates each grain with randomized modulation rates.

REVERB: A simple grain-by-grain reverb. The state of the reverb is not reset for new grains, allowing previous grains to resonate. Different grainsizes, densities, and envelopes qualitatively impact the reverb.

TAPE MODE: When activated, granulation-related processing is skipped. The sound is processed using a high-quality resampling algorithm with a restricted SPEED range of 0.1 to 2.0x (ten times slowed down to two times sped up). Lower or higher values are ignored. FADE can be used to smooth the loop. Please observe the waveform to understand its operation.

Grain by Grain Effects included in Upgrade

BUZZ fills the grain with harmonics (PARTIALS) of a fundamental frequency (CPS). OFFSET determines the starting harmonic, while BRIGHTNESS adjusts the loudness of higher harmonics.

MODAL passes either an impulse (with PRE GAIN) or the grain (with IN GAIN) through a bank of resonators tuned to the resonances (modes) of well-known sound objects.

VCO fills the grain with output from up to three bandlimited oscillators. Each oscillator can be detuned relative to CPS, producing beating effects. In stereo mode, DETUNELR creates binaural beating. Pulsewidth (PW) modulation is available when the oscillator waveform is PULSE or RAMP. This effect includes its own FILTER instance, controlled in the grain-by-grain FILTER section and activated with the FILTER switch.

CPS for BUZZ, MODAL, and VCO, takes its value from PDETECT if FOLLOW is enabled in any of these effects. PDETECT must be active. HOLD when active holds the current pitch.

FILTER filters each grain with one of several resonant filters, with sweepable frequency on a per-grain basis. When used with VCO, this creates grains in an analog subtractive synthesis style.

PDETECT performs pitch detection on the unprocessed source sound before applying any grain-by-grain effects. SMOOTH helps to smooth rapid changes in detected pitch between successive detections. PRELP filters the signal before pitch detection for more precise results. BOUNDA and BOUNDB adjust the pitch detection range. TRANSPOSE transposes the detected pitch in octaves.

Note: Pitch detection occurs with each new grain and should be used at low grain densities for optimal performance.

Phase Vocoder and Cross Synthesis

Before delving into specific effects, we provide a brief description of the underlying algorithms and implementation details:

Manipulation of Spectral Representation: Phase Vocoder and Cross Synthesis effects alter the spectral representation of the grain.
Transformation to Spectral Representation: The Fast Fourier Transform (FFT) algorithm is utilized to transform the grain from its time-domain representation to its spectral representation.
Grain Size Considerations: When Phase Vocoder or Cross Synthesis is active, GRAINSIZE is disregarded. Instead, the grain size can only be adjusted using the FFT SIZE parameter, which is specified in samples. The FFT size significantly influences the resulting sound quality. Larger FFT sizes generally enhance sound quality but require more computational resources.
Envelope Considerations: When Phase Vocoder or Cross Synthesis is active, ENV1 and ENV2 are disregarded, and a single internal envelope is used.

Phase Vocoder

PHASE CORRECTION I and II adjust phases of frequency components between successive grains to eliminate interferences at playback speeds other than 1.0.

FORMANT STRETCH computes a spectral envelope, adjusts its width, and applies it back to the grain.

RANDOM PHASE sets a random phase for each frequency component of the grain.

ZERO PHASE sets the phase of each frequency component of the grain to zero.

OSC BANK retains the loudest frequency components of the grain, while setting others to zero. Phase of kept frequencies can be original, zero, or continuous.

FREQ WARP maps one part of the spectrum to another.

Cross Synthesis

Cross Synthesis effects blend two sounds into a hybrid sound, distinct from simple mixing.
When enabled on a track, referred to as the source, the MODULATOR track, used to blend with the source, does not produce any output by itself. It stops computation once it provides the current grain in spectral representation, which the source then uses to complete computation.
Changing GRAINSIZE or FFT SIZE on the modulator has no effect because FFT sizes must be equal, and the FFT SIZE of the source is used.
Both tracks, source and modulator have to be active, otherwise cross synthesis will not be performed.

POLAR FORM interchanges magnitudes or phases of source or modulator.

CEPSTRUM shapes the spectrum of the source using the spectral envelope of the modulator.

CEPSTRUM WHITE additionally flattens the source spectrum.

INTERPOLATION: Sophisticated algorithm to interpolate between spectral envelopes and spectra of modulator and source. The interpolation parameter can be modulated by an LFO.

Spectral envelope estimation uses the "Cepstrum Method for Spectral Envelope Estimation". The CUT OFF parameter determines the smoothness of the spectral envelope.

VOCODER packs FFT results into CHANNELS, averaging magnitudes and interpolating between source and modulator spectra. Phases remain unchanged.

CONVOLUTION convolves source and modulator signals using fast convolution, akin to convolution reverbs but with time-varying impulse responses (up to 16384 samples).

LPC: Linear prediction-based algorithm complements the vocoders, using modulator to compute a filter representing its formants and applying it to the source. WHITE additionally computes an anti-filter to filter out formants from the source before applying the modulator filter.

Grain Envelopes

Grainstorm offers two options for creating a grain envelope: ENV1 and ENV2.

ENV1 comprises an inner envelope shaped by an outer envelope. The DEPTH parameter determines the influence of the outer envelope, while CYCLES specifies how many times its wavetable is iterated. This setup allows creating complex, symmetric waveforms.

The available waveforms for the outer and inner envelope include common waveforms from sound synthesis, as well as others without discontinuities typically used in granular synthesis.

FULL prefixed waveforms are bipolar, while others are unipolar.

ENV2 allows drawing an envelope resembling an ADSR curve.

Both ENV1 and ENV2 envelopes are applied to the grains. Upon application startup, ENV2 is set to a straight line at 1.0, indicating no effect unless adjusted. To nullify the effect of ENV1, set its inner envelope to rectangular waveform and DEPTH to 0.

For ENV2, ENV CYCLES and ENV PHASE are ignored. ENV2 can be used to smooth the start and end of ENV1, especially when modulating ENV PHASE or ENV CYCLES with INTEGER CYCLES disabled.

Waveforms with discontinuities can cause aliasing distortion. The app offers the ability to compute bandlimited envelopes (GRANULATION2, BANDLIMITED ENVELOPE), which smooths these discontinuities. However, computing bandlimited envelopes is computationally expensive, so it is advisable to enable this feature only when you are ready to hear a bandlimited version of your sound.

You can also choose to disable filling the grain with sampled sound and use only the envelope as the grain (GRANULATION2, ENVELOPE ONLY). This mode is suitable for granular synthesis with grain sizes typically below 50 ms and densities above 20 Hz. Values significantly above or below these ranges may result in silence. For instance, setting a grainsize of 1 second and density to 1 Hz causes the envelope waveform to oscillate at 1 Hz, which is well below the 18-20 Hz range perceptible by humans. Additionally, using waveforms that are only positive may introduce a strong DC component. Using a bipolar waveform for the inner envelope reduces the likelihood of the grains summing to a signal dominated by DC.

LFOs

LFOs with syncing enabled match their cycle duration to the loop duration of the track by pressing the SYNC button. This also works in reverse: the loop durations of the tracks are synced to one LFO cycle by pressing the SYNC button of the LFO.

Each parameter that can be modulated by the LFO has its own modulation range, adjustable by BOUND A and BOUND B. Initially, BOUND A and BOUND B are set to the same value, resulting in no modulation. Modulation begins when BOUND A and BOUND B have different values.

You can choose between four common waveforms or a custom waveform.

Note: When an LFO is controlling a grain parameter at a high rate and DENSITY is set at a low rate, it may sound as if the LFO is running slowly or not running at all. For example, if the LFO rate is 20Hz and DENSITY is also 20Hz, the LFO phase at the point it is looked up for the corresponding grain parameter will be the same for each grain. DENSITY should be at least 40Hz or more in this case for satisfying results (LFO rate/density ratio of 1:2 or better 1:4).

LFO waveform editor

The number of points is changed with SEGMENTS. There are three options to connect points: polynomial, linear, and rectangular. A short double tap on the editor window adjusts the positions of points according to QUANT. The waveform editor can be pinch-zoomed.

Screenshots
lfocustom
lfoedit

Envelope Followers

When TRACK1 - TRACK4 is set to a track different than the track on which the envelope follower is active, for performance reasons the control signal is the last computed buffer of that track (one buffer delay), otherwise it is what arrives at the effect in.

Effects

SSB MOD is based on "Single Sideband Modulation". The effect is also called "Frequency Shifter". It basically does the same as ring modulation. Carrier frequencies below audio rate result in a phasing effect, but only if there is some dry signal mixed with the wet signal.

VOCODER blends the output of two tracks as does Cross Synthesis. It takes as input the computed output buffers (granulation is already done at this point). The track whose sound is to be blended with is indicated as MODULATOR. Unlike Cross Synthesis, the modulator track still produces output and its POSTGAIN can be reduced if this is undesired. In commercial vocoders, there usually is a synth integrated which acts as the source, while the signal routed into the vocoder (often a voice) acts as the modulator. Grainstorm allows you to take any two sounds and do some granular manipulations before using them as source or modulator.

CREVERB: Convolution Reverb. Takes as impulse the raw audio of the track from where it is to be loaded, beginning at the current read position, with a maximum impulse response length of ten seconds. Any sound can be tried as an impulse response, not only ambient resonances, but care must be taken as the result may be very loud. Starting with a short impulse response or a stream of very short grains at low density as impulse is good practice.

COMPRESSOR allows sidechain compression. As with the envelope followers, if the track to take the control signal from is different than the track on which the compressor is active, the last computed output buffer of that track is taken as the control signal, resulting in a delay of one buffer. Because of multithreading, the compressor cannot wait until output is ready on another track.

Effects included in Upgrade

We only mention the uncommon effects. It should be clear what the other effects do.

DELAY and the delays of MULTIDELAY have a HOLD switch. When activated, FEEDBACK is set to 1.0 and no more input is inserted into the delay lines, resulting in a loop of what is currently in the delay. Delay time can be synced to track loops and LFO cycles and vice versa as described above.

SPECTRAL FILTER tries to slow down spectral evolution by filtering each of the channels of successive FFTs taken from the signal with special resonant low pass filters.

SPECTRAL DELAY delays channels of successive FFTs taken from the signal. An arbitrary curve can be drawn with the horizontal axis representing frequency and the vertical axis representing delay. If FOLLOW is active, individual FFT channels are delayed according to their magnitude.

PVAMPS: Phase Vocoder Amplitudes. Selects the loudest channels of successive FFTs of the incoming signal to drive up to six bandlimited oscillators at the frequencies of the computed loudest channels. SMOOTH smooths rapid variations of channel indices in between successive FFTs.

SPECTRAL FILTER, SPECTRAL DELAY2, and PVAMPS work on the computed output buffer. The granulation part of the app is finished at the point these effects are invoked. As they are Phase Vocoder effects, the signal on which they operate has to be granulated, and they do their own granulation internally. These effects introduce a delay of 256 samples.

FM: Six Frequency Modulation units each consist of up to six operators. Chords can be built by adjusting SEMITONES for each unit. Their frequency is changed in relation to CPS. DETUNE and FB affect beating. FB is routed to the gain of a low pass filter by which the self-modulation signal of some of the operators is filtered. DETUNELR gives binaural beating if the app is in stereo mode. INDEX of modulation can be set as an envelope follower target. With FOLLOW enabled, pitch is taken from PDETECT.

PDETECT does the same as the pitch detector from the grain effects, with the difference that it takes as input the output buffer after granulation and before the mono effects instead of the unmodified source sound.

Miscellaneous

Audio buffer size, control rate and latency

Control rate depends on audio buffer size as all control parameters are read before each new audio buffer is computed. This is then sent to the DAC. This means that by reducing audio buffer size the application gets more responsive at the cost of slightly increased computational overhead. The smallest possible buffer size is different from device to device and it has to be tried to see which buffersize will work. On some devices there may be software dependent irregularities in the period the DAC requests new buffers which results in clipping. In such cases larger buffer sizes have to be used.

Load

The bottom status bar shows the sum of time the audio engine has taken to provide new buffers in percentage of the total time available to provide new buffers. The value is updated every 250ms. It should never get close to 100%, otherwise audio clipping will occur. As the value gives the sum over 250ms, there may have been xruns in between and the value can still indicate less than 100%.

Performance

The audio engine is multithreaded, based on the fact that modern CPUs have various cores and work can be distributed. Each channel of each track runs in its own thread. If your CPU has various fast cores, full load on all four tracks in stereo may be possible. Load should stay the same regardless of whether one or multiple tracks are active. It may help to deactivate the internet and close other applications that run in the background and may temporarily require access to the CPU if you encounter glitches.

RAM Usage

In raw state, when no audio data is loaded, Grainstorm uses about 50mb of RAM on a cell phone and about 70mb on a 10-inch tablet. As all audio data is loaded into RAM for fast access, a five-minute, 16bit, 48kHz stereo file increases these values by about 60mb. If Android is running low on memory, it shuts down applications. If you encounter problems with large audio files (like the app being randomly shut down), close other applications to free memory or switch to mono mode. If nothing helps, you will have to use shorter audio files.

MIDI

If you use a physical controller, connect it from the Main menu under "MIDI Connection" or for virtual controllers/software, choose Grainstorm as MIDI Receiver from their preferences.

Learning mode is entered by pressing the small rect at the bottom of the left sidebar. Currently, only "Note On" events for the buttons and "Control Change" events for rotary controls/sliders are supported. Assignable controls will change color when learning mode is active. When touching any of these, a pop up window will open. On moving a slider or pressing a button on your controller or on receiving any MIDI event, it should indicate the channel and control value received. Press commit to assign.

If you own the upgrade, the LFOs can be synced to an external midiclock signal. If it is active on an LFO, its phase is no longer updated internally. Instead, it is updated when the app receives midiclock events. The phase advance can be modified with the "MIDI x" parameter. For example, if your controller is set to 120 BPM and this parameter is set to 0.1 the LFO will complete 12 cycles in one minute.

Presets

If you own the upgrade, you can save the state of the app either on a per-track basis or for the entire project.

Inside the preset section of the main settings, there is an option to save the audio (in 16-bit FLAC lossless format) along with the preset. We recommend enabling this option, as otherwise, the preset will not work after reinstalling the app or deleting the audio file. Additionally, it is advisable to set and use a custom preset folder that can be backed up when switching devices.