/*
 * MODE_Primitives.h
 *		User Primitive Header for MODE on Objectworks\Smalltalk R4
 *
 * Copyright (C) 1991, Stephen Travis Pope, Nomad Computer Music Research.
 *		All rights reserved.
 *
 *			V4.0: File created: 8/24/91--stp
 */

/*******************************************************************************/
/*		----MIDIPort>>play/record				*/
/*		open									*/
/*			"Open MIDI--start the primitive scheduler up."			*/
/*			"MIDI code on /dev/midi, compatible to geg/lb world."	*/
void MIDIopen (/* upHandle receiverMidiPort */);

/*		close									*/
/*			"Close the MIDI scheduler down."		*/
/*			"MIDIPort default close"				*/
void MIDIclose (/* upHandle receiverMidiPort */);

/*		play: anEventAssociation					*/
/*			"Play the argument on the receiver."	*/
void MIDIplayAssociation (/* upHandle receiverMidiPort, eventAssociation */);

/*		play: anEvent at: startDuration			*/
/*			"Play the argument on the receiver at the given time."	*/
void MIDIplayEventAt (/* upHandle receiverMidiPort, event, startTime */);

/*		put: aByteArray count: anInteger			*/
/*			"Write the anInteger bytes of aByteArray out to the scheduler.*/
/*			The first four bytes of the array are a 'clock-tick' time."	*/
void MIDIplayBytes (/* upHandle receiverMidiPort, array, count */);

/*		status: anIntCode						*/
/*			"Primitive to set primitive scheduler status."			*/
void MIDIgetStatus (/* upHandle receiverMidiPort, code */);

/*		set: anIntCode data: anInteger				*/
/*			"Primitive to set scheduler values."	*/
void MIDIsetStatus (/* upHandle receiverMidiPort, code, pointer */);

/*		nextEventInto: anEventAssociation		*/
/*			"Record via the receiver into the argument."		*/
void MIDInextEvent (/* upHandle receiverMidiPort, eventAssociation */);

/*		next: aByteArray						*/
/*			"Answer the next available byte array from MIDI."	*/
void MIDInextBytes (/* upHandle receiverMidiPort, array */);

/*		----MIDIPort class>>play/record		*/
/*		test									*/
/*			"Test for the existence of MIDI output."	*/
void MIDItest (/* upHandle receiverMidiPortClass */);


/*******************************************************************************/
/*		----SampledSound>>interpolating		*/
/*		maxFrom: aStart to: aStop into: aFloat	*/
/*			"Answer the max (or min) abs sample in the last argument."	*/
ModeMaxSampleInt(/* upHandle receiverSound, startSamp, stopSamp, resultFloat */);

/*		sampledFrom: aStart to: aStop into: aSound					*/
/*			"Place a down-sampled version of the receiver in the argument sound."		*/
ModeDownSampleInt(/* upHandle receiverSound, startSamp, stopSamp, resultSound */);

/*		rmsFrom: aStart to: aStop into: anArray						*/
/*			"Place a version of the root-mean-square energy of the receiver in the array."	*/
ModeRMSSampleInt(/* upHandle receiverSound, startSamp, stopSamp, resultArray */);

/*		----SampledSound>>merging								*/
/*		extractChannel: cNumber into: aSound		*/
/*			"Extract the given channel from the receiver into the argument sound."	*/
ModeExtractChannelInt(/* upHandle receiverSound, channelNum, resultSound */);

/*		mergeChannel: cNumber from: aSound		*/
/*			"Merge the argument sound into the given channel of the receiver."		*/
ModeMergeChannelInt(/* upHandle receiverSound, channelNum, argumentSound */);

/*		----SampledSound>>envelopes			*/
/*		scaledFrom: aStart to: aStop by: aScaleFactor into: aSound		*/
/*			"Answer a copy of the receiver scaled by the given factor in the argument sound."	*/
ModeScaleSampleInt(/* upHandle receiverSound, startSamp, stopSamp, factorFloat, resultSound */);

/*		scaledFrom: aStart to: aStop byBPEnvelope: anArrayOfPoints into: aSound		*/
/*			"Answer a copy of the receiver scaled by the given breakpoint	*/
/*			 envelope expressed as points in the argument sound."			*/
ModeEnvelopeSampleInt(/* upHandle receiverSound, startSamp, stopSamp, envelopePoints, resultSound */);

/*		scaledFrom: aStart to: aStop byEnvelopeArray: anArray into: aSound		*/
/*			"Answer a copy of the receiver scaled by the envelope array in the argument sound."*/
ModeMultiEnvelopeSampleInt(/* upHandle receiverSound, startSamp, stopSamp, envelopePoints, resultSound */);

