carolyn@cbmvax.cbm.UUCP (Carolyn Scheppner) (11/20/86)
======== IFF News ======== Carolyn Scheppner Amiga Technical Support In mid-September, we printed/duped a new batch of IFF docs and disks. The new batch is labeled "September 19, 1986". There were a few fixes and changes which I will describe for the benefit of those who have the April 30, 1986 release. In addition, I recently received some new material (SMUS.h, 8SVX.h, Read8svx.c) from EA. Listings of these new files are attached. FIXES/CHANGES INCORPORATED IN SEPT 30 DOCS/DISK =============================================== Document 1. Errata/Addenda from previous printing were incorporated. 2. New listing for SeeILBM. Disk 1. The source for the readpict.c module no longer "contains binary". The problem was a control character in a comment. (If you want to find it using Emacs, search for the word "via" in a comment line. I think the control character is in the word "handle" in the same line) 2. Revised source for SeeILBM. The revisions to SeeILBM were: - Polling eliminated. It now Waits for mouse activity. - Checking of window->MouseX and MouseY replaced with saving and checking of msg->MouseX and MouseY. This makes little difference to SeeILBM but is necessary when SeeILBM is used as a base for a program that can't handle its messages immediately. You want to know where the mouse was when the button was PRESSED, not where it is when you HANDLE the message. - Handling of ILBMFrames modified to use only one global frame. It should now work properly with LISTs and PROPs but I don't have any to try it out on. NEW INFORMATION SINCE SEPT 30 RELEASE ===================================== 1. EA just told me that they have defined two more SID values in SMUS: (SID value) (Next data byte) #define SID_Clef 135 0=treble,1=bass,2=alto,3=tenor #define SID_Tempo 136 beats per minute (0-255) These values are also defined in the attached SMUS.h header file. 2. I recently discovered that the IFF object modules on our distribution disk were compiled without disabling stack checking. This is fine if you're linking with LStartup.obj. However, if you plan to link with AStartup ... Amiga.lib, LC.lib, you'll have to first recompile the IFF modules using the -v flag on LC2. 3. I am expecting some new FORM and Chunk descriptions from several third-party developers. I'll let you know when I get them. Remember that ALL NEW IFF FORMS and Chunks should be registered with me. This will hopefully avoid name conflicts and unneccesary duplication of existing formats. Some suggestions when designing new FORMs and chunks - Read the docs carefully and see if an existing chunk, FORM, or CAT/LIST of FORMS will fill your needs - If you decide that you need a NEW form or chunk, call me first to find out if a suitable new one has been registered. - If you need to design a new form or chunk, follow the guidelines in the EA specs. Think ahead when designing a chunk. An IFF FORM or Chunk does not become a standard just because it's "IFF". Try to design something that will be useful to other applications and future applications of your own. If possible, discuss your form/chunk ideas with other programmers. A bulletin board is a good place to get ideas from programmers with a variety of interests. Try to include variables for pertinent features even if you are not supporting them in your current application. - Include a couple of pad variables in your chunk for future expansion. Make your chunks an even size if possible because some home-brew readers may choke on the required pad byte 0 after an odd-size chunk. - Remember to register the form/chunk with me. Do this as early as possible in your program development so that it will be possible to work in suggested modifications or additions. The information I need includes: - Your name, address, phone number - Name and description of your product, and information on any other commercial or public domain software that supports your form/chunks - Names of form/chunks and itemized description of their contents. (see IFF specs for examples) - Purposes of the form/chunks WHERE TO REGISTER FORMS/CHUNKS ============================== US MAIL Carolyn Scheppner Software Tech Support CBM 1200 Wilson Drive West Chester, PA 19380 PHONE 215-431-9180 UUCP ...{allegra,caip,ihnp4,seismo}!cbmvax!carolyn HOW TO ORDER IFF DOCS AND DISK ============================== The IFF specs and disk containing docs, source, Lattice object, and some executable examples is available for $20 from Kim Montgomery / Software Tech Support Commodore Business Machines 1200 Wilson Drive West Chester, PA. 19380 Make the check out to Commodore Business Machines, be sure to include your name and address, and ask for "IFF docs and disk". -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Carolyn Scheppner -- CBM >>Amiga Technical Support<< UUCP ...{allegra,caip,ihnp4,seismo}!cbmvax!carolyn PHONE 215-431-9180 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
carolyn@cbmvax.cbm.UUCP (Carolyn Scheppner) (11/20/86)
#ifndef SMUS_H #define SMUS_H /*----------------------------------------------------------------------* * SMUS.H Definitions for Simple MUSical score. 2/12/86 * * By Jerry Morrison and Steve Hayes, Electronic Arts. * This software is in the public domain. * * This version for the Commodore-Amiga computer. *----------------------------------------------------------------------*/ #ifndef COMPILER_H #include "iff/compiler.h" #endif #include "iff/iff.h" #define ID_SMUS MakeID('S', 'M', 'U', 'S') #define ID_SHDR MakeID('S', 'H', 'D', 'R') #define ID_NAME MakeID('N', 'A', 'M', 'E') #define ID_Copyright MakeID('(', 'c', ')', ' ') #define ID_AUTH MakeID('A', 'U', 'T', 'H') #define ID_ANNO MakeID('A', 'N', 'N', 'O') #define ID_INS1 MakeID('I', 'N', 'S', '1') #define ID_TRAK MakeID('T', 'R', 'A', 'K') /* ---------- SScoreHeader ---------------------------------------------*/ typedef struct { UWORD tempo; /* tempo, 128ths quarter note/minute */ UBYTE volume; /* playback volume 0 through 127 */ UBYTE ctTrack; /* count of tracks in the score */ } SScoreHeader; /* ---------- NAME -----------------------------------------------------*/ /* NAME chunk contains a CHAR[], the musical score's name. */ /* ---------- Copyright (c) --------------------------------------------*/ /* "(c) " chunk contains a CHAR[], the FORM's copyright notice. */ /* ---------- AUTH -----------------------------------------------------*/ /* AUTH chunk contains a CHAR[], the name of the score's author. */ /* ---------- ANNO -----------------------------------------------------*/ /* ANNO chunk contains a CHAR[], the author's text annotations. */ /* ---------- INS1 -----------------------------------------------------*/ /* Constants for the RefInstrument's "type" field. */ #define INS1_Name 0 /* just use the name; ignore data1, data2 */ #define INS1_MIDI 1 /* <data1, data2> = MIDI <channel, preset> */ typedef struct { UBYTE iRegister; /* set this instrument register number */ UBYTE type; /* instrument reference type (see above) */ UBYTE data1, data2; /* depends on the "type" field */ char name[60]; /* instrument name */ } RefInstrument; /* ---------- TRAK -----------------------------------------------------*/ /* TRAK chunk contains an SEvent[]. */ /* SEvent: Simple musical event. */ typedef struct { UBYTE sID; /* SEvent type code */ UBYTE data; /* sID-dependent data */ } SEvent; /* SEvent type codes "sID". */ #define SID_FirstNote 0 #define SID_LastNote 127 /* sIDs in the range SID_FirstNote through * SID_LastNote (sign bit = 0) are notes. The * sID is the MIDI tone number (pitch). */ #define SID_Rest 128 /* a rest; same data format as a note. */ #define SID_Instrument 129 /* set instrument number for this track. */ #define SID_TimeSig 130 /* set time signature for this track. */ #define SID_KeySig 131 /* set key signature for this track. */ #define SID_Dynamic 132 /* set volume for this track. */ #define SID_MIDI_Chnl 133 /* set MIDI channel number (sequencers) */ #define SID_MIDI_Preset 134 /* set MIDI preset number (sequencers) */ #define SID_Clef 135 /* inline clef change. * 0=Treble, 1=Bass, 2=Alto, 3=Tenor. */ #define SID_Tempo 136 /* Inline tempo change in beats per minute.*/ /* SID values 144 through 159: reserved for Instant Music SEvents. */ /* The remaining sID values up through 254: reserved for future * standardization. */ #define SID_Mark 255 /* SID reserved for an end-mark in RAM. */ /* ---------- SEvent FirstNote..LastNote or Rest -----------------------*/ typedef struct { unsigned tone :8, /* MIDI tone number 0 to 127; 128 = rest */ chord :1, /* 1 = a chorded note */ tieOut :1, /* 1 = tied to the next note or chord */ nTuplet :2, /* 0 = none, 1 = triplet, 2 = quintuplet, * 3 = septuplet */ dot :1, /* dotted note; multiply duration by 3/2 */ division :3; /* basic note duration is 2**-division: * 0 = whole note, 1 = half note, 2 = quarter * note, ... 7 = 128th note */ } SNote; /* Warning: An SNote is supposed to be a 16-bit entity. * Some C compilers will not pack bit fields into anything smaller * than an int. So avoid the actual use of this type unless you are certain * that the compiler packs it into a 16-bit word. */ /* You may get better object code by masking, ORing, and shifting using the * following definitions rather than the bit-packed fields, above. */ #define noteChord (1<<7) /* note is chorded to next note */ #define noteTieOut (1<<6) /* note/chord is tied to next note/chord */ #define noteNShift 4 /* shift count for nTuplet field */ #define noteN3 (1<<noteNShift) /* note is a triplet */ #define noteN5 (2<<noteNShift) /* note is a quintuplet */ #define noteN7 (3<<noteNShift) /* note is a septuplet */ #define noteNMask noteN7 /* bit mask for the nTuplet field */ #define noteDot (1<<3) /* note is dotted */ #define noteDShift 0 /* shift count for division field */ #define noteD1 (0<<noteDShift) /* whole note division */ #define noteD2 (1<<noteDShift) /* half note division */ #define noteD4 (2<<noteDShift) /* quarter note division */ #define noteD8 (3<<noteDShift) /* eighth note division */ #define noteD16 (4<<noteDShift) /* sixteenth note division */ #define noteD32 (5<<noteDShift) /* thirty-secondth note division */ #define noteD64 (6<<noteDShift) /* sixty-fourth note division */ #define noteD128 (7<<noteDShift) /* 1/128 note division */ #define noteDMask noteD128 /* bit mask for the division field */ #define noteDurMask 0x3F /* bit mask for all duration fields * division, nTuplet, dot */ /* Field access: */ #define IsChord(snote) (((UWORD)snote) & noteChord) #define IsTied(snote) (((UWORD)snote) & noteTieOut) #define NTuplet(snote) ((((UWORD)snote) & noteNMask) >> noteNShift) #define IsDot(snote) (((UWORD)snote) & noteDot) #define Division(snote) ((((UWORD)snote) & noteDMask) >> noteDShift) /* ---------- TimeSig SEvent -------------------------------------------*/ typedef struct { unsigned type :8, /* = SID_TimeSig */ timeNSig :5, /* time signature "numerator" timeNSig + 1 */ timeDSig :3; /* time signature "denominator" is * 2**timeDSig: 0 = whole note, 1 = half * note, 2 = quarter note, ... * 7 = 128th note */ } STimeSig; #define timeNMask 0xF8 /* bit mask for timeNSig field */ #define timeNShift 3 /* shift count for timeNSig field */ #define timeDMask 0x07 /* bit mask for timeDSig field */ /* Field access: */ #define TimeNSig(sTime) ((((UWORD)sTime) & timeNMask) >> timeNShift) #define TimeDSig(sTime) (((UWORD)sTime) & timeDMask) /* ---------- KeySig SEvent --------------------------------------------*/ /* "data" value 0 = Cmaj; 1 through 7 = G,D,A,E,B,F#,C#; * 8 through 14 = F,Bb,Eb,Ab,Db,Gb,Cb. */ /* ---------- Dynamic SEvent -------------------------------------------*/ /* "data" value is a MIDI key velocity 0..127. */ /* ---------- SMUS Reader Support Routines -----------------------------*/ /* Just call this to read a SHDR chunk. */ #define GetSHDR(context, ssHdr) \ IFFReadBytes(context, (BYTE *)ssHdr, sizeof(SScoreHeader)) /* ---------- SMUS Writer Support Routines -----------------------------*/ /* Just call this to write a SHDR chunk. */ #define PutSHDR(context, ssHdr) \ PutCk(context, ID_SHDR, sizeof(SScoreHeader), (BYTE *)ssHdr) #endif -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Carolyn Scheppner -- CBM >>Amiga Technical Support<< UUCP ...{allegra,caip,ihnp4,seismo}!cbmvax!carolyn PHONE 215-431-9180 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
carolyn@cbmvax.cbm.UUCP (Carolyn Scheppner) (11/20/86)
#ifndef EIGHTSVX_H #define EIGHTSVX_H /*-----------------------------------------------------------------------* * 8SVX.H Definitions for 8-bit sampled voice (VOX). 2/10/86 * * By Jerry Morrison and Steve Hayes, Electronic Arts. * This software is in the public domain. * * This version for the Commodore-Amiga computer. *----------------------------------------------------------------------*/ #ifndef COMPILER_H #include "iff/compiler.h" #endif #include "iff/iff.h" #define ID_8SVX MakeID('8', 'S', 'V', 'X') #define ID_VHDR MakeID('V', 'H', 'D', 'R') #define ID_NAME MakeID('N', 'A', 'M', 'E') #define ID_Copyright MakeID('(', 'c', ')', ' ') #define ID_AUTH MakeID('A', 'U', 'T', 'H') #define ID_ANNO MakeID('A', 'N', 'N', 'O') #define ID_BODY MakeID('B', 'O', 'D', 'Y') #define ID_ATAK MakeID('A', 'T', 'A', 'K') #define ID_RLSE MakeID('R', 'L', 'S', 'E') /* ---------- Voice8Header ---------------------------------------------*/ typedef LONG Fixed; /* A fixed-point value, 16 bits to the left of * the point and 16 to the right. A Fixed is a * number of 2**16ths, i.e. 65536ths. */ #define Unity 0x10000L /* Unity = Fixed 1.0 = maximum volume */ /* sCompression: Choice of compression algorithm applied to the samples. */ #define sCmpNone 0 /* not compressed */ #define sCmpFibDelta 1 /* Fibonacci-delta encoding (Appendix C) */ /* Could be more kinds in the future. */ typedef struct { ULONG oneShotHiSamples, /* # samples in the high octave 1-shot part */ repeatHiSamples, /* # samples in the high octave repeat part */ samplesPerHiCycle; /* # samples/cycle in high octave, else 0 */ UWORD samplesPerSec; /* data sampling rate */ UBYTE ctOctave, /* # of octaves of waveforms */ sCompression; /* data compression technique used */ Fixed volume; /* playback nominal volume from 0 to Unity * (full volume). Map this value into * the output hardware's dynamic range. */ } Voice8Header; /* ---------- NAME -----------------------------------------------------*/ /* NAME chunk contains a CHAR[], the voice's name. */ /* ---------- Copyright ------------------------------------------------*/ /* "(c) " chunk contains a CHAR[], the FORM's copyright notice. */ /* ---------- AUTH -----------------------------------------------------*/ /* AUTH chunk contains a CHAR[], the author's name. */ /* ---------- ANNO -----------------------------------------------------*/ /* ANNO chunk contains a CHAR[], the author's text annotations. */ /* ---------- Envelope ATAK & RLSE -------------------------------------*/ typedef struct { UWORD duration; /* segment duration in milliseconds, > 0 */ Fixed dest; /* destination volume factor */ } EGPoint; /* ATAK and RLSE chunks contain an EGPoint[], piecewise-linear envelope. */ /* The envelope defines a function of time returning Fixed values. * It's used to scale the nominal volume specified in the Voice8Header. */ /* ---------- BODY -----------------------------------------------------*/ /* BODY chunk contains a BYTE[], array of audio data samples. */ /* (8-bit signed numbers, -128 through 127.) */ /* ---------- 8SVX Reader Support Routines -----------------------------*/ /* Just call this macro to read a VHDR chunk. */ #define GetVHDR(context, vHdr) \ IFFReadBytes(context, (BYTE *)vHdr, sizeof(Voice8Header)) /* ---------- 8SVX Writer Support Routines -----------------------------*/ /* Just call this macro to write a VHDR chunk. */ #define PutVHDR(context, vHdr) \ PutCk(context, ID_VHDR, sizeof(Voice8Header), (BYTE *)vHdr) #endif -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Carolyn Scheppner -- CBM >>Amiga Technical Support<< UUCP ...{allegra,caip,ihnp4,seismo}!cbmvax!carolyn PHONE 215-431-9180 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
carolyn@cbmvax.cbm.UUCP (Carolyn Scheppner) (11/20/86)
/** Read8SVX.c ************************************************************** * * Read a sound sample from an IFF file. 21Jan85 * * By Steve Hayes, Electronic Arts. * This software is in the public domain. * ****************************************************************************/ #include "exec/types.h" #include "exec/exec.h" #include "libraries/dos.h" #include "iff/8svx.h" /* Message strings for IFFP codes. */ char MsgOkay[] = { "(IFF_OKAY) No FORM 8SVX in the file." }; char MsgEndMark[] = { "(END_MARK) How did you get this message?" }; char MsgDone[] = { "(IFF_DONE) All done."}; char MsgDos[] = { "(DOS_ERROR) The DOS returned an error." }; char MsgNot[] = { "(NOT_IFF) Not an IFF file." }; char MsgNoFile[] = { "(NO_FILE) No such file found." }; char MsgClientError[] = { "(CLIENT_ERROR) Read8SVX bug or insufficient RAM."}; char MsgForm[] = { "(BAD_FORM) A malformed FORM 8SVX." }; char MsgShort[] = { "(SHORT_CHUNK) A malformed FORM 8SVX." }; char MsgBad[] = { "(BAD_IFF) A mangled IFF file." }; /* THESE MUST APPEAR IN RIGHT ORDER!! */ char *IFFPMessages[-LAST_ERROR+1] = { /*IFF_OKAY*/ MsgOkay, /*END_MARK*/ MsgEndMark, /*IFF_DONE*/ MsgDone, /*DOS_ERROR*/ MsgDos, /*NOT_IFF*/ MsgNot, /*NO_FILE*/ MsgNoFile, /*CLIENT_ERROR*/ MsgClientError, /*BAD_FORM*/ MsgForm, /*SHORT_CHUNK*/ MsgShort, /*BAD_IFF*/ MsgBad }; typedef struct { ClientFrame clientFrame; UBYTE foundVHDR; UBYTE pad1; Voice8Header sampHdr; } SVXFrame; /* NOTE: For a simple version of this program, set Fancy to 0. * That'll compile a program that skips all LISTs and PROPs in the input * file. It will look in CATs for FORMs 8SVX. That's suitable for most uses. * * For a fancy version that handles LISTs and PROPs, set Fancy to 1. */ #define Fancy 1 BYTE *buf; int szBuf; /** DoSomethingWithSample() ********************************************** * * Interface to Amiga sound driver. * *************************************************************************/ DoSomethingWithSample(sampHdr) Voice8Header *sampHdr; { BYTE *t; printf("\noneShotHiSamples=%ld", sampHdr->oneShotHiSamples); printf("\nrepeatHiSamples=%ld", sampHdr->repeatHiSamples); printf("\nsamplesPerHiCycle=%ld", sampHdr->samplesPerHiCycle); printf("\nsamplesPerSec=%ld", sampHdr->samplesPerSec); printf("\nctOctave=%ld", sampHdr->ctOctave); printf("\nsCompression=%ld", sampHdr->sCompression); printf("\nvolume=0x%lx", sampHdr->volume); /* Decompress, if needed. */ if (sampHdr->sCompression) { t = (BYTE *)AllocMem(szBuf<<1, MEMF_CHIP); DUnpack(buf, szBuf, t); FreeMem(buf, szBuf); buf = t; szBuf <<= 1; }; printf("\nData = %3ld %3ld %3ld %3ld %3ld %3ld %3ld %3ld", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]); printf("\n %3ld %3ld %3ld %3ld %3ld %3ld %3ld %3ld ...\n", buf[8+0],buf[8+1],buf[8+2],buf[8+3],buf[8+4],buf[8+5], buf[8+6],buf[8+ 7]); } /** ReadBODY() *********************************************************** * * Read a BODY into RAM. * *************************************************************************/ IFFP ReadBODY(context) GroupContext *context; { IFFP iffp; szBuf = ChunkMoreBytes(context); buf = (BYTE *)AllocMem(szBuf, MEMF_CHIP); if (buf == NULL) iffp = CLIENT_ERROR; else iffp = IFFReadBytes(context, (BYTE *)buf, szBuf); CheckIFFP(); } /** GetFo8SVX() ********************************************************** * * Called via ReadSample to handle every FORM encountered in an IFF file. * Reads FORMs 8SVX and skips all others. * Inside a FORM 8SVX, it reads BODY. It complains if it * doesn't find an VHDR before the BODY. * * [TBD] We could read and print out any NAME and "(c) " chunks. * *************************************************************************/ IFFP GetFo8SVX(parent) GroupContext *parent; { /*compilerBug register*/ IFFP iffp; GroupContext formContext; SVXFrame smusFrame; /* only used for non-clientFrame fields.*/ if (parent->subtype != ID_8SVX) return(IFF_OKAY); /* just continue scaning the file */ smusFrame = *(SVXFrame *)parent->clientFrame; iffp = OpenRGroup(parent, &formContext); CheckIFFP(); do switch (iffp = GetFChunkHdr(&formContext)) { case ID_VHDR: { smusFrame.foundVHDR = TRUE; iffp = GetVHDR(&formContext, &smusFrame.sampHdr); break; } case ID_BODY: { if (!smusFrame.foundVHDR) iffp = BAD_FORM; /* Need an VHDR chunk first! */ else iffp = ReadBODY(&formContext); break; } case END_MARK: { if (!smusFrame.foundVHDR) iffp = BAD_FORM; else iffp = IFF_DONE; break; } } while (iffp >= IFF_OKAY); /* loop if valid ID of ignored chunk or a * subroutine returned IFF_OKAY (no errors).*/ if (iffp != IFF_DONE) return(iffp); /* If we get this far, there were no errors. */ CloseRGroup(&formContext); DoSomethingWithSample(&smusFrame.sampHdr); FreeMem(buf, szBuf); return(iffp); } /** Notes on extending GetFo8SVX **************************************** * * To read more kinds of chunks, just add clauses to the switch statement. * To read more kinds of property chunks (like NAME) add clauses to * the switch statement in GetPr8SVX, too. * ************************************************************************/ /** GetPr8SVX() ********************************************************* * * Called via ReadSample to handle every PROP encountered in an IFF file. * Reads PROPs 8SVX and skips all others. * *************************************************************************/ #if Fancy IFFP GetPr8SVX(parent) GroupContext *parent; { /*compilerBug register*/ IFFP iffp; GroupContext propContext; SVXFrame *svxFrame = (SVXFrame *)parent->clientFrame; /* Subclass */ if (parent->subtype != ID_8SVX) return(IFF_OKAY); /* just continue scaning the file */ iffp = OpenRGroup(parent, &propContext); CheckIFFP(); do switch (iffp = GetPChunkHdr(&propContext)) { case ID_VHDR: { svxFrame->foundVHDR = TRUE; iffp = GetVHDR(&propContext, &svxFrame->sampHdr); break; } } while (iffp >= IFF_OKAY); /* loop if valid ID of ignored chunk or a * subroutine returned IFF_OKAY (no errors).*/ CloseRGroup(&propContext); return(iffp == END_MARK ? IFF_OKAY : iffp); } #endif /** GetLi8SVX() ********************************************************** * * Called via ReadSample to handle every LIST encountered in an IFF file. * *************************************************************************/ #if Fancy IFFP GetLi8SVX(parent) GroupContext *parent; { SVXFrame newFrame; /* allocate a new Frame */ newFrame = *(SVXFrame *)parent->clientFrame; /* copy parent frame */ return( ReadIList(parent, (ClientFrame *)&newFrame) ); } #endif /** ReadSample() ********************************************************** * * Read IFF 8SVX, given a file handle open for reading. * *************************************************************************/ IFFP ReadSample(file) LONG file; { SVXFrame sFrame; /* Top level "client frame".*/ IFFP iffp = IFF_OKAY; #if Fancy sFrame.clientFrame.getList = GetLi8SVX; sFrame.clientFrame.getProp = GetPr8SVX; #else sFrame.clientFrame.getList = SkipGroup; sFrame.clientFrame.getProp = SkipGroup; #endif sFrame.clientFrame.getForm = GetFo8SVX; sFrame.clientFrame.getCat = ReadICat ; /* Initialize the top-level client frame's property settings to the * program-wide defaults. This example just records that we haven't read * any VHDR properties yet. * If you want to read another property, init it's fields in sFrame. */ sFrame.foundVHDR = FALSE; sFrame.pad1 = 0; iffp = ReadIFF(file, (ClientFrame *)&sFrame); return(iffp); } /** main0() **************************************************************/ void main0(filename) char *filename; { LONG file; IFFP iffp = NO_FILE; file = Open(filename, MODE_OLDFILE); if (file) iffp = ReadSample(file); Close(file); printf(" %s\n", IFFPMessages[-iffp]); } /** main() ***************************************************************/ void main(argc, argv) int argc; char **argv; { printf("Reading file '%s' ...", argv[1]); if (argc < 2) printf("\nfilename required\n"); else main0(argv[1]); } -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Carolyn Scheppner -- CBM >>Amiga Technical Support<< UUCP ...{allegra,caip,ihnp4,seismo}!cbmvax!carolyn PHONE 215-431-9180 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
carolyn@cbmvax.cbm.UUCP (Carolyn Scheppner) (11/20/86)
/* DUnpack.c --- Fibonacci Delta decompression by Steve Hayes */ #include <exec/types.h> /* Fibonacci delta encoding for sound data */ BYTE codeToDelta[16] = {-34,-21,-13,-8,-5,-3,-2,-1,0,1,2,3,5,8,13,21}; /* Unpack Fibonacci-delta encoded data from n byte source * buffer into 2*n byte dest buffer, given initial data * value x. It returns the lats data value x so you can * call it several times to incrementally decompress the data. */ BYTE D1Unpack(source,n,dest,x) BYTE source[], dest[]; LONG n; BYTE x; { BYTE d; LONG i, lim; lim = n << 1; for (i=0; i < lim; ++i) { /* Decode a data nibble, high nibble then low nibble */ d = source[i >> 1]; /* get a pair of nibbles */ if (i & 1) /* select low or high nibble */ d &= 0xf; /* mask to get the low nibble */ else d >>= 4; /* shift to get the high nibble */ x += codeToDelta[d]; /* add in the decoded delta */ dest[i] = x; /* store a 1 byte sample */ } return(x); } /* Unpack Fibonacci-delta encoded data from n byte * source buffer into 2*(n-2) byte dest buffer. * Source buffer has a pad byte, an 8-bit initial * value, followed by n-2 bytes comprising 2*(n-2) * 4-bit encoded samples. */ void DUnpack(source, n, dest) BYTE source[], dest[]; LONG n; { D1Unpack(source+2, n-2, dest, source[1]); } -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Carolyn Scheppner -- CBM >>Amiga Technical Support<< UUCP ...{allegra,caip,ihnp4,seismo}!cbmvax!carolyn PHONE 215-431-9180 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
carolyn@cbmvax.cbm.UUCP (Carolyn Scheppner) (11/20/86)
Example linkage for Read8svx.c. Note that iffr.o is the object of one of the standard IFF reader modules. For this link, all modules must be compiled with the -v flag on LC2. FROM LIB:AStartup.obj, Read8svx.o, dUnpack.o, iffr.o LIBRARY LIB:Amiga.lib TO Read8svx -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Carolyn Scheppner -- CBM >>Amiga Technical Support<< UUCP ...{allegra,caip,ihnp4,seismo}!cbmvax!carolyn PHONE 215-431-9180 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=