home *** CD-ROM | disk | FTP | other *** search
- This is the document for the dissidents' samp.library 1.0 © 1989. Set your
- editor's TAB width to 3.
-
-
- «««««««««««««« WHAT THE HELL IS SAMP? »»»»»»»»»»»»
- (or "If it doesn't have anything to do with video, what good is it?")
-
- SAMP is an IFF file format used to store any resolution audio data. This
- format is used in dissidents' Midi Sample Wrench, a 16 bit audio waveform
- editing program for the Amiga. The dissidents' samp.library is a library
- used to load and save SAMP files. The samp.library will allow you to write
- applications that can save and retrieve audio data saved in the SAMP format.
- For a detailed spec of the SAMP format, consult the SAMP.doc file.
- The samp.library is written entirely in 68000 assembly for speed and small
- size. Distributed with the library are C and assembly Include files and example
- applications, as well as a utility to convert 8SVX files to SAMP, and other
- SAMP support libraries.
-
-
- ««««««««««««««««« COPYRIGHT NOTICE »»»»»»»»»»»»»»»»»»
-
- The samp.library and ToSAMP conversion utility are copyright by dissidents
- software. These two files may be used by and freely distributed with any
- application, commercial or otherwise, although copyright is retained exclu-
- sively by dissidents, and the files must not be modified in any way. In
- addition, the following files are copyright by dissidents, and may only be
- distributed on disks which are freely-distributable or for which a nominal
- charge to cover media and shipping is the only consumer cost:
-
- 1). SAMPlib.doc
- 2). SAMP.doc
- 3). ToSAMP.asm
- 4). Exam.c, Exam.asm
- 5). SAMP.i, SAMP.h
- 6). SAMPInterface.asm
- 7). TestInsType.c, TestInsType.asm
- 8). InsTypeInterface.asm
- 9). instype.library
- 10). SAMP_ReadOut.c
- 11). SAMP_Writer.c
-
- All copyright notices must remain intact.
-
-
- «««««««««««««««« CURRENT LIMITATIONS »»»»»»»»»»»»»»»»
-
- The library does not support loading/saving SAMP files inside of a CAT or
- LIST, nor does it currently support Continuation files or NumOfChans > 4.
- Due to memory considerations, the library can only be servicing one task
- at any given moment (though several tasks may simultaneously open the library).
-
-
- ««««««««««««««««« DATA STRUCTURES »»»»»»»»»»»»»»»»»
-
- Before you open and use the samp.library, you must create a few structures
- and variables from which the library can load/save data. The most important
- structure is is the SampleHeader64 structure. It is used to hold information
- about 1 waveform such as its size, OneShotStart and LoopStart addresses, Root
- Note, and velocity table. Each waveform that is loaded must have its own 64
- byte SampleHeader64 structure. Furthermore, all the SampleHeader64 structures
- must be contiguous in memory. For this reason, an application should allocate
- the proper number of SampleHeader64 structures before actually loading the
- waveform data. This can be done by either of the following procedures:
-
- 1). Determine the maximum # of waves that the application can load, and
- declare an array of this many SampleHeader64 structures.
- (The C example takes this approach).
-
- 2). After opening a file (via OpenSampRead) and examining the MHDR's
- NumOfWaves, allocate a block of mem with size = sizeofSampleHeader64
- * NumOfWaves.
-
- The string buffers for the waves' names must also be contiguous in memory.
- For this reason, your application must decide upon the maximum length of each
- name, and allocate an appropriately sized mem block. On the other hand, you
- may forego allocating any string buffers, in which case the library will ignore
- loading the waves' names.
-
- Finally, a pointer to a TransposeNode must be declared (and initially set
- to zero). A TransposeNode is a structure that the library will create for
- every different sampleRate in a SAMP file. These structures are all linked
- into a list to which your variable points. A TransposeNode contains a transpose
- table as described in the SAMP doc.
-
- Note that these structures are not part of the SAMP spec itself. They simply
- facilitate the playback of SAMP files with minimal processing delays.
-
-
- «««««««««««««««««« LIBRARY STRUCTURES »»»»»»»»»»»»»»»»
-
- When you open a SAMP file to read or write, you gain exclusive access to
- the samp.library's structures until you close the file. One structure is a
- SAMPInfo structure. This contains an imbedded MHDR chunk. When you open a
- SAMP for reading via OpenSampRead(), the SAMP's MHDR is loaded into the library
- SAMPInfo's MHDR. So, you can examine the file's NumOfWaves, NumOfChans,
- Format, etc before loading any wave data. The SAMPInfo also contains fields to
- store pointers to (addresses of) functions within your application. These
- functions will be called at certain times by the library's read/write routines.
- For example, you can supply a pointer to a function which will be called by
- the library's ReadWaves() for every wave's FATK data handling. The SAMPInfo
- also contains fields to specify the maximum allowed length of a wave's name,
- the type of mem into which the wave data will be loaded, and Seek() offsets
- from the beginning of the file to various chunks.
-
- The library also has a waveHeader structure as described in the SAMP doc.
- This structure is used by ReadWaves() and WriteWaves() to hold data per each
- wave read/written.
-
-
- «««««««««««««««««««« OPENING THE LIBRARY »»»»»»»»»»»»»»»»»»»
-
- The samp.library file must be copied to the libs drawer of your boot disk.
-
- Then, any application may open and use the library via a call to Exec's
- OpenLibrary(). The current version of samp is 0. The library is closed via
- Exec's CloseLibrary(). C applications must be linked with the module
-
- SAMPInterface.asm
-
- (which itself must be assembled by your C compiler's assembler).
-
-
- ««««««««««««««««««««« THE LIBRARY FUNCTIONS »»»»»»»»»»»»»»»»»»
-
- Here are descriptions and calling procedures for the library functions:
-
-
- *************************** OpenSampRead *****************************
-
- This routine must be called first in order to read in a SAMP file and
- perform operations on it via other library routines such as LoadNames,
- LoadPlaymap, MixPlaymap, and ReadWaves. It opens the file, determines
- if it is a SAMP file that the library can read, and prevents other tasks
- from using the library until the file is processed and closed.
-
- This is passed the name of the SAMP file to be opened (a NULL-terminated
- string). Also, you may pass a pointer to a function which the library should
- call for unknown chunks, or instead pass in 0. The library understands
- "BODY", "AUTH", "ANNO", "NAME", "MHDR" and "(c) " chunks. If you pass a 0,
- it will ignore all other chunks. If you pass a pointer to your own function,
- it will call your function as so:
-
- flag = UnknownChunk( ID, ChunkSize, SeekOffset, SAMPInfo );
- d0 d2 d4 a4
-
- ID ULONG, IFF-type ID ( eg, 'XYZ0' ).
- ChunkSize ULONG, Size of this chunk.
- SeekOffset ULONG, Offset from start of the file.
- SAMPInfo Pointer to library's SAMPInfo structure.
-
- flag ULONG, return value.
-
- If you return a 1, then the OpenSampRead terminates and closes the file.
- A 0 allows OpenSampRead to continue.
- For more details, see the section "PROCESSING UNKNOWN CHUNKS".
-
- OpenSampRead() returns the address of the library's SAMPInfo structure
- or 0 if an error. The z-flag is cleared for error (bne Error), set otherwise.
- An error may be caused by some other task already using the library, failure
- to open the requested file, the requested file is not a SAMP file, or the BODY
- for this SAMP file cannot be located within this file (i.e. will not support
- Continuation files). For C programmers, the exact error number is returned
- in a variable called SAMPError (which is a global in the module
- SampInterface.asm). For assembly programmers, the exact error number is
- returned in d1.
-
- SAMPInfo = OpenSampRead( Filename, UnKnownVector );
- d0 d1 a0
-
- Filename Pointer to UBYTE, DOS name of the desired SAMP file.
- UnKnownVector Pointer to a function ( APTR ) ( use 0 to skip unknown chunks ).
-
- SAMPInfo Pointer to a SAMPInfo structure.
-
- ***************************** CloseSamp *******************************
-
- Closes a SAMP file that was opened for reading or writing, and frees the
- library for other tasks to use. This must be called after you have successfully
- opened a SAMP file (via OpenSampRead or OpenSampWrite), and are finished
- processing it.
-
- CloseSamp();
-
-
- ***************************** ReadWaves *********************************
-
- #define nameSize 20 /* just for an example */
-
- total = ReadWaves( offsetWave, totalWaves, nameBuffer[offsetWave][nameSize], SampleHeader64[offsetWave] );
- d0 d6 d7 a2 a3
-
- offsetWave ULONG, first wave to start loading.
- totalWaves ULONG, number of waves to load in.
- &nameBuffer[][] Address of UBYTE buffer array which will hold wave names.
- &SampHead64[] Address of SampleHeader64 structures array, which will
- hold the individual waves data.
-
- total ULONG, total number of waves actually read in.
-
- Loads the specified range of waves within the SAMP file between offsetWave
- and offsetWave+totalWaves. offsetWave is the first wave to start loading
- (with the first wave in the SAMP file being wave #0). Loads them starting at
- the passed SampleHeader64. Also loads the names for these waves starting at
- nameBuffer unless passed a NULL. Before calling ReadWaves, you should
- set the library SAMPInfo's MaxChars variable to the max # of chars each
- nameBuffer can hold. The default is 20 bytes. All names are padded out with
- spaces and NULL-terminated.
-
- Also, you should set the SAMPInfo's ATAKvector, RLSEvector, FATKvector,
- FRLSvector, USERvector, and EXTRAvector to point to any routines you want the
- library to call per wave. If you don't, the default is for the library to
- ignore FATK, FRLS, and USER data, and to read/reformat ATAK and RLSE EGPoints
- into the SampleHeader64's envelope fields.
-
- offsetWave is specified from zero (i.e. a value of zero won't skip any waves
- in the file. A 2 will skip the first 2 waves in the file and start loading the
- 3rd wave into SampleHeader1.) For totalWaves = 1, only 1 wave is loaded.
-
- This returns the number of waves actually loaded (0 if none). Sets
- z-flag for success, cleared for error. For C programmers, the exact error
- number is returned in a variable called SAMPError. For assembly programmers,
- the exact error number is returned in d1.
-
- Each wave's SampleHeader64 structure has an TransTable field. ReadWaves()
- places each wave's sampleRate in this field. Later, you can extract the value
- from this field when making the transpose tables, and rewrite the field with
- a pointer to the ORIGINAL pitch of the table. See the C example.
-
- The library calls your ATAK, RLSE, FATK, FRLS, or USER vector only if a
- wave has data. In other words, if a wave doesn't have any FRLS EGPoints,
- then the library skips calling your FRLS vector when loading that wave.
- The library calls your EXTRA vector AFTER each wave's 80 byte waveHeader
- and BEFORE the sample data is read in. This vector is useful for getting the
- library waveHeader's midiSampNum, loopType, and instrumType if you wish to
- use/store this data somewhere. See the section "CONVERTING WAVE DATA".
- Your vectors are passed the lib's SAMPInfo and waveHeader, the current
- SampleHeader64 address (a pointer to a SampleHeader64), and waveNumber
- (minus offsetWave).
- They should return an abort flag (1 = Abort read, 0 = continue). For
- example, the library calls your FATK routine as so:
-
- flag = FATKroutine( waveNumber, SampleHeader, SAMPInfo, waveHeader );
- d0 d5 a3 a4 a5
-
- waveNumber ULONG, wave of interest.
- SampleHeader Pointer to library's SampleHeader64 structure.
- SAMPInfo Pointer to library's SAMPInfo structure.
- waveHeader Pointer to library's waveHeader structure.
-
- flag ULONG, return value.
-
- When reading a SAMP, you should either read or seek past any data from
- within an ATAK, RLSE, FATK, FRLS, or USER vector. When the library calls your
- ATAK, RLSE, FATK, FRLS, or USER vector, the DOS file position will be at the
- expected data within the SAMP file. In other words, when the library calls
- your FATK vector, the file position will be at the wave's FATK data (if there
- is any). When the library calls your USER vector, the file position will be
- at the wave's USER data (if any). You can find your precise position and the
- type of USER data via the waveHeader structure. Your vector must either read
- exactly this many bytes of data, or Seek() forward this many bytes from the
- current position. In other words, when your vector returns, the new file
- position must be at the next byte AFTER the expected data. If you Seek()
- somewhere else in the file, always Seek() back to the point after the
- expected data (before your vector returns).
-
- By default, the library loads the sample data into MEMF_CHIP, but you can
- change this before calling ReadWaves() by storing the desired AllocMem()
- attributes in the lib's SAMPinfo MemType field.
-
-
- *************************** LoadPlayMap ********************************
- Checks each byte of the loaded PlayMap. For every wave number above or below
- the wave range (offsetWave+1 to offsetWave+totalWaves) in the loaded PlayMap,
- the application's destination PlayMap byte is left as is. Otherwise, the wave
- number is set to
-
- (SAMPInfo's NumOfWaves - offsetWave) + startWave
-
- where startWave is the number of the SampleHeader where the first wave
- was loaded in. (startWave and offsetWave both referenced from wave #0)
- numOfChans is the # of channels for each midi note in the destination playMap.
- LoadPlaymap simply zeros out the destination playMap first (i.e. sets all
- bytes to NO WAVE) before loading the new playMap. The difference is that
- for every byte that is not = NO WAVE in the loaded playmap, MixPlayMap
- overwrites the respective destination playmap byte. This is useful for
- combining several SAMP files into one by loading each file into different
- SampleHeader64 structures, and "mixing" each loaded playmap. LoadPlaymap
- makes the destination playmap an exact copy of the loaded playmap. This is
- useful for an application that loads only one samp file.
- If totalWaves = 0, LoadPlaymap just zeros out the playMap and MixPlaymap
- does nothing. In this case, offsetWave and startWave are ignored. In this
- context LoadPlaymap can be used to initialize ("empty") a playmap.
-
-
- MixPlayMap( totalWaves, numOfChans, offsetWave, startWave, destPlayMap);
- d0 d1 d6 d7 a0
-
- totalWaves ULONG, total number of waves read in.
- numOfChans ULONG, number of play channels.
- offsetWave ULONG, wave offset position.
- startWave ULONG, number of first wave read in.
- destPlayMap Pointer to UBYTE array, a playMap.
-
- *************************** MakeTransTable ***************************
- Makes a TransposeNode for the passed sample period. The transpose table
- will have the specified # of steps above and below the ORIGINAL_PITCH as
- described by the upperRange and lowerRange values. This routine will
- allocate and link the TransposeNode into the passed TList only if there
- is not already a table for this sampleRate. Otherwise, returns ORIGPITCH
- of the other table in order to avoid duplication. Returns a zero if not
- enough mem to create a new table, or the passed sampleRate = 0.
- TList holds the address of (is a handle to) the first TransposeNode.
-
- If using the Amiga hardware, you may set the library's SAMPInfo's LowLimit
- and HighLimit fields before calling this. Defaults are 500 and 127 respec-
- tively. These are the limits between which the period values must range within
- the Transpose table. If a period is outside these limits, then the Transpose
- table entry is set to zero to indicate that the period is out of range. When
- playing back the wave, it is then easy to determine if a certain transposition
- of a wave's sample Rate results in a period out of range. The default limits
- are set for normal DMA audio and should not be altered unless your program
- does non-DMA audio output.
-
- Note that this function only supports a Transpose table of +12 to -12 steps
- from the root. All further steps will result in TransposeTable entries of 0.
-
- ORIGPITCHaddr = MakeTransTable( samplePeriod, upperRange, lowerRange, &TList );
- d0 d5 d6 d7 a2
-
-
- samplePeriod ULONG, sample period in nSec.
- upperRange ULONG, number of entries above original pitch.
- lowerRange ULONG, number of entries below original pitch.
- &TList Pointer to a pointer to a TransposeNode ( a handle ).
-
- ORIGPITCH Pointer to a ULONG, this is the middle of a ULONG array.
- The array extends outward from this address by the upperRange
- and lowerRange values.
-
- If you are not using the Amiga's audio hardware, you will probably want to
- calculate the periods differently than MakeTransTable. This function figures
- in the Amiga fudge factor (.279365), a hardware limitation. Hopefully, your
- hardware will be MUCH nicer than the primitive Amiga audio system, and so a
- second function is provided:
-
- ORIGPITCHaddr = CusMakeTransTable( sampleRate, upperRange, lowerRange, Vector, &TList );
- d0 d5 d6 d7 a1 a2
-
- This routine has an extra parameter; a pointer to a vector which will be
- called for each "step" of the transpose table, starting with the lowest step.
- This routine is passed the sample period in nanoseconds and the step offset
- from the original pitch address of the table. It should return the new trans-
- pose table entry for that step.
-
-
- entry = Vector( period, stepOffset );
-
- For example, if you asked for 6 steps lowerRange with sampleRate = 18000, the
- first call to your vector is passed period = 55556 and step = -6*2 (Multiplied
- by 2 because each entry in transpose table is a USHORT). If you were making
- a transpose table for a western tempered scale, you could calculate
-
- period/.707106781
-
- for the new period in nanoseconds. (.707106781 because we are transposing down
- 6 steps. See SAMP doc.) Actually, since the transpose table expects back a
- USHORT, you might choose to return the period in MICROSECONDS. Excepting a
- little round-off error, we can use integer division:
-
- period/707 (in microseconds)
-
- This assumes that your hardware wants the period in microseconds (like the
- Amiga hardware). You should return a zero for a period that is out of range.
- In this way, your player program can understand that a TransposeTable entry
- of 0 means that the hardware cannot play the wave back at the required speed.
-
- With your own vector, there is no limit to the number of steps above or below
- the root note. That will be determined by your application and hardware.
-
-
- **************************** RemoveTTable() ***************************
- Removes the TransposeNode (and its Table) for the passed sampleHeader64
- structure from the passed TList if there are no other waves using the Table.
- If the passed ptr to ORIGINAL_PITCH is NULL, this function does nothing.
-
- RemoveTable( sampleHeader64, TList );
- a0 a1
-
- sampleHeader64 Pointer to a sampleHeader64 structure.
- TList Pointer to a pointer to a TransposeNode ( a handle ).
-
- NOTE: Because we only have a pointer to the ORIGINAL_PITCH in our sample-
- Header64 structure and the TransposeTable can be any size (i.e. we don't
- really know the address of the TransposeNode), we need to locate the prepended
- TransposeNode by inspection. We do this by searching the TList until we find
- a Node whose tn_Orig field matches our sampleHeader64's ORIGINAL_PITCH. Then
- we know we have the right Node. Before we deAlloc, we need to check if any
- other waves are also using this table (one table can be used for many waves)
- by checking the tn_Hosts field. This field counts how many waves have been
- given this table from MakeTransTable().
-
-
- **************************** FreeTTables() *****************************
- Frees all of the TransposeTables in the passed TList. TList is a handle to
- the first TransposeNode in the list.
-
- FreeTTables( TList );
- a1
-
- TList Pointer to a pointer to a TransposeNode ( a handle ).
-
- ;*************************** FindTNode() *******************************
- Finds the TransposeNode address given the ptr to the TransposeTable list
- and the ORIGINAL_PITCH address of the table whose node address you want.
- Returns zero if no matching Node found. (Z-flag set accordingly)
- If passed an ORIGINAL_PITCH address of NULL, this function returns 0.
-
- TransposeNode = FindTNode( ORIGPITCHaddr, TList );
- d0 d0 a1
-
- TList Pointer to a pointer to a TransposeNode ( a handle ).
-
- ***************************** OpenSampWrite ***************************
- Opens the SAMP filename for writing. Must be called before using WriteMHDR,
- WriteName, WriteChunk, or WriteWaves. Returns the address of the library's
- SAMPInfo if success, or a zero if the file couldn't be created. Upon
- successful return, application should set SAMPInfo's Format, PlayMode,
- NumWaves, and NumOfChans. The defaults for these are 8 bit, INDEPENDENT,
- 0 waves, and 4 channels. z-flag cleared for error.
-
- SAMPInfo = OpenSampWrite( fileName );
- d0 d1
-
- fileName Pointer to UBYTE, DOS filename.
-
- SAMPInfo Pointer to a SAMPInfo structure.
-
-
- ******************************* WriteMHDR ******************************
- Writes out the SAMP and MHDR with SAMP header fileSize = 14+sizeOfPlayMap.
- Adjusts your PlayMap bytes so that all wave numbers < startWave and > =
- startWave+numWaves are set to 0. startWave is from 0 being the first wave.
- Returns a 1 if success, 0 if an error.
-
- result = WriteMHDR( startWave, playMap );
- d0 d0 a0
-
- startWave ULONG, wave number at which to start.
- playMap Pointer to a UBYTE array, a playMap.
-
- result BOOL, success / failure code.
-
- You can save a file without playMaps by setting the NumOfChans field in the
- SAMPInfo structure to 0, and then passing in 0 for the playMap address.
- ( ie, the SAMPInfo you got from OpenSampWrite() )
-
- ******************************* WriteSampChunk ***************************
- Writes out the passed ID, size (of data, not including header), and data.
- Returns a 1 if success, 0 if an error.
-
- result = WriteSampChunk( ID, size, data );
- d0 d0 d1 a0
-
- ID ULONG, a standard IFF-type ID ( ie, like 'ILBM' - but don't
- use this one :-)
- size ULONG, number of bytes.
- data Pointer to UBYTE of data to be saved.
-
- result BOOL, success / failure code.
-
-
- ****************************** WriteSampData ******************************
- Writes out the data for the passed number of bytes and the passed data ptr.
- This is commonly used by vector routines writing out FATK, FRLS, and USER
- data when saving a wave. Returns a 1 if success, 0 if an error.
-
- result = WriteSampData( numOfBytes, dataPtr );
- d0 d3 a0
-
- numOfBytes ULONG, number of bytes.
- dataPtr Pointer to UBYTE of data to be saved.
-
- result BOOL, success / failure code.
-
- ****************************** WriteNames ********************************
- Writes the NAME chunk. Uses SAMPInfo's NumWaves to determine how many wave
- names to write. Passed the base of the first string buffer. Passed the size
- of a string buffer. Ignores trailing spaces on each name.
- Returns a 1 if success, 0 if an error.
-
- result = WriteNames( bufsize, bufPtr );
- d0 d0 a0
-
- bufsize ULONG, number of bytes.
- bufPtr Pointer to UBYTE of data to be saved.
-
- result BOOL, success / failure code.
-
- ******************************* WriteWaves *****************************
-
- result = WriteWaves( offsetWave, totalWaves, SampleHeader64[0], TList )
- d0 d0 d1 a0 a1
-
- offsetWave ULONG, offset number.
- totalWaves ULONG, total number of waves to write.
- &SampleHeader64[] Pointer to a SampleHeader64 array.
- &TList Pointer to a pointer to a TransposeNode.
-
- result BOOL, success / failure code.
-
- Writes the specified range of waves between offsetWave and offsetWave +
- totalWaves to the SAMP file. offsetWave is the first wave to start saving
- (with the first SampleHeader64 being wave #0).
-
- offsetWave is specified from zero (i.e. a value of zero won't skip any
- SampleHeader64 structs. A 2 will skip the first 2 SampleHeader64s and start
- saving the 3rd SampleHeader64 as wave #0.) For totalWaves = 1, only 1 wave
- is saved.
-
- totalWaves is the number of waves to save. If totalWaves = 0, it returns 1
- and writes an "empty" BODY chunk.
-
- TList holds the address of the first TransposeNode. (a C handle)
-
- As a side note, if you are not using Transpose Tables you may pass 0
- for the TList handle, BUT in order to do this, you MUST also set the
- TransTable field of the passed SampleHeader64 structure(s) to 0.
-
- Before calling WriteWaves(), you should set the SAMPInfo's ATAKvector,
- RLSEvector, FATKvector, FRLSvector, USERvector, and EXTRAvector to point to
- any routines you want the library to call per wave. If you don't, the default
- is for the library to write no FATK, FRLS, and USER data, and to write ATAK
- and RLSE EGPoints based upon the SampleHeader64's envelope fields.
-
- WriteWaves() calls your EXTRAvector BEFORE the each wave's 80 byte waveHeader
- and data is written out. This vector is useful for setting the library
- waveHeader's SampNum, LoopType, and InsType per wave.
-
- Calls ATAK, RLSE, FATK, FRLS vectors to write out Amplifier/Filter EGPoints,
- and USERvector to write User Data.
-
- The vectors are passed the lib's SAMPInfo and waveHeader, and the current
- SampleHeader. The vectors should return an abort flag (1 = Abort write, 0 =
- continue). For example, the library calls your FATK routine as so:
-
- flag = FATKroutine( SampleHeader, SAMPinfo, waveHeader );
- d0 a3 a4 a5
-
- SampleHeader Pointer to a SampleHeader64 structure ( about to be saved ).
- SAMPInfo Pointer to a SAMPInfo structure ( about to be saved ).
- waveHeader Pointer to a waveHeader structure ( about to be saved ).
-
- flag ULONG, success / failure code.
-
- You must set the waveHeader's size fields to the number of bytes in the
- data written out. For example, if your USER vector writes out 40 bytes of
- data, set the waveHeader's USERsize to 40. (You should also set the
- USERtype).
-
- NOTE: In order to write out a SAMP file without a playMap, simply set
- NumOfChans in the MHDR chunk to zero ( see WriteMHDR() ). You may then pass
- WriteWaves 0's for the TList and SampleHeader64. It is imperative that you
- set all required fields in the waveHeader structure ( via the EXTRAVector )!
- This includes WaveSize, Period, Rate, and the three Loop fields.
-
-
- ************************** SAMPErrorMsg ****************************
-
- When passed the error number (as returned by OpenSampRead for example),
- this returns the address of a NULL-terminated string describing the error.
- This is suitable for informing the user of any possible errors. For asm
- programmer's certain lib routines return a error number in d1. For C pro-
- grammer's, the error is stored in a variable called SAMPError.
-
- string = SAMPErrorMsg( SAMPError );
- d0 d1
-
- SAMPError ULONG, internal error code.
-
- string Pointer to UBYTE, a corresponding error code message.
-
-
- «««««««««««««« PROCESSING UNKNOWN CHUNKS »»»»»»»»»»»»
-
- When your UnknownChunk vector is called by OpenSampRead, it passes a
- SeekOffset. This value is the number of bytes from the beginning of the file
- to this chunk's ID, and can be used by your application to Seek() to this chunk
- later. Your vector should store the chunk ID and SeekOffset for later process-
- ing after OpenSampRead returns. Do not do any Seek() or Read() from within
- this vector!!! Always wait until you return from OpenSampRead() before you
- access the chunk. The idea is to Seek() from the beginning of file to the
- chunk and process it, perhaps before or after you ReadWaves(), ReadNames(),
- LoadPlaymap(), MixPlaymap(), and certainly before you CloseSamp(). The DOS
- fileHandle can be found in the library SAMPInfo's Handle field.
- Note that the ChunkSize passed to your vector does not count the standard, 8
- byte IFF chunkID and chunkSize fields with which all IFF chunks must start.
-
-
- «««««««««««««« READING AUTH, ANNO, etc. CHUNKS »»»»»»»»»»»»
-
- In order to grab the data held in the other known chunks ( AUTH, ANNO, (C) ),
- you may obtain the FileHandle for the file via the SAMPInfo structure before
- calling CloseSamp(). Seek values for each of the known chunks are also found
- in this structure. The general idea is to Seek() to the beginning of the
- file, and then Seek() to the desired segment. This will place you at the
- start of the chunk, and you may then determine the chunk size by reading the
- first 8 bytes (the 2nd ULONG is the chunk size). After reading this, you may
- read the actual chunk data, and do with it as you will.
-