/* SampleObject.h */

#ifndef Included_SampleObject_h
#define Included_SampleObject_h

/* SampleObject module depends on */
/* MiscInfo.h */
/* Audit */
/* Debug */
/* Definitions */
/* Memory */
/* DataMunging */
/* SampleList */
/* SampleWindow */
/* FixedPoint */
/* SampleConsts */
/* SampleStorageActual */
/* MainWindowStuff */
/* BufferedFileInput */
/* BufferedFileOutput */

#include "SampleConsts.h"
#include "FixedPoint.h"
#include "MainWindowStuff.h"

struct SampleObjectRec;
typedef struct SampleObjectRec SampleObjectRec;

/* forward declarations */
struct MainWindowRec;
struct CodeCenterRec;
struct SampleListRec;
struct SampleStorageActualRec;
struct BufferedInputRec;
struct BufferedOutputRec;

/* allocate and create a new empty sample object, with reasonable defaults */
SampleObjectRec*			NewSampleObject(struct CodeCenterRec* CodeCenter,
												struct MainWindowRec* MainWindow,
												struct SampleListRec* SampleList);

/* allocate and create a sample object with the specified attributes */
/* the RawData field must not be NIL.  It will be copied for the new sample */
SampleObjectRec*			NewSampleObjectInitialized(struct CodeCenterRec* CodeCenter,
												struct MainWindowRec* MainWindow,
												struct SampleListRec* SampleList, char* DataToCopy,
												NumBitsType NumBits, NumChannelsType NumChannels, long Origin,
												long LoopStart1, long LoopStart2, long LoopStart3,
												long LoopEnd1, long LoopEnd2, long LoopEnd3, long SamplingRate,
												double NaturalFrequency);

/* dispose of a sample object */
void									DisposeSampleObject(SampleObjectRec* SampObj);

/* find out if sample object has been modified */
MyBoolean							HasSampleObjectBeenModified(SampleObjectRec* SampObj);

/* get a copy of the sample's name. */
char*									SampleObjectGetNameCopy(SampleObjectRec* SampObj);

/* set the sample's name.  the object becomes the owner of the Name block so */
/* the caller should not release it. */
void									SampleObjectNewName(SampleObjectRec* SampObj, char* Name);

/* get a copy of the formula applied to the sample */
char*									SampleObjectGetFormulaCopy(SampleObjectRec* SampObj);

/* install a new formula into the sample.  the object becomes the owner of the */
/* formula, so the caller should not release it */
void									SampleObjectNewFormula(SampleObjectRec* SampObj, char* Formula);

/* get the number of bits in a channel for the sample */
NumBitsType						SampleObjectGetNumBits(SampleObjectRec* SampObj);

/* get the number of channels in the sample */
NumChannelsType				SampleObjectGetNumChannels(SampleObjectRec* SampObj);

/* get the loop control values.  if the loop end and loop start are the same, */
/* then there is no loop */
long									SampleObjectGetOrigin(SampleObjectRec* SampObj);
long									SampleObjectGetLoopStart1(SampleObjectRec* SampObj);
long									SampleObjectGetLoopStart2(SampleObjectRec* SampObj);
long									SampleObjectGetLoopStart3(SampleObjectRec* SampObj);
long									SampleObjectGetLoopEnd1(SampleObjectRec* SampObj);
long									SampleObjectGetLoopEnd2(SampleObjectRec* SampObj);
long									SampleObjectGetLoopEnd3(SampleObjectRec* SampObj);

/* get sample attributes */
long									SampleObjectGetSamplingRate(SampleObjectRec* SampObj);
double								SampleObjectGetNaturalFrequency(SampleObjectRec* SampObj);

/* get the number of sample frames */
long									SampleObjectGetNumSampleFrames(SampleObjectRec* SampObj);

/* get a pointer to the raw data for the sample.  this pointer is the */
/* actual data, not a copy, so don't dispose of it.  if any operations are performed */
/* on the sample, this pointer may become invalid.  format of raw data: */
/*  - mono, 8-bit:  array of signed bytes */
/*  - stereo, 8-bit:  array of signed bytes, grouped in pairs.  the one lower in */
/*    memory is the left channel */
/*  - mono, 16-bit:  array of signed short integers (either 2 or 4 bytes) */
/*  - stereo, 16-bit:  array of signed short integers, grouped in pairs.  the one */
/*    lower in memory is the left channel */
char*									SampleObjectGetRawData(SampleObjectRec* SampObj);

/* put new data into the sample.  the num channels, bits, and data has to be put */
/* in all at the same time so that no reformatting routines need to be supplied. */
/* the object becomes owner of the data block, so it must not be released by the */
/* caller.  this call should also be made BEFORE any of the calls to set the */
/* attributes, since the attribute's values will be constrained based on this data */
void									SampleObjectPutNewSample(SampleObjectRec* SampObj,
												struct SampleStorageActualRec* NewStorage);

/* change the loop control values and attributes */
void									SampleObjectPutOrigin(SampleObjectRec* SampObj, long Origin);
void									SampleObjectPutLoopStart1(SampleObjectRec* SampObj, long LoopStart);
void									SampleObjectPutLoopStart2(SampleObjectRec* SampObj, long LoopStart);
void									SampleObjectPutLoopStart3(SampleObjectRec* SampObj, long LoopStart);
void									SampleObjectPutLoopEnd1(SampleObjectRec* SampObj, long LoopEnd);
void									SampleObjectPutLoopEnd2(SampleObjectRec* SampObj, long LoopEnd);
void									SampleObjectPutLoopEnd3(SampleObjectRec* SampObj, long LoopEnd);
void									SampleObjectPutSamplingRate(SampleObjectRec* SampObj,
												long SamplingRate);
void									SampleObjectPutNaturalFrequency(SampleObjectRec* SampObj,
												double NaturalFrequency);

/* call which makes object open its editor window */
MyBoolean							SampleObjectOpenWindow(SampleObjectRec* SampObj);

/* this is called by the window when it is closing to notify the object. */
/* the object should not take any action. */
void									SampleObjectClosingWindowNotify(SampleObjectRec* SampObj,
												short NewXSize, short NewYSize, short NewWidth, short NewHeight);

/* obtain fixed point array of data.  NIL is returned if there isn't enough memory. */
largefixedsigned*			SampleObjectGetLeftFixed(SampleObjectRec* SampObj);
largefixedsigned*			SampleObjectGetRightFixed(SampleObjectRec* SampObj);
largefixedsigned*			SampleObjectGetMonoFixed(SampleObjectRec* SampObj);

/* the document's name has changed, so the window needs to be updated */
void									SampleObjectGlobalNameChange(SampleObjectRec* SampObj,
												char* NewFilename);

/* read a sample object from the file */
FileLoadingErrors			SampleObjectNewFromFile(SampleObjectRec** ObjectOut,
												struct BufferedInputRec* Input, struct CodeCenterRec* CodeCenter,
												struct MainWindowRec* MainWindow,
												struct SampleListRec* SampleList);

/* write the data in a sample object out to the file */
FileLoadingErrors			SampleObjectWriteOutData(SampleObjectRec* SampObj,
												struct BufferedOutputRec* Output);

/* mark sample object as not modified */
void									SampleObjectMarkAsSaved(SampleObjectRec* SampObj);

#endif
