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.
Source/DoubleBuffer.c
#include <Resources.h> |
#include <Sound.h> |
#include <Memory.h> |
#define TRUE 0xFF |
#define FALSE 0 |
#define kDoubleBufferSize 0x1000 |
struct LocalVars { |
long bytesTotal; |
long bytesCopied; |
Ptr dataPtr; |
}; |
typedef struct LocalVars LocalVars; |
typedef LocalVars *LocalVarsPtr; |
pascal void MyDoubleBackProc (SndChannelPtr channel, |
SndDoubleBufferPtr doubleBufferPtr); |
void main() |
{ |
SndDoubleBufferHeader doubleHeader; |
SndDoubleBufferPtr doubleBuffer; |
int i; |
OSErr err; |
SCStatus Stats; |
SndChannelPtr chan; |
SoundHeaderPtr Head; |
Handle SoundData; |
LocalVars myVars; |
SoundData = GetResource ('snd ', 100); |
if (ResError() != noErr || SoundData == nil) |
Debugger(); |
HLock (SoundData); |
chan = nil; |
err = SndNewChannel (&chan, sampledSynth, 0, nil); |
if (err != noErr) |
Debugger(); |
Head = (SoundHeaderPtr) NewPtrClear (sizeof(SoundHeader)); |
Head->samplePtr = *SoundData; |
Head->length = 45838; |
Head->sampleRate = 0x56EE8BA3; //recorded at 22KHz |
Head->loopStart = 0; |
Head->loopEnd = 0; |
Head->encode = 0; |
Head->baseFrequency = 60; |
Head->sampleArea[0] = 0; |
myVars.bytesTotal = Head->length; |
myVars.bytesCopied = 0; |
myVars.dataPtr = Head->samplePtr; |
doubleHeader.dbhNumChannels = 1; |
doubleHeader.dbhSampleSize = 8; |
doubleHeader.dbhCompressionID = 0; |
doubleHeader.dbhPacketSize = 0; |
doubleHeader.dbhSampleRate = Head->sampleRate; |
/* create a UPP for the SndDoubleBackProc */ |
doubleHeader.dbhDoubleBack = NewSndDoubleBackProc (MyDoubleBackProc); |
for (i = 0; i <= 1; ++i) { |
doubleBuffer = (SndDoubleBufferPtr) NewPtrClear (sizeof(SndDoubleBuffer) + kDoubleBufferSize); |
if (doubleBuffer == nil || MemError() != 0) |
Debugger(); |
doubleBuffer->dbNumFrames = 0; |
doubleBuffer->dbFlags = 0; |
doubleBuffer->dbUserInfo [0] = (long) &myVars; |
MyDoubleBackProc (chan, doubleBuffer); // initialize the buffers |
doubleHeader.dbhBufferPtr [i] = doubleBuffer; |
} |
err = SndPlayDoubleBuffer (chan, &doubleHeader); |
if (err != noErr) |
Debugger(); |
do { |
err = SndChannelStatus (chan, sizeof (Stats), &Stats); |
} while (Stats.scChannelBusy); |
for (i = 0; i <= 1; ++i) |
DisposePtr ((Ptr) doubleHeader.dbhBufferPtr[i]); |
err = SndDisposeChannel (chan,FALSE); |
if (err != noErr) |
Debugger(); |
HUnlock (SoundData); |
} |
/**********************************/ |
pascal void MyDoubleBackProc (SndChannelPtr chan,SndDoubleBufferPtr doubleBuffer) |
{ |
#pragma unused (chan) |
LocalVarsPtr myVarsPtr; |
long bytesToCopy; |
myVarsPtr = (LocalVarsPtr) doubleBuffer->dbUserInfo[0]; |
bytesToCopy = myVarsPtr->bytesTotal - myVarsPtr->bytesCopied; |
if (bytesToCopy > kDoubleBufferSize) |
bytesToCopy = kDoubleBufferSize; |
BlockMove (myVarsPtr->dataPtr, &doubleBuffer->dbSoundData[0], bytesToCopy); |
doubleBuffer->dbNumFrames = bytesToCopy; |
doubleBuffer->dbFlags = (doubleBuffer->dbFlags) | dbBufferReady; |
myVarsPtr->dataPtr = (Ptr) ((myVarsPtr->dataPtr) + bytesToCopy); |
myVarsPtr->bytesCopied = myVarsPtr->bytesCopied + bytesToCopy; |
if (myVarsPtr->bytesCopied == myVarsPtr->bytesTotal) |
doubleBuffer->dbFlags = (doubleBuffer->dbFlags) | dbLastBuffer; |
return; |
} |
/**********************************/ |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14