home *** CD-ROM | disk | FTP | other *** search
-
- /*
- **
- ** $VER: dispatch.c 1.2 (9.11.97)
- ** 16sv.datatype 1.2
- **
- ** Dispatch routine for a DataTypes class
- **
- ** Written 1996/97 by Roland 'Gizzy' Mainz
- ** Original example source from David N. Junod
- **
- */
-
- /* main includes */
- #include "classbase.h"
- #include "classdata.h"
-
- /*****************************************************************************/
-
- /* local prototypes */
- static LONG Load16SV( struct ClassBase *, Object * );
- static LONG Load16SVBody( SAMPLE8 *, UBYTE *, ULONG );
-
- #ifndef NO_ENCODER
- static ULONG SaveIFF16SV( struct ClassBase *, Object *, struct dtWrite * );
-
- static struct IFFHandle *CreateDOSIFFHandle( struct ClassBase *, BPTR );
-
- static LONG PutIFFObjectInfo( struct ClassBase *, struct IFFHandle *, STRPTR, STRPTR, STRPTR, STRPTR, STRPTR );
- static LONG PutIFFString( struct ClassBase *, struct IFFHandle *, ULONG, STRPTR );
-
- static LONG Put16SVBODY( struct ClassBase *, struct IFFHandle *, SAMPLE8 *, ULONG );
- #endif /* NO_ENCODER */
-
-
-
- /*****************************************************************************/
-
- /* Create "16sv.datatype" BOOPSI class */
- struct IClass *initClass( struct ClassBase *cb )
- {
- struct IClass *cl;
-
- /* Create our class... */
- if( cl = MakeClass( IFF16SVDTCLASS, SOUNDDTCLASS, NULL, 0UL, 0UL ) )
- {
- #define DTSTACKSIZE (16384UL)
- cl -> cl_Dispatcher . h_Entry = (HOOKFUNC)StackSwapDispatch; /* see stackswap.c */
- cl -> cl_Dispatcher . h_SubEntry = (HOOKFUNC)Dispatch; /* see stackswap.c */
- cl -> cl_Dispatcher . h_Data = (APTR)DTSTACKSIZE; /* see stackswap.c */
- cl -> cl_UserData = (ULONG)cb; /* class library base as expected by datatypes.library */
-
- AddClass( cl );
- }
-
- return( cl );
- }
-
- /*****************************************************************************/
-
- /* IFF errors to DOS errors */
- static
- const
- LONG ifferr2doserr[] =
- {
- 0L, /* End of file (not an error). */
- 0L, /* End of context (not an error). */
- DTERROR_INVALID_DATA, /* No lexical scope. */
- ERROR_NO_FREE_STORE, /* Insufficient memory. */
- ERROR_SEEK_ERROR, /* Stream read error. */
- ERROR_SEEK_ERROR, /* Stream write error. */
- ERROR_SEEK_ERROR, /* Stream seek error. */
- DTERROR_INVALID_DATA, /* File is corrupt. */
- DTERROR_INVALID_DATA, /* IFF syntax error. */
- ERROR_OBJECT_WRONG_TYPE, /* Not an IFF file. */
- ERROR_REQUIRED_ARG_MISSING, /* Required call-back hook missing. */
- 0xDEADDEAD /* Return to client. You should never see this ! */
- };
-
- /*****************************************************************************/
-
-
- /* class dispatcher */
- DISPATCHERFLAGS
- ULONG Dispatch( REGA0 struct IClass *cl, REGA2 Object *o, REGA1 Msg msg )
- {
- struct ClassBase *cb = (struct ClassBase *)(cl -> cl_UserData);
- ULONG retval = 0UL;
-
- switch( msg -> MethodID )
- {
- /****** 16sv.datatype/OM_NEW *************************************************
- *
- * NAME
- * OM_NEW -- Create a 16sv.datatype object.
- *
- * FUNCTION
- * The OM_NEW method is used to create an instance of the 16sv.datatype
- * class. This method is passed to the superclass first. After this,
- * 16sv.datatype parses the file and loads the sample.
- *
- * ATTRIBUTES
- * The following attributes can be specified at creation time.
- *
- * DTA_SourceType (ULONG) -- Determinates the type of DTA_Handle
- * attribute. DTST_FILE, DTST_CLIPBOARD and DTST_RAM are supported.
- * If any other type was set in a given DTA_SourceType,
- * OM_NEW will be rejected.
- * Defaults to DTST_FILE.
- *
- * DTA_Handle -- For both supported DTST_FILE and DTST_CLIPBOARD, a
- * (struct IFFHandle *) is expected.
- * (DTST_FILE expects a IFF Stream handle because this is a IFF
- * type DataType (DTF_IFF)).
- * A DTST_RAM (create empty object) source type requires a NULL
- * handle.
- *
- * NOTE
- * If the datatype was compiled with the NO_ENCODER flag set,
- * DTA_SourceType == DTST_RAM causes OM_NEW to reject the method.
- *
- * RESULT
- * If the object was created a pointer to the object is returned,
- * otherwise NULL is returned.
- *
- ******************************************************************************
- *
- */
- case OM_NEW:
- {
- struct TagItem *ti;
-
- /* We only support DTST_FILE, DTST_CLIPBOARD or DTST_RAM as source type */
- if( ti = FindTagItem( DTA_SourceType, (((struct opSet *)msg) -> ops_AttrList) ) )
- {
- if( ((ti -> ti_Data) != DTST_FILE) &&
- ((ti -> ti_Data) != DTST_CLIPBOARD)
- #ifndef NO_ENCODER
- && ((ti -> ti_Data) != DTST_RAM)
- #endif /* !NO_ENCODER */
-
- )
- {
- SetIoErr( ERROR_OBJECT_WRONG_TYPE );
-
- break;
- }
- }
-
- /* This must not be a subclass of 16sv.datatype
- * (not implemented yet)
- */
- if( o == (Object *)cl )
- {
- if( retval = DoSuperMethodA( cl, o, msg ) )
- {
- LONG error;
-
- /* Load sample... */
- if( error = Load16SV( cb, (Object *)retval ) )
- {
- /* Something went fatally wrong, dispose object */
- CoerceMethod( cl, (Object *)retval, OM_DISPOSE );
- retval = 0UL;
- }
-
- SetIoErr( error );
- }
- }
- else
- {
- /* Subclasses of 16sv.datatype are not implemented */
- SetIoErr( ERROR_NOT_IMPLEMENTED );
- }
- }
- break;
-
- case OM_UPDATE:
- {
- if( DoMethod( o, ICM_CHECKLOOP ) )
- {
- break;
- }
- }
- case OM_SET:
- {
- /* Pass the attributes to the sound class and force a refresh if we need it */
- if( retval = DoSuperMethodA( cl, o, msg ) )
- {
- /* The following check statement isn't needed because OM_NEW does not allow subclasses of 16sv.datatype,
- * therefore, we're always the top instance...
- */
- #ifdef COMMENTED_OUT
- /* Top instance ? */
- if( OCLASS( o ) == cl )
- #endif /* COMMENTED_OUT */
- {
- struct RastPort *rp;
-
- /* Get a pointer to the rastport */
- if( rp = ObtainGIRPort( (((struct opSet *)msg) -> ops_GInfo) ) )
- {
- struct gpRender gpr;
-
- /* Force a redraw */
- gpr . MethodID = GM_RENDER;
- gpr . gpr_GInfo = ((struct opSet *)msg) -> ops_GInfo;
- gpr . gpr_RPort = rp;
- gpr . gpr_Redraw = GREDRAW_UPDATE;
-
- DoMethodA( o, (Msg)(&gpr) );
-
- /* Release the temporary rastport */
- ReleaseGIRPort( rp );
-
- retval = 0UL;
- }
- }
- }
- }
- break;
-
- /****** 16sv.datatype/DTM_WRITE **********************************************
- *
- * NAME
- * DTM_WRITE -- Save data
- *
- * FUNCTION
- * This method saves the object's contents to disk.
- *
- * If dtw_Mode is DTWM_IFF, the method is passed unchanged to the
- * superclass, sound.datatype, which writes an IFF 8SVX sample.
- *
- * If dtw_mode is DTWM_RAW, the object writes an IFF 16SV sample to
- * the filehandle given.
- * (If the class library was compiled with the NO_ENCODER switch
- * (not the default), result == 0 and resul2 == ERROR_NOT_IMPLEMENTED
- * are returned).
- *
- * BUGS
- * - The encoder does not support compression. A request to save
- * compressed data returns DTERROR_UNKNOWN_COMPRESSION.
- *
- * TAGS
- * None defined.
- *
- * RESULT
- * Returns 0 for failure (IoErr() returns result2), non-zero
- * for success.
- *
- ******************************************************************************
- *
- */
- case DTM_WRITE:
- {
- struct dtWrite *dtw;
-
- dtw = (struct dtWrite *)msg;
-
- /* Local data format requested ? */
- if( (dtw -> dtw_Mode) == DTWM_RAW )
- {
- /* Enable the followng code if you don't have an encoder implemented... */
- #ifdef NO_ENCODER
- SetIoErr( ERROR_NOT_IMPLEMENTED );
- retval = 0UL;
- #else
- retval = SaveIFF16SV( cb, o, dtw );
- #endif /* NO_ENCODER */
- }
- else
- {
- /* Pass msg to superclass (which writes an IFF 8SVX sample)... */
- retval = DoSuperMethodA( cl, o, msg );
- }
- }
- break;
-
- /* Let the superclass handle everything else */
- default:
- {
- retval = DoSuperMethodA( cl, o, msg );
- }
- break;
- }
-
- return( retval );
- }
-
-
- static
- LONG Load16SV( struct ClassBase *cb, Object *o )
- {
- LONG error = 0L;
- APTR fh; /* IFF stream handle */
- ULONG sourcetype; /* type of stream (either DTST_FILE, DTST_CLIPBOARD or DTST_RAM */
- struct VoiceHeader *vh; /* obj's voice header */
-
- /* Get file handle, handle type and VoiceHeader */
- if( GetDTAttrs( o, DTA_SourceType, (&sourcetype),
- DTA_Handle, (&fh),
- SDTA_VoiceHeader, (&vh),
- TAG_DONE ) == 3UL )
- {
- struct IFFHandle *iff = NULL;
-
- switch( sourcetype )
- {
- case DTST_CLIPBOARD:
- case DTST_FILE:
- {
- /* This is an IFF DataType, datatypesclass provides an IFFHandle for us.
- * (See datatypesclass autdocs for details !)
- */
- iff = (struct IFFHandle *)fh;
- }
- break;
-
- #ifndef NO_ENCODER
- case DTST_RAM:
- {
- /* Do nothing... */
- }
- break;
- #endif /* !NO_ENCODER */
-
- default:
- {
- /* unsupported source type */
- error = ERROR_NOT_IMPLEMENTED;
- }
- break;
- }
-
- /* Any error ? */
- if( error == 0L )
- {
- /* Any handle to proccess ? */
- if( iff )
- {
- SAMPLE8 *sample = NULL; /* resulting sample (e.g. SDTA_Sample) */
- ULONG samplelength = 0UL; /* resulting sample length (e.g. SDTA_SampleLength) */
-
- struct StoredProperty *vhdrprop = NULL, /* 16SV VHDR (struct VoiceHeader) */
- *bodyprop = NULL, /* 16SV BODY */
- *annoprop = NULL, /* Generic IFF ANNO (annotation) chunk */
- *authprop = NULL, /* Generic IFF AUTH (author) chunk */
- *copyrightprop = NULL, /* Generic IFF (C) (copyright) chunk */
- *fverprop = NULL, /* Generic IFF FVER (version) chunk */
- *nameprop = NULL; /* Generic IFF NAME (name) chunk */
-
- #define NUM_PROPCHUNKS (7L)
- const
- LONG propchunks[ (NUM_PROPCHUNKS * 2) ] =
- {
- ID_16SV, ID_VHDR,
- ID_16SV, ID_BODY,
- ID_16SV, ID_ANNO,
- ID_16SV, ID_AUTH,
- ID_16SV, ID_Copyright,
- ID_16SV, ID_FVER,
- ID_16SV, ID_NAME
- };
-
- if( !(error = PropChunks( iff, (LONG *)propchunks, NUM_PROPCHUNKS )) )
- {
- /* Scan IFF stream until an error or an EOF occurs */
- for( ;; )
- {
- if( error = ParseIFF( iff, IFFPARSE_STEP ) )
- {
- /* EOF (End Of File) is no error here... */
- if( error == IFFERR_EOF )
- {
- error = 0L;
- break;
- }
-
- /* vhdr header loaded ? */
- if( vhdrprop == NULL )
- {
- if( vhdrprop = FindProp( iff, ID_16SV, ID_VHDR ) )
- {
- *vh = *((struct VoiceHeader *)(vhdrprop -> sp_Data));
-
- /* BODY data compression is currently not implemented yet... */
- if( (vh -> vh_Compression) != CMP_NONE )
- {
- error = DTERROR_UNKNOWN_COMPRESSION;
- }
- }
- }
-
- /* annotation loaded ? */
- if( annoprop == NULL )
- {
- /* IFF ANNO found ? */
- if( annoprop = FindProp( iff, ID_16SV, ID_ANNO ) )
- {
- STRPTR buff;
-
- /* Allocate a temp buffer so that stccpy can add a '\0'-terminator */
- if( buff = (STRPTR)AllocVec( ((annoprop -> sp_Size) + 2UL), MEMF_ANY ) )
- {
- stccpy( buff, (annoprop -> sp_Data), (int)(annoprop -> sp_Size) );
-
- SetDTAttrs( o, NULL, NULL, DTA_ObjAnnotation, buff, TAG_DONE );
-
- FreeVec( buff );
- }
- else
- {
- /* no temp. buffer */
- error = ERROR_NO_FREE_STORE;
- }
- }
- }
-
- /* autor loaded ? */
- if( authprop == NULL )
- {
- /* IFF AUTH found ? */
- if( authprop = FindProp( iff, ID_16SV, ID_AUTH ) )
- {
- STRPTR buff;
-
- /* Allocate a temp buffer so that stccpy can add a '\0'-terminator */
- if( buff = (STRPTR)AllocVec( ((authprop -> sp_Size) + 2UL), MEMF_ANY ) )
- {
- stccpy( buff, (authprop -> sp_Data), (int)(authprop -> sp_Size) );
-
- SetDTAttrs( o, NULL, NULL, DTA_ObjAuthor, buff, TAG_DONE );
-
- FreeVec( buff );
- }
- else
- {
- /* no temp. buffer */
- error = ERROR_NO_FREE_STORE;
- }
- }
- }
-
- /* copyright loaded ? */
- if( copyrightprop == NULL )
- {
- /* IFF (C) found ? */
- if( copyrightprop = FindProp( iff, ID_16SV, ID_Copyright ) )
- {
- STRPTR buff;
-
- /* Allocate a temp buffer so that stccpy can add a '\0'-terminator */
- if( buff = (STRPTR)AllocVec( ((copyrightprop -> sp_Size) + 2UL), MEMF_ANY ) )
- {
- stccpy( buff, (copyrightprop -> sp_Data), (int)(copyrightprop -> sp_Size) );
-
- SetDTAttrs( o, NULL, NULL, DTA_ObjCopyright, buff, TAG_DONE );
-
- FreeVec( buff );
- }
- else
- {
- /* no temp. buffer */
- error = ERROR_NO_FREE_STORE;
- }
- }
- }
-
- /* file version loaded ? */
- if( fverprop == NULL )
- {
- /* IFF FVER found ? */
- if( fverprop = FindProp( iff, ID_16SV, ID_FVER ) )
- {
- STRPTR buff;
-
- /* Allocate a temp buffer so that stccpy can add a '\0'-terminator */
- if( buff = (STRPTR)AllocVec( ((fverprop -> sp_Size) + 2UL), MEMF_ANY ) )
- {
- stccpy( buff, (fverprop -> sp_Data), (int)(fverprop -> sp_Size) );
-
- SetDTAttrs( o, NULL, NULL, DTA_ObjVersion, buff, TAG_DONE );
-
- FreeVec( buff );
- }
- else
- {
- /* no temp. buffer */
- error = ERROR_NO_FREE_STORE;
- }
- }
- }
-
- /* name loaded ? */
- if( nameprop == NULL )
- {
- /* IFF NAME found ? */
- if( nameprop = FindProp( iff, ID_16SV, ID_NAME ) )
- {
- STRPTR buff;
-
- /* Allocate a temp buffer so that stccpy can add a '\0'-terminator */
- if( buff = (STRPTR)AllocVec( ((nameprop -> sp_Size) + 2UL), MEMF_ANY ) )
- {
- stccpy( buff, (nameprop -> sp_Data), (int)(nameprop -> sp_Size) );
-
- SetDTAttrs( o, NULL, NULL, DTA_ObjName, buff, TAG_DONE );
-
- FreeVec( buff );
- }
- else
- {
- /* no temp. buffer */
- error = ERROR_NO_FREE_STORE;
- }
- }
- }
-
- /* body loaded ? */
- if( bodyprop == NULL )
- {
- if( bodyprop = FindProp( iff, ID_16SV, ID_BODY ) )
- {
- if( vhdrprop )
- {
- /* 8 bit sample data needs half of the size of 16 bit samples */
- samplelength = ((bodyprop -> sp_Size) / (sizeof( SAMPLE16 ) / sizeof( SAMPLE8 )));
-
- if( sample = (SAMPLE8 *)AllocVec( (samplelength + 16UL), (MEMF_PUBLIC | MEMF_CLEAR) ) )
- {
- error = Load16SVBody( sample, (bodyprop -> sp_Data), (bodyprop -> sp_Size) );
- }
- else
- {
- /* No sample */
- error = ERROR_NO_FREE_STORE;
- }
- }
- else
- {
- /* No VHDR chunk before BODY chunk */
- error = DTERROR_INVALID_DATA;
- }
- }
- }
-
- /* on error: leave for-loop */
- if( error )
- {
- if( error != IFFERR_EOC )
- {
- break;
- }
- }
- }
- }
- }
-
- /* voiceheader, body and all other required information available ? */
- if( ((vhdrprop == NULL) || (bodyprop == NULL) || (sample == NULL)) && (samplelength == 0UL) && (error == 0L) )
- {
- error = DTERROR_INVALID_DATA;
- }
-
- /* Any error ? */
- if( error == 0L )
- {
- if( vh -> vh_SamplesPerSec )
- {
- ULONG clock = ((SysBase -> ex_EClockFrequency) * 5UL),
- period;
- ULONG volume;
-
- /* Calc sample period */
- period = clock / (vh -> vh_SamplesPerSec);
-
- /* scale IFF 8SVX volume resolution (0 - VOLUME_UNITY) to sound.datatype resolution (0 - 63) */
- volume = ((vh -> vh_Volume) * 63UL) / VOLUME_UNITY;
-
- /* No name chunk ? */
- if( nameprop == NULL )
- {
- STRPTR name;
-
- GetDTAttrs( o, DTA_Name, (&name), TAG_DONE );
- SetDTAttrs( o, NULL, NULL, DTA_ObjName, name, TAG_DONE );
- }
-
- /* Set misc attributes
- * In fact, SDTA_Period and SDTA_Volume are calculated from SDTA_VoiceHeader info,
- * but we set it here EXPLICITLY that noone can say we didn't pass this to sound.datatype...
- */
- SetDTAttrs( o, NULL, NULL, SDTA_Sample, sample,
- SDTA_SampleLength, samplelength,
- SDTA_Period, period,
- SDTA_Volume, volume,
- TAG_DONE );
-
- /* sound.datatype now owns the sample data and will FreeVec then at OM_DISPOSE time... */
- sample = NULL;
- }
- else
- {
- /* we need a valid sps value here */
- error = DTERROR_INVALID_DATA;
- }
- }
-
- /* If the sample data were not used by sound.datatype (e.g. eaten up), free them here */
- if( sample )
- {
- FreeVec( sample );
- }
- }
- else
- {
- /* No iff handle ? - Be sure we got a DTST_RAM sourcetype */
- if( sourcetype != DTST_RAM )
- {
- /* No handle ! */
- error = ERROR_REQUIRED_ARG_MISSING;
- }
- }
- }
- }
- else
- {
- /* can't get required attributes from superclass */
- error = ERROR_OBJECT_WRONG_TYPE;
- }
-
- /* Error codes below 0 are related to the IFFParse.library functions */
- if( error < 0L )
- {
- /* convert IFFParse error to DOS error */
- error = ifferr2doserr[ (-error - 1) ];
- }
-
- return( error );
- }
-
-
- /* The IFF 16SV BODY loader */
- static
- LONG Load16SVBody( SAMPLE8 *sample8, UBYTE *buffer, ULONG buffersize )
- {
- LONG error = 0L;
- ULONG i;
- SAMPLE16 *sample16 = (SAMPLE16 *)buffer;
-
- buffersize /= (sizeof( SAMPLE16 ) / sizeof( SAMPLE8 ));
-
- for( i = 0UL ; i < buffersize ; i++ )
- {
- /* scale sample from 16 down to 8 bit resolution... */
- *sample8++ = ((ULONG)sample16[ i ] * SAMPLE8_MAX) / SAMPLE16_MAX;
- }
-
- return( error );
- }
-
-
- #ifndef NO_ENCODER
- /* The IFF 16SV encoder */
- static
- ULONG SaveIFF16SV( struct ClassBase *cb, Object *o, struct dtWrite *dtw )
- {
- ULONG retval = 0UL;
- LONG error = 0L;
-
- /* A NULL file handle is a nop (GMultiView uses this to test if a datatype supports RAW writing) */
- if( dtw -> dtw_FileHandle )
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *)(G( o ) -> SpecialInfo);
- STRPTR objname,
- objauthor,
- objannotation,
- objcopyright,
- objversion;
- struct VoiceHeader *vh;
- SAMPLE8 *sample;
- ULONG samplelength;
- ULONG volume;
- ULONG period;
-
- /* Lock data that noone could change it...
- * We use here a shared lock because we don't chaange any object data below
- * Theoretically, this allows that multiple savers acts on the same object :-)
- */
- ObtainSemaphoreShared( (&(si -> si_Lock)) );
-
- if( GetDTAttrs( o, DTA_ObjName, (&objname),
- DTA_ObjAuthor, (&objauthor),
- DTA_ObjAnnotation, (&objannotation),
- DTA_ObjCopyright, (&objcopyright),
- DTA_ObjVersion, (&objversion),
- SDTA_VoiceHeader, (&vh),
- SDTA_Sample, (&sample),
- SDTA_SampleLength, (&samplelength),
- SDTA_Volume, (&volume),
- SDTA_Period, (&period),
- TAG_DONE ) == 10UL )
- {
- if( sample && samplelength && period )
- {
- /* BODY data compression for IFF 16SV is currently not implemented */
- if( (vh -> vh_Compression) == CMP_NONE )
- {
- struct IFFHandle *iff;
- struct VoiceHeader vhdr;
-
- /* Fill voiceheader... */
- vhdr . vh_OneShotHiSamples = samplelength;
- vhdr . vh_RepeatHiSamples = 0UL;
- vhdr . vh_SamplesPerHiCycle = 0UL;
- vhdr . vh_SamplesPerSec = ((SysBase -> ex_EClockFrequency) * 5UL) / period;
- vhdr . vh_Octaves = 1UL;
- vhdr . vh_Compression = CMP_NONE;
- vhdr . vh_Volume = MAX( (((vh -> vh_Volume) * VOLUME_UNITY) / 64UL), VOLUME_UNITY );
-
- /* Create IFF handle based in the given file handle */
- if( iff = CreateDOSIFFHandle( cb, (dtw -> dtw_FileHandle) ) )
- {
- if( !(error = OpenIFF( iff, IFFF_WRITE )) )
- {
- for( ;; ) /* not a loop, used as a jump table */
- {
- if( error = PushChunk( iff, ID_16SV, ID_FORM, IFFSIZE_UNKNOWN ) )
- break;
-
- /* write VHDR (VoiceHeader) */
- {
- if( error = PushChunk( iff, 0UL, ID_VHDR, sizeof( struct VoiceHeader ) ) )
- break;
-
- if( (error = WriteChunkBytes( iff, (APTR)(&vhdr), sizeof( struct VoiceHeader ) )) != sizeof( struct VoiceHeader ) )
- {
- break;
- }
-
- if( error = PopChunk( iff ) )
- break;
- }
-
- /* write misc info (name, author, annotation etc.) */
- if( error = PutIFFObjectInfo( cb, iff, objname, objauthor, objannotation, objcopyright, objversion ) )
- break;
-
- /* Write 16SV BODY */
- if( error = Put16SVBODY( cb, iff, sample, samplelength ) )
- break;
-
- if( error = PopChunk( iff ) )
- break;
-
- break; /* end of jump table */
- }
-
- CloseIFF( iff );
- }
-
- /* No error == success */
- if( error == 0L )
- {
- retval = 1UL; /* success ! */
- }
-
- FreeIFF( iff );
- }
- else
- {
- /* Can't alloc iff handle */
- error = ERROR_NO_FREE_STORE;
- }
- }
- else
- {
- /* IFF 16SV does currectly not implement compresion */
- error = DTERROR_UNKNOWN_COMPRESSION;
- }
- }
- else
- {
- /* Some things are missing (e.g. no sample etc.)... */
- error = DTERROR_NOT_ENOUGH_DATA;
- }
- }
- else
- {
- /* Object does not support the attributes we need... */
- error = ERROR_OBJECT_WRONG_TYPE;
- }
-
- /* Release data */
- ReleaseSemaphore( (&(si -> si_Lock)) );
- }
-
- /* Error codes below 0 are related to the IFFParse.library functions */
- if( error < 0L )
- {
- /* convert IFFParse error to DOS error */
- error = ifferr2doserr[ (-error - 1) ];
- }
-
- /* Store Result2 */
- SetIoErr( error );
-
- return( retval );
- }
-
-
- /* Create IFF handle based on given file handle */
- static
- struct IFFHandle *CreateDOSIFFHandle( struct ClassBase *cb, BPTR fh )
- {
- struct IFFHandle *iff;
-
- if( iff = AllocIFF() )
- {
- iff -> iff_Stream = (ULONG)fh;
-
- InitIFFasDOS( iff );
- }
-
- return( iff );
- }
-
-
- /* Put IFF generic info chunks (NAME, AUTH, ANNO, (C), FVER etc. */
- static
- LONG PutIFFObjectInfo( struct ClassBase *cb, struct IFFHandle *iff, STRPTR objname, STRPTR objauthor, STRPTR objannotation, STRPTR objcopyright, STRPTR objversion )
- {
- LONG error;
-
- if( error = PutIFFString( cb, iff, ID_NAME, objname ) ) return( error );
- if( error = PutIFFString( cb, iff, ID_AUTH, objauthor ) ) return( error );
- if( error = PutIFFString( cb, iff, ID_ANNO, objannotation ) ) return( error );
- if( error = PutIFFString( cb, iff, ID_Copyright, objcopyright ) ) return( error );
- if( error = PutIFFString( cb, iff, ID_FVER, objversion ) ) return( error );
-
- return( 0L );
- }
-
-
- /* write an string into a chunk (like generic AUTH, ANNO etc. chunks) */
- static
- LONG PutIFFString( struct ClassBase *cb, struct IFFHandle *iff, ULONG id, STRPTR string )
- {
- LONG error = 0L;
-
- if( string )
- {
- ULONG len = (ULONG)(strlen( string ) + 1UL);
-
- if( error = PushChunk( iff, 0UL, id, len ) )
- return( error );
-
- if( (error = WriteChunkBytes( iff, (APTR)string, len )) != len )
- {
- return( error );
- }
-
- error = PopChunk( iff );
- }
-
- return( error );
- }
-
-
- /*****************************************************************************/
-
- /* Write 16SV BODY data */
- static
- LONG Put16SVBODY( struct ClassBase *cb, struct IFFHandle *iff, SAMPLE8 *sample, ULONG samplelength )
- {
- LONG error;
- ULONG i;
-
- /* Write out a BODY chunk header */
- if( error = PushChunk( iff, 0L, ID_BODY, (samplelength * 2L) ) )
- return( error );
-
- /* Write out the BODY contents */
- for( i = 0UL ; i < samplelength ; i++ )
- {
- SAMPLE16 sample16 = (LONG)sample[ i ] * 256L;
-
- if( (error = WriteChunkBytes( iff, (APTR)(&sample16), sizeof( SAMPLE16 ) )) != sizeof( SAMPLE16 ) )
- return( error );
- }
-
- /* Finish the chunk */
- error = PopChunk( iff );
-
- return( error );
- }
-
- #endif /* NO_ENCODER */
-
-
-
-
-
-