Distribution: COMPANY CONFIDENTIAL Project: Browser Issue: 0.01 Author(s): Simon Middleton Date: 10-May-96 Last Issue: None
10-May-96 SJM Started
None
There are many different types of sound file formats in existence however they are generally very similar in structure.
This module provides an extensible method for accessing these files.
SoundFile is a module designed to make it easy for any application to read and decode foreign sound file types. It provides SWIs to open and decode the type of a file and translation code to convert from various data formats to 16 bit linear.
The system is easily extensible. The SoundFile module will provide support for a few core file types and data formats. Other types can be provided for transparently by use of SoundFileExtension modules. These communicate with the main module via Service calls and function pointers.
Note SoundFile doesn't do any playback itself, it just provides detection and translation services, it is up to the application (possibly using the ReplaySupport module) to feed the data to an output device.
SoundFile provides two commands for general use.
Scans and identifies the file format and prints out information on it. The information given may vary from version to version and shouldn't be relied upon to occur in any particular format.
Normally the SoundFile module will refuse to die if it thinks it still has any files open. This call forces all sound files closed. It should be used with extreme care.
On entry, R0 always holds a flags word.
On exit, if V is set then R0 points to a standard error block. If V is clear then R0 will be corrupted.
All registers not specifically mentioned will be preserved.
Open a file and identify it. If the file format cannot be identified (but no other error is given) then as much information as possible will be filled in.
On entry: R0 = flags bits 0,1: type of data in R1 0 file name R1 -> null-terminated file name 1 file handle R1 -> SoundFile_OpenHandleInfo 2 memory buffer R1 -> SoundFile_OpenBufferInfo 3 reserved bit 2: how to interpret R2 1 set data format from block filling in derived parameters 0 interrogate file and fill in block bit 3: keep file open? 1 fill in or update format block and then close file 0 keep file open for further operations R1 -> file info (see above) R2 -> SoundFile_Format block On exit: R0 = soundfile handle R1 -> SoundFile_Stream block
Soundfile handle is an opaque handle that should be passed back in when the other SWI's are used.
Closes the sound file. Releases any resources claimed.
On entry: R0 = flags R1 = soundfile handle
This allows you to read data out from the file, either in its native format or pre-translated to 16bit. 'buffer' must be large enough.
On entry: R0 = flags bit 0: 1 = Convert data to 16bit 0 = Leave data in native format bits 1-31: reserved R1 = soundfile handle R2 -> buffer R3 = n samples R4 = start sample index On exit: R2 -> next byte to write to. R3 = n samples not read R4 = next soundfile position to read from
Note this interface is not actually used in current ARPlayer and is not completely operational.
Miscellaneous operations
On entry: R0 = flags and op code bits 0-7: operation bits 8-31: flags for operation Other registers as needed for operation
This reason code allows access to the lookup tables that SoundFile holds internally.
On entry: R0 = 0 R1 = Data format code On exit: R0 -> lookup table within SoundFile, or 0
The format code is as returned in the format block in the word at +12.
Not all formats have a lookup table, for those that don't, r0 = 0.
Those currently returning pointers are as follows:
They each return a pointer to a 512 byte table. This is a table of 256 half words mapping the encoded sample value to a 16 bit signed linear value.
A SoundFileExtension module just needs to implement a service call handler to look for Service_IdentifySoundFile and respond if it can. It should store all the information necessary to access the file in the buffer pointed to by R5. If it needs to allocate extra space for more info it can do this, and should store the pointer to this info in the buffer. When it is called via its dispose handler it should free any extra space it allocated.
This handler is called directly from the SoundFile module when necessary.
On entry: R0 = flags and op code bits 0-7: reason code bits 8-31: reason dependant flags R11 -> SoundFile_Format (as filled in by module originally) R12 = private word (as filled in to SoundFile_Format block) On exit: VS, R0 -> error block VC, R0 corrupted All other registers preserved unless returning values.
This handler is not currently used or defined. It is intended that this be used to handle file types where the sound data is not stored contiguously (eg ARMovie files or AVI files).
Convert data to 16bit buffer.
On entry: R1 -> input buffer R2 -> output buffer R3 = number of samples R4 = number of channels R12 = handler_r12 from SoundFile_Format
Free any extra memory allocated and stored in the SoundFile_Format block.
On entry: R0 -> SoundFile_Format block R12 = handler_r12 from SoundFile+Format
This is is an initial list of filetypes for which work has been done. It is intended that it be extended as far as time allows.
Filetype Extension Name Source --------------------------------------------------- FC2 .aif AIFF/AIFC Mac/Amiga FB1 .wav Wave Microsoft D3C ArmSamp Clares CB5 STSample Sound Tracker sample C47 SoundLib Iota Complete Animator BD6 AudioWrk Computer Concepts .voc SoundBlaster Creative Labs .8SVX Amiga .au .snd NeXT/Sun audio Psion S3A
AIFC is an extended version of AIFF supporting compressed formats. Unfortunately information on the compression algorithms is difficult to find.
Wave supports many different compression formats. There seem to be as many different compression formats as there are PC manufacturers, some of which are proprietary. Therefore we will stick to the simple ones unless formats appear to be important. One case that is important is Microsoft ADPCM (type 2) as it is used in a number of key CDROMs.
Only the uncompressed Iota samples are supported.
There are many sub types of AU. Only 8 and 16 bit are supported.
Identify the type of sound file or supply special routines for an already identified type. The bottom byte of R0 gives a reason code describing what is needed.
If the reason code is 0 then the file has not been identified at all, R4 points to the first 1024 bytes of the file and all information in the SoundFileInfo structure pointed to by R5 should be filled in.
If the reason code is 1 then the file has been identified as a Microsoft Wave file, however the format code is not supported by the SoundFile module. In this case R4 points to the description structure for this format (or the first 1024 bytes of it) and the format independent information will have already been entered into the SoundFileInfo structure.
On entry: R0 bits 0-7 = reason code 0 = IdentifySoundFile_Unknown 1 = IdentifySoundFile_Wave other values are reserved bits 8-31 = flags all bits reserved R1 = Service_IdentifySoundFile R2 = soundfile stream handle R3 -> OS_GBPB block R4 -> SoundFile_Format structure On exit: If file format or compression type is recognised R0 = should be set to 0 or error pointer R1 = 0 (claim service call) R4 updated with details of file type If file not recognised all registers preserved
This is the main information block.
+0 Flags bit 0: 1 = data is unsigned 0 = data is signed bit 1: 1 = stereo positions reversed (RL) 0 = stereo is stored LR bit 2: 1 = the format is unsupported +4 Source Identifier for the file format, where there is a file type allocated then this is the identifier used. Other types recognised are VOC 0x20434F56 AU 0x20205541 8SVX 0x58565338 Psion 0x6f697350 +8 Bits per sample +9 Number of channels +10 Sample period in µs +11 Channel interleave In multi-channel formats this is the number of successive samples from the same channel in each block. +12 Data format code -1 Unknown 0 8 Bit Linear 1 8 Bit VIDC 2 8 Bit µ-Law 3 8 Bit A-Law 4 12 Bit Linear 5 16 Bit Linear 6 16 Bit Linear Big Endian +16 Sample rate, in 1/1024 Hz +20 Number of samples +24 Data offset, in bytes Offset to sample data in file +28 Data length, in bytes +32 Block alignment, in bytes +36 Minimum chunk size, in bytes +40 Maximum sample size, 1/65536 sample +44 Info offset, in bytes Offset to important sample info block for format +48 event handler private word (passed in R12) +52 load data handler address (reserved) +56 convert to 16bit handler address +60 dispose handler address +64 reserved (8 words) ... +96 Format specific data (8 words) ... +128 textual name for format (24 bytes, null-terminated) +152 textual name for compression type (24 bytes, null-terminated) +176 textual comments (80 bytes, null-terminated)
One of sample rate or period must be filled in.
The call should be claimed if the module is sure it can handle the file. eg if a module were to recognise .WAV but could only handle one type of compression format then it should ignore all .WAVs of other formats so that another module gets the chance to handle them.
The Extension module is free to store whatever it wishes in the the Format specific data area. This includes pointers to other pieces of allocated memory. In this case ensure that bit 2 is set so that the module will be called to free this space.
+0 Flags bits 0,1: as passed in SoundFile_Open +4 current position +8 ptr to buffer +12 buffer size +16 OS file handle +20 ptr to original file name
+0 OS file handle +4 Load address +8 Execute address +12 File size +16 Attribute bits +20 Object type +24 File type
+0 ptr to data +4 size of data in bytes +8 Load address +12 Execute address +16 File size +20 Attribute bits +24 Object type +28 File type
None.
To be decided.
None.
The product is a relocatable module is written in C and assembler using Acorn C release 5 with veneers by cmhg. Some OSLib headers are used and DefMod is used to create an interface header and library. it is integrated into the Omega source tree for a ROM build.
It is possible you might want to run this system from somewhere other than a file, ie some kind of data stream. This could probably be handled with a bit of thought.