#ifndef __QUANTUM_H
#define __QUANTUM_H

#include "graal_isolate.h"


#if defined(__cplusplus)
extern "C" {
#endif

/*
 * Create a time-stretching engine. Arguments:

 * • Isolate thread,

 * • sample rate, in Hz (between 32000 and 192000),

 * • number of channels (1 = mono, 2 = stereo, etc), between 1 and 8

 * • time-stretch ratio (1.0 = no change, 1.2 = 20% slower, etc), between 0.25 and 4.0,

 * • quality (between 1 and 5),

 * • transient sensitivity (between 0.0 and 1.0, ignored if quality < 3).

 * returns the created engine as an opaque pointer, or null on error.
 */
void* quantum_createEngine(graal_isolatethread_t*, float, int, double, int, float);

/*
 * Set the serial key. Without a valid serial key, this engine won't process more than 30 seconds. Arguments:

 * • Isolate thread,

 * • engine created by quantum_createEngine(),

 * • the serial key.

 * returns true on success.
 */
int quantum_setSerialKey(graal_isolatethread_t*, void*, char*);

/*
 * Get the length of the output audio chunk for this engine. Arguments:

 * • Isolate thread,

 * • engine created by quantum_createEngine().

 * returns number of audio frames (1 sample in each channel). The corresponding size in bytes is the returned value times the number of channels times sizeof(float).
 */
int quantum_getOutputChunkLength(graal_isolatethread_t*, void*);

/*
 * Prepare for real-time processing, by preallocating required resources.

 * Do not use for off-line processing. If this method is not invoked, the latency will be automatically compensated.

 * • Isolate thread,

 * • engine created by proton_createEngine().

 * • time-stretch ratio, must be the same value as the one passed to proton_createEngine()

 * returns the latency, in output frames. The value might be fractional if the time stretch ratio is fractional; you may want to round it to the nearest integer.
 */
double quantum_prepareRealtime(graal_isolatethread_t*, void*, double);

/*
 * Produce the next output audio chunk. Arguments:

 * • Isolate thread,

 * • engine created by quantum_createEngine().

 * • a function pointer to read input audio samples. Signature: int readSamples(float* target, int length);

 *   the function MUST provide exactly the requested number of audio sample frames, unless the end has been reached;

 *   the length is in audio sample frames (1 audio sample in each channel); 

 *   the function must return the number of audio sample frames provided.

 * • a preallocated pointer into which the output samples will be written by this method;

 *   Its size must match the value returned by quantum_getOutputChunkLength().

 * returns the number of audio sample frames actually produced. A value of -1 means that the end has been reached.
 */
int quantum_process(graal_isolatethread_t*, void*, void *, float*);

/*
 * Destroy an engine created by quantum_createEngine(). Arguments:

 * • Isolate thread,

 * • engine created by quantum_createEngine().
 */
int quantum_destroyEngine(graal_isolatethread_t*, void*);

int run_main(int argc, char** argv);

#if defined(__cplusplus)
}
#endif
#endif
