SetSoundInput.c

#include    <Quickdraw.h>
#include    <Windows.h>
#include    <Dialogs.h>
#include    <Files.h>
#include    <StandardFile.h>
#include    <Packages.h>
#include    <OSEvents.h>
#include    <Memory.h>
#include    <Sound.h>
#include    <SoundInput.h>
#include    <OSUtils.h>
#include    <ToolUtils.h>
#include    <Types.h>
#include    <TextUtils.h>
 
struct soundRateData{
    short numberOfRatesSupported;
    Handle ratesSupported;
} soundRateInfo;
 
void main()
{
    SndChannelPtr           mySoundChannel;
    StandardFileReply       fileReply;
    short                   myFRefNum;
    short                   numChannels = 1;
    short                   sampleSize = 0;
    short                   twosComplementSetting = 1;
    long                    soundDuration = 20000;
    OSErr                   err = 0;
    long                    mySIRefNum;
    Fixed                   previousSampleRate = 0;
    Fixed                   mySISampleRate = 0x00000000;
    SPBPtr                  mySIParamBlockPtr;
    ParmBlkPtr              myIOParamBlockPtr;
    Fixed                   *myFixedPointer;
    Fixed                   myFixedVariable = 0;
    Boolean                 allDone = false;
    
    InitGraf(&qd.thePort);
    FlushEvents(everyEvent, 0);
    InitWindows();
    InitDialogs(nil);
    InitCursor();
    
    soundRateInfo.numberOfRatesSupported = 0;
    soundRateInfo.ratesSupported = nil;
    
    /*Allocate our own sound channel--we don't have to for this but why not!*/
    mySoundChannel = (SndChannelPtr) NewPtr(sizeof (SndChannel));
    err = SndNewChannel(&mySoundChannel, sampledSynth, 0, nil);
    if (err != noErr)
        DebugStr("\p Failure at SndNewChannel");
    
    /*Select a file to record to*/
    StandardGetFile(nil, -1, (SFTypeList) nil, &fileReply);
    err = FSpOpenDF (&fileReply.sfFile, fsRdWrPerm, &myFRefNum);
    if (err != noErr)
        DebugStr("\p Failure at call to FSpOpenDF");
                
    /*Open the sound input device*/
    err = SPBOpenDevice("\p",siWritePermission,&mySIRefNum);
    if (err != noErr)
        DebugStr("\p Failure at call to SPBOpenDevice");
        
    /*Get the current sound input rate to be restored when we're done.
    We're not going to do anything with this now, it is here as an example.
    You would want to get information for all settings you are going to change below
    in order to restore them later*/
    
    err = SPBGetDeviceInfo(mySIRefNum,siSampleRate, (Ptr) &previousSampleRate);
    if (err != noErr)
        DebugStr("\p Failure at call to SPBGetDeviceInfo");
        
    
    /*Set the number of channels we will be using*/
    err = SPBSetDeviceInfo(mySIRefNum,siNumberChannels, (Ptr) &numChannels);
    if (err != noErr)
        DebugStr("\p Failure at call to SPBSetDeviceInfo numChannels");
    
        
    /*Get the  number of sample rates supported*/
    err = SPBGetDeviceInfo(mySIRefNum,siSampleRateAvailable,(Ptr) &soundRateInfo);
    if (err != noErr)
        DebugStr("\p Failure at call to SPBSetDeviceInfo set to 0");
    
    /*Now we move to the end of our list of sample rates to get the best one--this is a little flaky
    since I am using the fact that the highest rate is currently the last rate in the 
    buffer. . .if this were to change I'd be hosed 8-)*/
    
    myFixedPointer = (Fixed *)(*(soundRateInfo.ratesSupported));
    
    
    myFixedPointer = myFixedPointer + ((soundRateInfo.numberOfRatesSupported) -1);
    myFixedVariable = *myFixedPointer;
    switch (myFixedVariable)
    {
        case 0xBB800000:
            mySISampleRate = 0xBB800000;
            sampleSize = 16;
            break;
        case 0xAC440000:
            mySISampleRate = 0xAC440000;
            sampleSize = 16;
            break;
        case 0x56EE8BA3:
            mySISampleRate = 0x56EE8BA3;
            sampleSize = 8;
            break;
        case 0x56220000:
            mySISampleRate = 0x56220000;
            sampleSize = 8;
            break;
        default:
            mySISampleRate = 0x56EE8BA3;
            sampleSize = 8;
            break;
    }
            
    /*Set the sound input rate to the rate that we want*/
    err = SPBSetDeviceInfo(mySIRefNum,siSampleRate, (Ptr) &mySISampleRate);
    if (err != noErr)
        DebugStr("\p Failure at call to SPBSetDeviceInfo sampleRate");
        
    /*Set the sample size to the size that we want*/
    err = SPBSetDeviceInfo(mySIRefNum,siSampleSize, (Ptr) &sampleSize);
    if (err != noErr)
        DebugStr("\p Failure at call to SPBSetDeviceInfo sampleSize");
        
    /*If we're using 8-bit data we need to set the state of the two's complement feature*/
    err = SPBSetDeviceInfo(mySIRefNum,siTwosComplementOnOff, (Ptr) &twosComplementSetting);
    if (err != noErr)
        DebugStr("\p Failure at call to SPBSetDeviceInfo twosComplement");
    
    /*Set up our AIFF file header*/
    err = SetupAIFFHeader(myFRefNum,1,mySISampleRate, sampleSize, 'NONE', 0, 0);
    if (err != noErr)
        DebugStr("\p Failure at call to SetupAIFFHeader");
        
    /*Set up our param block and record our sound*/
    mySIParamBlockPtr = (SPBPtr) NewPtr(sizeof (SPB));
    if (MemError() != noErr || mySIParamBlockPtr == nil)
        DebugStr("\p Failure at memory allocation for Sound Param Block");
    
    mySIParamBlockPtr->inRefNum = mySIRefNum;
    mySIParamBlockPtr->count = 0;
    mySIParamBlockPtr->milliseconds = soundDuration;
    mySIParamBlockPtr->completionRoutine = nil;
    mySIParamBlockPtr->interruptRoutine = nil;
    mySIParamBlockPtr->userLong = 0;
    mySIParamBlockPtr->unused1 = 0;
    
    err = SPBRecordToFile (myFRefNum, mySIParamBlockPtr, false);
    if (err != noErr)
        DebugStr("\p Failure at call to SPBRecordToFile");
    
    /*We're done recording so close the device*/
    err = SPBCloseDevice(mySIRefNum);
    if (err != noErr)
        DebugStr("\p Failure at call to SPBCloseDevice");
 
    /*Now that we've recorded to our file, let's setup for playing the sound data back*/
    err = SPBMillisecondsToBytes(mySIRefNum, &soundDuration); 
    myIOParamBlockPtr = (ParmBlkPtr) NewPtr(sizeof (IOParam));
    if (MemError() != noErr || myIOParamBlockPtr == nil)
        DebugStr("\p Failure at memory allocation for ioParamBlock");
    
    myIOParamBlockPtr->ioParam.ioCompletion = nil; //Setup our ioParam Block
    myIOParamBlockPtr->ioParam.ioRefNum = myFRefNum;
    myIOParamBlockPtr->ioParam.ioPosMode = fsFromStart;
    myIOParamBlockPtr->ioParam.ioPosOffset = 0;
    
    err = PBSetFPos(myIOParamBlockPtr, false); //Set our sound file position to the beginning 
    if (err != noErr)
        DebugStr("\p Failure at call to PBSetFPos");
        
    err = SetupAIFFHeader(myFRefNum,1,mySISampleRate, sampleSize, 'NONE', soundDuration, 0);
    if (err != noErr)
        DebugStr("\p Failure at call to SetupAIFFHeader");
        
    err = SndStartFilePlay(mySoundChannel, myFRefNum, 0, 30000, nil, nil, nil, false);
    if (err != noErr)
        DebugStr("\p Failure at call to SndStartFilePlay");
        
    /*Dispose of Channel*/
    SndDisposeChannel(mySoundChannel, true);
    
    /*Dispose of param block pointers*/
    DisposePtr ((Ptr) myIOParamBlockPtr);
    DisposePtr ((Ptr) mySIParamBlockPtr);
    
    /*Close the file. . .goodnight!*/
    FSClose(myFRefNum);
}