home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Audio 4.94 - Over 11,000 Files
/
audio-11000.iso
/
mac
/
soundutl
/
vmtrs10s.hqx
/
VUMeters
/
Sources
/
SoundMonitor.c
< prev
next >
Wrap
Text File
|
1993-08-05
|
9KB
|
345 lines
/*
* ARTA VUMeters for Macintosh
* Malcolm Slaney
* Advanced Technology Group
* Apple Computer, Inc.
* malcolm@apple.com
* 1992-1993
*
* Warranty Information
* Even though Apple has reviewed this software, Apple makes no warranty
* or representation, either express or implied, with respect to this
* software, its quality, accuracy, merchantability, or fitness for a
* particular purpose. As a result, this software is provided "as is,"
* and you, its user, are assuming the entire risk as to its quality
* and accuracy.
*
* Copyright (c) 1992-1993 by Apple Computer, Inc
* All Rights Reserved.
*/
/* SoundMonitor.c */
#include <DSPConstants.h>
#include <DSPManager.h>
#include <StandardSound.h>
#include <Memory.h>
#include <StdLib.h>
#include "SoundMonitor.h"
pascal void DSPMonitorTaskHandler ();
/* SMOpenDSPSoundStream - Open a DSP sound stream. Return the stream
* that is used for the Standard Sound System.
*/
SoundStream SMOpenDSPSoundStream(){
SoundStream sound_stream;
StdSndGetIndexedStream (&sound_stream, kStdSndSystemStream);
return (sound_stream);
}
/* SMOpenDSP3210 - Open a DSP client. Given a sound stream, open
* the proper DSP device and return its parameter block. We'll need
* this parameter block later when we want to reference it.
*/
DSPCPUDeviceParamBlkPtr SMOpenDSP3210(sound_stream)
SoundStream sound_stream;
{
DSPCPUDeviceParamBlkPtr pblock;
OSErr err;
int i;
#ifdef DONTDO
#define UNIMPL_TRAP_NUM 0x9F
if (NGetTrapAddress(0xBF5, ToolTrap) ==
NGetTrapAddress(UNIMPL_TRAP_NUM, ToolTrap)){
DoAlert("\pCathedral Toolbox is not installed. Bye.");
exit(1);
}
#endif /* DONTDO */
/* Check manager version */
if (DSPManagerVersion () != kdspManagerBuildVersion)
return (NULL);
/* Allocate memory for
* parameter block record
*/
pblock = (DSPCPUDeviceParamBlkPtr)NewPtr(sizeof(DSPCPUDeviceParamBlk));
if (!pblock)
return (NULL);
/* Clear out parameter block
* so we don't have any surprises
*/
for (i = 0; i < sizeof(DSPCPUDeviceParamBlk); i++)
((char *) pblock)[i] = 0;
/* Get the cpu index for
* this particular stream
* and stuff it into parameter
* block.
*/
StdSndGetStreamCPUIndex(sound_stream, 0, &(pblock->pbhDeviceIndex));
/* Now get the proper DSP using
* using the manager.
*/
err = DSPGetIndexedCPUDevice(pblock);
if (err != noErr)
return (NULL);
/* Open DSP device */
pblock->pbhClientPermission = kdspReadPermission;
BlockMove("\pFrontEnd", pblock->pbhClientName, 32);
err = DSPOpenCPUDevice(pblock);
if (err != noErr)
return (NULL);
return (pblock);
}
/* SMCloseDSP3210 - Close the DSP client. When we're all done we close the
* the DSP and dispose of the parameter block.
*/
long SMCloseDSP3210(pblock)
DSPCPUDeviceParamBlkPtr pblock;
{
OSErr err;
long zerror = NO_ERROR;
if (pblock == NULL)
return (ERROR);
err = DSPCloseCPUDevice(pblock);
if (err != noErr)
zerror = ERROR;
DisposPtr((Ptr) pblock);
return (zerror);
}
/* SMCreateDSPMonitor - Create a sound monitor. This does the real
* work. Given a DSP device (indicated by the parameter block) and a
* type name we can define a DSP task and load the appropriate module.
* The type names are defined in the DSP code as NewModule(). Currently
* "\pMax" or "\pPower" are the only valid module types.
*
* Once we have the module loaded into a task we can attach it to the
* sound stream. We use the soundStream to get access to the left and
* right channels and we insert the new task at the location determined
* by the streamLocation parameter.
*/
DSPMonitor SMCreateDSPMonitor(dspParameterBlock, soundStream,
monitorType, streamLocation)
DSPCPUDeviceParamBlkPtr dspParameterBlock;
SoundStream soundStream;
StringPtr monitorType;
long streamLocation;
{
DSPMonitor monitor;
DSPModuleRefNum MonitorModule;
DSPSectionRefNum sectionLeft, sectionRight, section;
long patchPoint;
OSErr err;
/* alloc mem for monitor record */
monitor = (DSPMonitor) NewPtr(sizeof(DSPMonitorRec));
if (!monitor)
return (NULL);
monitor->taskRef = 0;
monitor->dspParms = 0;
monitor->typeName = 0;
monitor->streamLocation = streamLocation;
monitor->taskActive = 0;
/* Create new monitor task */
err = DSPNewTask (dspParameterBlock,
(MessageActionProc)DSPMonitorTaskHandler,
"\pDSPMonitorTask", &monitor->taskRef);
if (err != noErr)
return (NULL);
/* Load monitor module */
err = DSPLoadModule (monitorType, monitor->taskRef,
kdspAnyPositionInsert, 0,
&MonitorModule, 240);
if (err != noErr)
return (NULL);
/* Connect to standard sound. Figure
* out the AIAO buffers (sections) that
* correspond to the left and right
* channel. The DSP monitor which we
* created above has two input buffers
* that we want to connect to the
* standard sound buffers.
*/
StdSndGetStreamSections (soundStream, §ionLeft, §ionRight);
DSPGetSection (MonitorModule, "\pLeft", §ion);
err = DSPConnectSections(sectionLeft, section, kdspDirectConnection);
if (err != noErr)
return (NULL);
DSPGetSection (MonitorModule, "\pRight", §ion);
err = DSPConnectSections(sectionRight, section, kdspDirectConnection);
if (err != noErr)
return (NULL);
/* Insert into standard sound
* task list at either input
* or output. This determines whether
* this monitor will be monitoring the
* microphone input or the speaker
* output.
*/
if (streamLocation == SMMonitorInput)
patchPoint = kStdSndRecorder;
else
patchPoint = kStdSndPostProcessor;
err = StdSndInsertTask (soundStream, monitor->taskRef, patchPoint);
if (err != noErr)
return (NULL);
/* Get pointer to the DSP monitor
* parameters */
DSPGetSection(MonitorModule, "\pParams", §ion);
DSPGetSectionData (section, (Ptr *) &(monitor->dspParms));
/* set monitoring */
monitor->taskActive = FALSE;
return (monitor);
}
/*
* SMDestroyDSPMonitor - Destroy the DSP monitor task. When all done, remove
* and dispose the DSP task that monitors the sound stream.
*/
long SMDestroyDSPMonitor(monitor)
DSPMonitor monitor;
{
long zerror = NO_ERROR;
OSErr err;
if (monitor == NULL)
zerror = ERROR;
err = DSPRemoveTask (monitor->taskRef);
if (err != noErr)
zerror = ERROR;
err = DSPDisposeTask (monitor->taskRef);
if (err != noErr)
zerror = ERROR;
DisposPtr ((Ptr) monitor);
return (zerror);
}
/*
* SMStartDSPMonitor - Start a DSP task to monitor the sound.
*/
long SMStartDSPMonitor(monitor)
DSPMonitor monitor;
{
OSErr err;
err = DSPSetTaskActive (monitor->taskRef);
if (err != noErr)
return (ERROR);
monitor->taskActive = TRUE;
return (NO_ERROR);
}
/*
* SMStopDSPMonitor - Stop a DSP task that is monitoring the sound.
*/
long SMStopDSPMonitor(monitor)
DSPMonitor monitor;
{
OSErr err;
err = DSPSetTaskInactive (monitor->taskRef);
if (err != noErr)
return (ERROR);
monitor->taskActive = FALSE;
return (NO_ERROR);
}
long SMSetChannel(monitor, left, right)
DSPMonitor monitor;
enum SMSetChannelParm left, right;
{
struct DSPMonitorParmStruct *dspParms = monitor->dspParms;
/* set left and right monitoring */
switch (left){
case SMChannelOff: /* turn channel off */
dspParms->monitorLeft = FALSE;
break;
case SMChannelOn: /* turn channel on */
if (!(dspParms->monitorLeft))
dspParms->monitorLeft = TRUE;
break;
case SMChannelAddClient: /* add client to left monitor */
dspParms->monitorLeft += 1;
break;
case SMChannelRemoveClient: /* remove client from left monitor */
if (dspParms->monitorLeft)
dspParms->monitorLeft -= 1;
break;
default: /* SMChannelDontChange : don't
* change channel state */
break;
}
switch (right){
case SMChannelOff: /* turn channel off */
dspParms->monitorRight = FALSE;
break;
case SMChannelOn: /* turn channel on */
if (!(dspParms->monitorRight))
dspParms->monitorRight = TRUE;
break;
case SMChannelAddClient: /* add client to left monitor */
dspParms->monitorRight += 1;
break;
case SMChannelRemoveClient: /* remove client from left monitor */
if (dspParms->monitorRight)
dspParms->monitorRight -= 1;
break;
default: /* SMChannelDontChange: don't
* change channel state */
break;
}
/* do we need to activate or deactivate task? */
if ((dspParms->monitorLeft || dspParms->monitorRight) &&
(monitor->taskActive == FALSE))
return SMStartDSPMonitor(monitor);
if ((dspParms->monitorLeft == FALSE) &&
(dspParms->monitorRight == FALSE) &&
(monitor->taskActive == TRUE))
return SMStopDSPMonitor(monitor);
return (NO_ERROR);
}
static pascal void DSPMonitorTaskHandler(){
}
/* SoundMonitor.c */