#include "artsflow.idl"
#include "kmedia2.idl"
#include "core.idl"

module Arts {

/**
 * One entry of the sample storage - initially, you'll need to fill the entry.
 *
 * To do so, call write repeatedly to fill it with data, and finish() when
 * you are done. After that you can use the filename attribute to get the
 * name of the file on the server that has stored the data. You can use
 * this filename for other things (i.e. SimpleSoundServer::play).
 */
interface SampleStorageEntry {
	readonly attribute string name;
	readonly attribute string filename;
	readonly attribute boolean completed;

	void write(sequence<byte> data);
	void finish();
};

/**
 * Interface for storing files on the sound server
 */
interface SampleStorage {
	void constructor(string directory, boolean clearOnInit);

	/**
	 * creates a new entry which you can use to store a sample - if you just
	 * create an entry, it will be private to you, i.e. you can use it, and
	 * as soon as you don't need it any longer, it will be freed
	 *
	 * if you want that the entry stays in the storage, you need to add it,
	 * and it will stay then until you remove it
	 */
	SampleStorageEntry createEntry(string name);

	/**
	 * add an entry (which will make it accessible via findEntry) - remember
	 * to eventually call removeEntry, or the entry will stay there forever
	 */
	void addEntry(SampleStorageEntry entry);

	/**
	 * removes an entry, that is, the entry will only stay there until
	 * nobody needs it any more and then get freed
	 */
	void removeEntry(SampleStorageEntry entry);

	/**
	 * finds an entry by name
	 */
	SampleStorageEntry findEntry(string name);
};

/**
 * Producer of byte sound
 *
 * This is used inside the sound server interface
 */
interface ByteSoundProducer : SynthModule
{
	readonly attribute long samplingRate;
	readonly attribute long channels;
	readonly attribute long bits;

	async out byte stream outdata;
};

/**
 * V2 version of the ByteSoundProducer interface that implements the title
 * attribute
 */
interface ByteSoundProducerV2 : ByteSoundProducer
{
	readonly attribute string title;
};

/**
 * Receiver of byte sound
 */
interface ByteSoundReceiver : SynthModule
{
	readonly attribute long samplingRate;
	readonly attribute long channels;
	readonly attribute long bits;
	readonly attribute string title;

	async in byte stream indata;
};

/**
 * This is a very simple sound server interface
 *
 * WARNING: This currently inherits a KMedia2 PlayObjectFactory for test
 *          purposes, but don't rely on that
 */

interface SimpleSoundServer : PlayObjectFactory
{
	readonly attribute StereoEffectStack outstack;

	/**
	 * tries to play the sound in "filename"
	 *
	 * returns an ID when success 0 when it fails
	 */
	long play(string filename);

	/**
	 * returns true if the sound in ID is still playing
	 */
	//boolean isPlaying(long ID);

	/**
	 * stops a playing sound by ID
	 */
	//void stop(long ID);

	/**
	 * specifies the minimum amount of milliseconds that have to be buffered
	 * to allow safe streaming (without interruptions) from/to external apps
	 *
	 * this depends on the realtime parameters the sound server itself uses
	 * to talk to the hardware
	 */
	readonly attribute float minStreamBufferTime;

	/**
	 * specifies the amount of milliseconds the server itself spends with
	 * the hardware (buffering latency) - so if you stream into the server,
	 * you should have a yourStreamBufferTime >= minStreamBufferTime, and
	 * the total latency is
	 *
	 *  totalLatency = yourStreamBufferTime + serverBufferTime
	 */
	readonly attribute float serverBufferTime;

	/**
	 * attaches a byte sound producer (read: a client which produces/mixes
	 * an audio stream itself and just wants playback via the soundserver)
	 */
	void attach(ByteSoundProducer producer);

	/**
	 * detaches a previous attached byte sound producer
	 */
	void detach(ByteSoundProducer producer);

	/**
	 * attaches a byte sound receiver (a client that records an
	 * audio stream from the soundserver)
	 */
	void attachRecorder(ByteSoundReceiver receiver);

	/**
	 * detaches a previous attached byte sound receiver
	 */
	void detachRecorder(ByteSoundReceiver receiver);

	object createObject(string name);
};

enum RealtimeStatus { rtRealtime, rtNoSupport, rtNoWrapper, rtNoRealtime };

/**
 * This is an enhanced sound server interface which can be used to
 * query status information or suspend the soundserver right away
 */
interface SoundServer : SimpleSoundServer
{
	readonly attribute RealtimeStatus realtimeStatus;

	/**
	 * Returns how many seconds you have to wait _now_ for the soundserver
	 * to suspend. A value of -1 signals that the sound server is busy and
	 * will not suspend automatically at the moment.
	 */
	readonly attribute long secondsUntilSuspend;

	/**
	 * Makes the soundserver suspend now _if_ it is not busy playing, that
	 * is, if it is "suspendable". Returns true if successful.
	 */
	boolean suspend();

	/**
	 * Asks the soundserver if it is suspended.  Returns true if so.
	 */
	boolean suspended();

	/**
	 * Permanently terminates the sound server - this is not intended to be
	 * widely used. However, it provides a way to "kill" the sound server,
	 * even if you don't reside on the same host with it, and even if you
	 * don't know the process id, and so on. In the future it also offers
	 * the possibility for interested apps to be informed before the server
	 * goes away, and for important apps to block termination.
	 *
	 * Returns true if successful.
	 */
	boolean terminate();
};

/**
 * This is an even more enhanced sound server interface that supports changing
 * the autosuspend time, and returning more information about the server
 * settings.
 */
interface SoundServerV2 : SoundServer, PlayObjectFactoryV2
{
	/**
	 * Time in seconds after which server will suspend if idle.
	 */
	attribute long autoSuspendSeconds;

	/**
	 * Multiplier for size of network buffers. Default is 1,
	 * which is fragment size * fragment count. (expressed
	 * as milliseconds).
	 */
	attribute long bufferSizeMultiplier;

	/**
	 * Current CPU usage in percent
	 */
	readonly attribute float cpuUsage;

	/**
	 * AudioSubSystem parameters
	 */
	readonly attribute string audioMethod;
	readonly attribute long samplingRate;
	readonly attribute long channels;
	readonly attribute long bits;
	readonly attribute boolean fullDuplex;
	readonly attribute string audioDevice;
	readonly attribute long fragments;
	readonly attribute long fragmentSize;

	/**
	 * version
	 */
	readonly attribute string version;

	/**
	 * global output volume for the sound server
	 */
	readonly attribute StereoVolumeControl outVolume;

	/**
	 * for storing samples on the sound server
	 */
	readonly attribute SampleStorage sampleStorage;

	/**
	 * this method checks for new object implementations (you can call this
	 * if you have implemented and installed new components in C++ or with
	 * artsbuilder, to make the soundserver use them without restart)
	 */
	void checkNewObjects();
};

/**
 * A KMedia2 Wave PlayObject
 */
interface WavPlayObject : PlayObject, SynthModule
{
	out audio stream left,right;
};

/**
 * An advanced KMedia2 PlayObject based on GSL datahandles
 */
interface GSLPlayObject : PlayObject, PitchablePlayObject, SynthModule
{
	attribute boolean done;

	out audio stream left,right;
};

/**
 * Helper interface to ensure that artsd gets initialized properly when
 * multiple artsd processes are started at the same time.
 */
interface SoundServerStartup
{
	void lock();
	void unlock();
};

};
