Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
AIFFWriter.h
////////// |
// |
// File: AIFFWriter.c |
// |
// Contains: Header for dispatching a sound hardware output ('sdev') component. |
// |
// Written by: Mark Cookson, Apple Developer Technical Support |
// Based on code by Kip Olson. |
// Revised by: Tim Monroe |
// |
// Copyright: © 1993-1999 by Apple Computer, Inc., all rights reserved. |
// |
// Change History (most recent first): |
// |
// <2> 03/05/99 rtm further work to bring into line with existing component sample code |
// <1> 02/25/99 rtm first inherited file; changed some compiler conditionals |
// to support Windows compiles |
// |
// You may incorporate this sample code into your applications without |
// restriction, though the sample code has been provided "AS IS" and the |
// responsibility for its operation is 100% yours. However, what you are |
// not permitted to do is to redistribute the source as "Apple Sample |
// Code" after having made changes. If you're going to re-distribute the |
// source, we require that you make it clear in the source that the code |
// was descended from Apple Sample Code, but that you've made changes. |
// |
////////// |
#ifndef __AIFFWRITER__ |
#define __AIFFWRITER__ |
////////// |
// |
// header files |
// |
////////// |
#ifndef __COMPONENTS__ |
#include <Components.h> |
#endif |
#ifndef __MACMEMORY__ |
#include <MacMemory.h> |
#endif |
#ifndef __MACERRORS__ |
#include <MacErrors.h> |
#endif |
#ifndef __SOUND__ |
#include <Sound.h> |
#endif |
#ifndef __TIMER__ |
#include <Timer.h> |
#endif |
#ifndef __FIXMATH__ |
#include <FixMath.h> |
#endif |
#ifndef __SCRIPT__ |
#include <Script.h> |
#endif |
////////// |
// |
// compiler flags |
// |
////////// |
#define FakeInterrupts 1 |
////////// |
// |
// constants |
// |
////////// |
#define kSoundComponentVersion 0x00010000 // version for this component |
#define kSndFileName "\pAIFF Writer output" // name for sound file data is written to |
#define kAIFFWriterName "\pAIFF Writer" |
#define kSecondsInIOBuffer 1 // number of seconds of audio data in each I/O buffer |
#define kAIFFWriterSifterID 128 |
#define kAIFFWriterPanelID 130 |
#define kAIFFWriterSubType 'hack' // OS Type for component |
#define kAIFFCreator FOUR_CHAR_CODE('TVOD') |
#define kAIFFFileType FOUR_CHAR_CODE('AIFF') |
enum { |
kHardwareVolumeSteps = 16, // levels of volume adjustments |
kHardwareSampleCount = 1024, // number of samples in hardware buffer |
kHardwareByteSize = kHardwareSampleCount * 2 * 2 // enough for 16 bit stereo |
}; |
////////// |
// |
// data types |
// |
////////// |
#if PRAGMA_STRUCT_ALIGN |
#pragma options align=mac68k |
#elif PRAGMA_STRUCT_PACKPUSH |
#pragma pack(push, 2) |
#elif PRAGMA_STRUCT_PACK |
#pragma pack(2) |
#endif |
typedef struct myTMTask myTMTask; |
typedef struct myTMTask *myTMTaskPtr; |
typedef struct SoundOutputGlobals SoundOutputGlobals; |
typedef struct SoundOutputGlobals *SoundOutputGlobalsPtr; |
// a Time Manager task record that includes space for my globals at the end |
struct myTMTask { |
TMTask task; |
SoundOutputGlobalsPtr globals; |
}; |
// i/o buffer structure |
typedef struct IOBuffer { |
ParamBlockRec iopb; // i/o parameter block |
long byteCount; // no. bytes in buffer |
Ptr buffer; // buffer for data |
} IOBuffer, *IOBufferPtr; |
typedef struct HardwarePreferences { |
long size; // size of current preferences |
Fixed version; // 16.16 value for version |
unsigned long volume; // current hardware volume |
UnsignedFixed sampleRate; // current sample rate |
short sampleSize; // current sample size |
short numChannels; // current num channels |
short muteState; // current hardware mute state |
short sampleCount; // size of interrupt buffer in samples |
} HardwarePreferences, *HardwarePrefsPtr, **HardwarePrefsHandle; |
struct SoundOutputGlobals { |
// component stuff |
ComponentInstance sourceComponent; // component to call when hardware needs more data |
SoundComponentDataPtr sourceDataPtr; // pointer to source data structure |
SoundComponentData outputData; |
ComponentInstance self; // our component's instance |
// fields specific to this component implementation |
HardwarePrefsHandle prefs; // user's preferences |
Boolean prefsChanged; // true if prefs need to be saved to disk |
Boolean hardwareOn; // true if hardware is on, false if it is off |
Boolean inAppHeap; // true if loaded into an app's heap |
Boolean padding1; // padding to align struct |
unsigned long ioBufferSize; // size of i/o buffer in bytes |
long interruptInterval; // time in microseconds between interrupts |
myTMTask tmTask; // time manager task record used to trigger interrupt |
long headerLen; // length of AIFF header written to beginning of file |
short fRefNum; // fref of file to save data into |
short currentIndex; // current buffer to save data into |
IOBuffer ioBuffers[2]; // buffer descriptions |
#ifdef FakeInterrupts |
unsigned long nextTime; // next time to interrupt |
#endif |
}; |
#if PRAGMA_STRUCT_ALIGN |
#pragma options align=reset |
#elif PRAGMA_STRUCT_PACKPUSH |
#pragma pack(pop) |
#elif PRAGMA_STRUCT_PACK |
#pragma pack() |
#endif |
////////// |
// |
// function prototypes |
// |
////////// |
OSErr SetupHardware (SoundOutputGlobalsPtr globals); |
void ReleaseHardware (SoundOutputGlobalsPtr globals); |
void StartHardware (SoundOutputGlobalsPtr globals); |
void StopHardware (SoundOutputGlobalsPtr globals); |
void ResumeHardware (SoundOutputGlobalsPtr globals); |
void CopySamplesToHardware (SoundOutputGlobalsPtr globals, SoundComponentDataPtr siftPtr); |
void OutputToFile (SoundComponentDataPtr siftPtr, void *dest, long sampleCount); |
Boolean FakeInterrupt (void); |
void InterruptRoutine (SoundOutputGlobalsPtr globals); |
SoundComponentDataPtr GetMoreSource (SoundOutputGlobalsPtr globals); |
OSErr SetupOutputFile (SoundOutputGlobalsPtr globals); |
OSErr CloseOutputFile (SoundOutputGlobalsPtr globals); |
OSErr GetPreferences (SoundOutputGlobalsPtr globals); |
OSErr InitFromPreferences (SoundOutputGlobalsPtr globals); |
//#if TARGET_CPU_68K |
//void TMInterrupt (myTMTaskPtr taskPtr:__a1); |
//#else |
void TMInterrupt (myTMTaskPtr taskPtr); |
//#endif |
unsigned long MicroSeconds (void) ONEWORDINLINE(0xA193); |
extern Ptr GetRegisterA1 (void) ONEWORDINLINE(0x2009); // MOVE.L A1,D0 |
////////// |
// |
// failure handling macros |
// |
////////// |
/* |
Some macros used to check for errors and also to allow for |
handling them by using a goto statement. This makes the source |
code easier to read. It will break into the debugger with a |
message showing the condition that caused the failure. In some |
of the macros the debug message is removed but goto remains. In |
other macros all of it is removed when doing a non-debug build. |
Note that these macros use the "\p" construct for creating |
Pascal strings at compile time. Most non-Mac compilers do |
not recognize this, give a warning, and put 'p' as the first |
character of the string. You can ignore the warning because |
the non-Mac version of DebugStr deals with this just fine. |
For Microsoft's Visual C++, we suppress the warning below. |
*/ |
#if defined(_MSC_VER) && !defined(__MWERKS__) |
// Visual C++ from Microsoft |
#pragma warning(disable:4129) // unrecognized character escape sequence |
#endif |
// This checks for the exception, and if true then goto handler |
#ifdef _DEBUG |
#define FailIf(cond, handler) \ |
if (cond) { \ |
DebugStr((ConstStr255Param)"\p"#cond " goto " #handler); \ |
goto handler; \ |
} else 0 |
#else |
#define FailIf(cond, handler) \ |
if (cond) { \ |
goto handler; \ |
} else 0 |
#endif |
// This checks for the exception, and if true do the action and goto handler |
#ifdef _DEBUG |
#define FailWithAction(cond, action, handler) \ |
if (cond) { \ |
DebugStr((ConstStr255Param)"\p"#cond " goto " #handler); \ |
{ action; } \ |
goto handler; \ |
} else 0 |
#else |
#define FailWithAction(cond, action, handler) \ |
if (cond) { \ |
{ action; } \ |
goto handler; \ |
} else 0 |
#endif |
// This will insert debugging code in the application to check conditions |
// and displays the condition in the debugger if true. This code is |
// completely removed in non-debug builds. |
#ifdef _DEBUG |
#define FailMessage(cond) \ |
if (cond) \ |
DebugStr((ConstStr255Param)"\p"#cond); \ |
else 0 |
#else |
#define FailMessage(cond) |
#endif |
// This allows you to test for the result of a condition (i.e. CloseComponent) |
// and break if it returns a non zero result, otherwise it ignores the result. |
// When a non-debug build is done, the result is ignored. |
#ifdef _DEBUG |
#define ErrorMessage(cond) \ |
if (cond) \ |
DebugStr((ConstStr255Param)"\p"#cond); \ |
else 0 |
#else |
#define ErrorMessage(cond) cond |
#endif |
// This will display a given message in the debugger; this code is completely |
// removed in non-debug builds. |
#ifdef _DEBUG |
#define DebugMessage(s) DebugString((ConstStr255Param)s) |
#else |
#define DebugMessage(s) |
#endif |
#endif // __AIFFWRITER__ |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14