/*		----SampledSound>>analysis				*/
/*		fftTo: anArray params: pArray				*/
/*			"Place a version of the fft of the receiver in the argument array."		*/
/*			"frm's code"						*/

/*		lpcTo: anArray params: pArray				*/
/*			"Place a version of the fft of the receiver in the argument array."		*/
/*			"paul's code"					*/


/*******************************************************************************/
/*		----FloatSound>>interpolating		*/
/*		maxFrom: aStart to: aStop into: aFloat		*/
/*			"Answer the max (or min) abs sample in the last argument."			*/
/*		sampledFrom: aStart to: aStop into: aSound	*/
/*			"Place a down-sampled version of the receiver in the argument sound."		*/
/*		rmsFrom: aStart to: aStop into: anArray		*/
/*			"Place a version of the root-mean-square energy of the receiver in the array."	*/

/*		----FloatSound>>envelopes		*/
/*		scaledFrom: aStart to: aStop by: aScaleFactor into: aSound		*/
/*			"Answer a copy of the receiver scaled by the given factor in the argument sound."	*/
/*		scaledFrom: aStart to: aStop byBPEnvelope: anArrayOfPoints into: aSound	*/
/*			"Answer a copy of the receiver scaled by the given breakpoint envelope 	*/
/*			 expressed as points in the argument sound."					*/
/*		scaledFrom: aStart to: aStop byEnvelopeArray: anArray into: aSound		*/
/*			"Answer a copy of the receiver scaled by the envelope array in the argument sound."*/


/*******************************************************************************/
/*		----SPARCAudioPort>>play/record			*/
/*		open				*/
/*			"Open SSAudio port/stream."	*/
void ModeSSAudioOpen (/* upHandle receiverSSAudioPort */);

/*		close				*/
/*			"Close SSAudio down."		*/
void ModeSSAudioClose (/* upHandle receiverSSAudioPort */);

/*		play: aSound		*/
/*			"Play the argument on the receiver."		*/
/*			"play to /dev/audio"			*/
void ModeSSAudioPlay (/* upHandle receiverSSAudioPort, sound */);

/*		record: aSound		*/
/*			"Record into the argument via the receiver."		*/
/*			"record from /dev/audio"		*/
void ModeSSAudioRecord (/* upHandle receiverSSAudioPort, sound */);

/*		getProps: anArray	*/
/*			"Get the property array of the port into the given value array."		*/
void ModeSSAudioGetProps (/* upHandle receiverSSAudioPort, propArray */);

/*		setProps: anArray	*/
/*			"Set the property array of the port from the given value array."		*/
void ModeSSAudioSetProps (/* upHandle receiverSSAudioPort, propArray */);


/*******************************************************************************/
/*		----ProPort>>play/record			*/
/*		open				*/
/*			"Open the Pro Port."				*/
void ModeProPortOpen (/* upHandle receiverProPort */);

/*		close				*/
/*			"Close the Pro Port down."		*/
void ModeProPortClose (/* upHandle receiverProPort */);

/*		play: aSound		*/
/*			"Play the argument on the receiver."		*/
/*			"DSP-play"		*/
void ModeProPortPlay (/* upHandle receiverProPort, sound */);

/*		record: aSound		*/
/*			"Record into the argument via the receiver."		*/
/*			"DSP-record"	*/
void ModeProPortRecord (/* upHandle receiverProPort, sound */);

/*		getProps: anArray	*/
/*			"Get the property array of the port into the given value array."	*/
void ModeProPortGetProps (/* upHandle receiverProPort, propArray */);

/*		setProps: anArray	*/
/*			"Set the property array of the port from the given value array."	*/
void ModeProPortSetProps (/* upHandle receiverProPort, propArray */);


/*******************************************************************************/
/*		----Mix>>mixing	*/
/*		mixCollection: aCollectionofEventAssociations into: aSound		*/
/*			"Perform the mix of the given elements, creating a new sound."	*/
/*			"Mix engine"	*/
void ModeMixRun (/* upHandle receiverMix, elements, resultSound */);


/****************** C-Language Definitions for MODE UP's ******************/

#define ModeCheckSound(sound, samples)		\
	if (UPinstVarSize(sound) != 3)		UPfail((upInt) -4);	\
	samples = UPinstVarAt(sound, 3);				\
	if (!UPisByteLike(samples))		UPfail((upInt) -4);

#define ModeCheckInt(object, integer)				\
	if (!UPisSmallInteger(object))		UPfail((upInt) -4);	\
	integer = UPSTtoCint(object);

#define ModeCheckFloat(object, float)				\
	if (!UPisFloat(object))				UPfail((upInt) -4);	\
	float = UPSTtoCfloat(object);

