awacs_hw.h   [plain text]


/*
 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * The contents of this file constitute Original Code as defined in and
 * are subject to the Apple Public Source License Version 1.1 (the
 * "License").  You may not use this file except in compliance with the
 * License.  Please obtain a copy of the License at
 * http://www.apple.com/publicsource and read it before using this file.
 * 
 * This Original Code and all software distributed under the License are
 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*
 *   AWACs - Audio Waveform Amplifier and Converter
 *
 *   Notes:
 *
 *   1. All values written to (or read from) hardware must be endian reversed
 *      when using the constants from this file.
 *   2. The hardware uses a serial-bus time multiplexed scheme to communicate
 *      with up to four addressable devices (subframes). AWACs currently only uses
 *      'SubFrame 0'.  When a register field refers to a  subframe, then the SubFrame0
 *      value  should be used.
 *   3. The CodecControlRegister is used to as a pointer/data reg to access four 12-bit
 *      registers. The kCodecCtlAddress* values indicate the 12-bit register to be
 *      written and the kCodecCtlDataMask indicates the 12-bits to be written.
 *      kCodecCtlBusy is set/cleared by hardware when a pending value waiting to be
 *      written to one of the 12-bit registers. kCodecCtlEMSelect* indicates which
 *      SubFrame the data will go out on. (See Note 2)
 *  4.  The SoundControlRegister is used to set the data rate and indicates the input,
 *      output and status subframes. (See Note 2).
 *  5.  The CodecStatusRegister indicate when there was an error, or a change of input
 *      or output sources, i.e. a mic, line, or headphones were plugged in.
 *  6.  The ClippingCountRegister  is incremented on a left/right channel overflow. It
 *      is reset by reading its contents.
 *
 */

// ----------------------------- AWACs register mapping structure -------------------------

typedef UInt32                          SndIOSubFrame;

#define		kCodecCtlOffset			0x0010

enum AwacsCodecCtrl {
	kCtlDataMask			=	0x00000FFF,	// CODEC control data bits
	kCtlAddrMask			=	0x003FF000,	// CODEC control address bits

	kCtlEMSel0				=	0x00000000,	// Select subframe 0
	kCtlEMSel1				=	0x00400000,	// Select subframe 1
	kCtlEMSel2				=	0x00800000,	// Select subframe 2
	kCtlEMSel3				=	0x00C00000,	// Select subframe 4

	kCtlBusy				=	0x01000000	// AWACS busy bit
};

enum {
  kSndIOInputSubFrame0          = 0x0001, // Four available input subframes on SndIO
  kSndIOInputSubFrame1          = 0x0002,
  kSndIOInputSubFrame2          = 0x0004,
  kSndIOInputSubFrame3          = 0x0008,
  kSndIOOutputSubFrame0         = 0x0100, // Four available output subframes on SndIO
  kSndIOOutputSubFrame1         = 0x0200,
  kSndIOOutputSubFrame2         = 0x0400,
  kSndIOOutputSubFrame3         = 0x0800,
  kSndIOInputSubFrameMask       = 0x00FF,
  kSndIOOutputSubFrameMask      = 0xFF00,
  kSndIONumSubFrames            = 0x04
};

struct awacs_regmap_t
{
        volatile u_int32_t		       	SoundControlRegister;
        u_int32_t	       		       	pad0[3];
        volatile u_int32_t		       	CodecControlRegister;
        u_int32_t	       				pad1[3];
        volatile u_int32_t	       		CodecStatusRegister;
        u_int32_t	               		pad2[3];
        volatile u_int32_t	       		ClippingCountRegister;
        u_int32_t	       				pad3[3];
        volatile u_int32_t	       		ByteSwappingRegister;
};

// Power state constants 
enum {
  kSndHWRunState                = 0,    // SndHW in the run state
  kSndHWDozeState               = 1,    // SndHW in the doze state
  kSndHWIdleState               = 2,    // SndHW in the idle state
  kSndHWSleepState              = 3,    // SndHW in the sleep state
  kSndHWNotReadyState           = 4,    // SndHW not ready (either in reset or wait state)
  kSndHWResetState              = 5,    // SndHW reset (not a valid state to stay in)
  kSndHWPartDead                = 6,    // SndHW is dead (can't get it out of reset)
  kSndHWInsomniaState           = 7,
  kSndHWWakeSubwoofer           = 8,
  kSndHWEnterSpeedSwitch        = 9,
  kSndHWExitSpeedSwitch         = 10
};

// ------------------------ AWACs CODEC Control register constants -----------------------

enum AWACsCODEC_ControlRegisterGeneralConstants
{
        kCodecCtlDataMask	=	0x00000FFF,	    // CODEC control data bits

        kCodecCtlAddress0	=	0x00000000,		// Select address 0
        kCodecCtlAddress1	=	0x00001000,		// Select address 1
        kCodecCtlAddress2	=	0x00002000,		// Select address 2
        kCodecCtlAddress4	=	0x00004000,		// Select address 4
        kCodecCtlAddress5	=	0x00005000,		// Select address 5 - Screamer only
        kCodecCtlAddress6	=	0x00006000,		// Select address 6 - Screamer only
        kCodecCtlAddress7	=	0x00007000,		// Select address 7 - Screamer only

        kCodecCtlEMSelect0	=	0x00000000,		// Select subframe 0
        kCodecCtlEMSelect1	=	0x00400000,		// Select subframe 1
        kCodecCtlEMSelect2	=	0x00800000,		// Select subframe 2
        kCodecCtlEMSelect4	=	0x00C00000,		// Select subframe 4

        kCodecCtlBusy		=	0x01000000 		// AWACS busy bit
};

enum AWACsCODEC_ControlRegister0Constants
{
        kLeftInputGainMask		=	0x000000F0,	// Bits used for left input gain
        kLeftInputGainShift		=	4,
        kRightInputGainMask		=	0x0000000F,	// Bits used for right input gain
        kRightInputGainShift	=	0,

        kDefaultMicGain			=	0x000000CC,	// Default right & left gain for a mic
        kDefaultCDGain			=	0x000000BB,	// Default right & left gain for a CD

        kNotMicPreamp			=	0x00000100,	// Select preamp on or off

        kInputMuxMask			=	0x00000E00,	// Bits used to set which input to use
        kCDInput		       	=	0x00000200,	// Bit 9 = CD ROM audio input
        kMicInput		       	=	0x00000400,	// Bit 10 = external mic input
        kUnusedInput			=	0x00000800,	// Bit 11 = unused input
        kInitialAwacsR0Value    =	0x00000000	// Initial value set on boot
};


enum AWACsCODEC_ControlRegister1Constants
{
        kReservedR1Bit0			=	0x00000001,	// Reserved - always set to zero
        kReservedR1Bit1			=	0x00000002,	// Reserved - always set to zero
        kRecalibrate			=	0x00000004,	// Recalibrate AWACs
        kExtraSampleRateMask    =	0x00000038,	// !!!Do these bits do anything???
        kLoopThruEnable			=	0x00000040,	// Loop thru enable
        kMuteInternalSpeaker	=	0x00000080,	// Internal speaker mute
        kReservedR1Bit8			=	0x00000100,	// Reserved - always set to zero
        kMuteHeadphone			=	0x00000200,	// Headphone mute
        kOutputZero				=	0x00000400,
        kOutputOne				=	0x00000800,	// Sometimes speaker enable
        kParallelOutputEnable	=	0x00000C00,	// Parallel output port
        kInitialAwacsR1Value    =	0x00000000	// Initial value set on boot
};


enum AWACsCODEC_ControlRegister2Constants
{
        kRightHeadphoneAttenMask	=	0x0000000F,	// Attenuation for right headphone speaker
        kRightHeadphoneAttenShift	=	0,		// Bit shift from LSB position
        kReservedR2Bit4				=	0x00000010,	// Reserved - always set to zero
        kReservedR2Bit5				=	0x00000020,	// Reserved - always set to zero
        kLeftHeadphoneAttenMask 	=	0x000003C0,	// Attenuation for left headphone speaker
        kLeftHeadphoneAttenShift	=	6,		// Bit shift from LSB position
        kReservedR2Bit10			=	0x00000400,	// Reserved - always set to zero
        kReservedR2Bit11			=	0x00000800,	// Reserved - always set to zero
        kHeadphoneAttenMask			=	(kRightHeadphoneAttenMask | kLeftHeadphoneAttenMask),
        kInitialAwacsR2Value	    =	0x00000000	// Initial value set on boot
};


enum AWACsCODEC_ControlRegister4Constants
{
        kRightSpeakerAttenMask		=	0x0000000F,	// Attenuation for right internal speaker
        kRightSpeakerAttenShift		=	0,	       	// Bit shift from LSB position
        kReservedR4Bit4				=	0x00000010,	// Reserved - always set to zero
        kReservedR4Bit5				=	0x00000020,	// Reserved - always set to zero
        kLeftSpeakerAttenMask		=	0x000003C0,	// Attenuation for left internal speaker
        kLeftSpeakerAttenShift		=	6,	       	// Bit shift from LSB position
        kReservedR4Bit10			=	0x00000400,	// Reserved - always set to zero
        kReservedR4Bit11			=	0x00000800,	// Reserved - always set to zero
        kSpeakerAttenMask			=	(kRightSpeakerAttenMask | kLeftSpeakerAttenMask),
        kInitialAwacsR4Value		=	0x00000000	// Initial value set on boot
};

// ---------------------- Screamer Extensions ----------------------------------------

enum AWACsVersions
{
        kAWACSMaxVersion			=	2
};

enum AWACsCODEC_ControlRegister5Constants
{
        kRightLoopThruAttenMask		=	0x0000000F,
        kRightLoopThruAttenShift	=	0,
        kLeftLoopThruAttenMask		=	0x000003C0,
        kLeftLoopThruAttenShift     =   6
};

enum AWACsCODEC_ControlRegister6Constants
{
        kPowerModeDoze				=	0x00000001,
        kPowerModeIdle				= 	0x00000002,
        kMicPreampBoostEnable		=	0x00000004,
        kPCMCIASpeakerAttenMask		=   0x00000038,
        kPowerModeAnalogShutdown	=   0x00000040,
        kLittleDischarge			=   0x00000080,
        kBigDischarge  				=   0x00000100
};

enum AWACsCODEC_ControlRegister7Constants
{
        kReadBackEnable				= 	0x00000001,
        kReadBackRegisterMask		= 	0x0000000E,
        kReadBackRegisterShift		=	1
};

// ----------------- AWACs CODEC Status Register constants -------------------------------

enum AWACsCODEC_StatusRegisterConstants
{
        kNotMicSense	        	=	0x00000001,	// This bit is 0 when a mic(input) is plugged in
        kNotMicShift				=	0,
        kLineInSense	          	=	0x00000002,	// This bit is 1, when a line(input) is pluggen in
        kLineInShft					=	1,
        kAux1Sense					=   0x00000004,     // This bit is 1, when something is plugged into the Whisper line-out
        kAux1Shft					=	2,
        kHeadphoneSense	        	=	0x00000008,	// This bit is 1 when headphone is plugged in
        kHeadphoneShft				=	3,
        kAllSense					= 	0x0000000F,
        kManufacturerIDMask	        =	0x00000F00,	// AWACS chip manufacturer ID bits
        kManufacturerIDShft	        =	8,	       	// Bits to shift right to get ID in LSB position
        kRevisionNumberMask	        =	0x0000F000,	// AWACS chip revision bits
        kRevisionNumberShft     	=	12,	       	// Bits to shift right to get rev in LSB position
        kAwacsErrorStatus	      	=	0x000F0000,	// AWACS error status bits
        kOverflowRight              =   0x00100000,
        kOverflowLeft               =   0x00200000,
        kValidData                  =   0x00400000,
        kExtend                     =   0x00800000
};

// --------------------- AWACs Sound Control register ------------------------------------

enum AWACsSoundControlRegisterConstants
{
        kInSubFrameMask			=	0x0000000F,	// All of the input subframe bits
        kInSubFrame0			=	0x00000001,	// Input subframe 0
        kInSubFrame1			=	0x00000002,	// Input subframe 1
        kInSubFrame2			=	0x00000004,	// Input subframe 2
        kInSubFrame3			=	0x00000008,	// Input subframe 3

        kOutSubFrameMask		= 	0x000000F0, 	// All of the output subframe bits
        kOutSubFrame0			=	0x00000010,	// Output subframe 0
        kOutSubFrame1			=	0x00000020,	// Output subframe 1
        kOutSubFrame2			=	0x00000040,	// Output subframe 2
        kOutSubFrame3			=	0x00000080, 	// Output subframe 3

        kHWRateMask	       		=	0x00000700,	// All of the hardware sampling rate bits
        kHWRate44100			=	0x00000000,	// Hardware sampling bits for 44100 Hz
        kHWRate29400			=	0x00000100,	// Hardware sampling bits for 29400 Hz
        kHWRate22050			=	0x00000200,	// Hardware sampling bits for 22050 Hz
        kHWRate17640			=	0x00000300,	// Hardware sampling bits for 17640 Hz
        kHWRate14700			=	0x00000400,	// Hardware sampling bits for 14700 Hz
        kHWRate11025			=	0x00000500,	// Hardware sampling bits for 11025 Hz
        kHWRate08820			=	0x00000600,	// Hardware sampling bits for  8820 Hz
        kHWRate07350			=	0x00000700,	// Hardware sampling bits for  7350 Hz

        kHWRateShift            =   8,

        kAWACSError	       	 	=	0x00000800,	// AWACs error indicator
        kPortChange	       	 	=	0x00001000,	// Port change indicator
        kEnableErrInt		 	=	0x00002000,	// Interrupt on error enable
        kEnablePortChangeInt 	=	0x00004000,	// Interrupt on port change enable

        kStatusSubFrmSel0	 	=	0x00000000,	// Select subframe zero  status
        kStatusSubFrmSel1 	 	=	0x00008000,	// Select subframe one   status
        kStatusSubFrmSel2 	 	=	0x00010000,	// Select subframe twoo  status
        kStatusSubFrmSel3 	 	=	0x00018000	// Select subframe three status
};

// --------------------- AWACs Clipping Count register ------------------------------------

enum AWACsClippingCountRegisterConstants
{
       kRightClippingCount      = 	0x000000FF,
       kLeftClippingCount       =	0x0000FF00
};


// -------------------- Awacs definition from the OS 9 version ---------------------------
enum {
	kAWACsInputReg				=	0x00000000,		// register for input port selection
	kAWACsInputA				= 	0x00000800,		// input A enable and mask
	kAWACsInputB				=	0x00000400,		// input B enable and mask
	kAWACsInputC				=	0x00000200,		// input C enable and mask
	kAWACsInputField			=	kAWACsInputA | kAWACsInputB | kAWACsInputC,	// mask to get the entire input mux field
	
	kAWACsPreampBReg			=	0x00000000,		// register for input B preamp
	kAWACsPreampB				=	0x00000100,		// input B preamp enable and mask

	kAWACsGainReg				=	0x00000000,		// register for gain settings
	kAWACsGainLeft				=	0x000000F0, 		// mask to get left gain
	kAWACsGainLeftShift			=	0x00000004,		// shift for left gain
	kAWACsGainRight				=	0x0000000F,		// mask to get right gain
	kAWACsGainField				=	kAWACsGainLeft | kAWACsGainRight,	// mask to get the entire gain field

	kAWACsProgOutputReg			=	0x00000001,		// register for programmable output settings
	kAWACsOutputZero			=	0x00000400,		// hit output zero
	kAWACsOutputOne				=	0x00000800,		// hit output one
	kAWACsProgOutputField		=	kAWACsOutputZero | kAWACsOutputOne,	// mask to get the entire programmable output field
	kAWACsProgOutputShift		=	10,			// shift for programmable output bits
	
	kAWACsMuteReg				=	0x00000001,		// register for muting outputs
	kAWACsMuteOutputA			=	0x00000200,		// mute output A
	kAWACsMuteOutputC			=	0x00000080,		// mute output C
	kAWACsMuteField				=	kAWACsMuteOutputA | kAWACsMuteOutputC,	// mask to get the entire mute field
	
	kAWACsLoopThruReg			=	0x00000001,		// register for setting loop-through
	kAWACsLoopThruEnable		=	0x00000040,		// enable loop-through mode (playthrough)
	
	kAWACsRecalibrateReg		=	0x00000001,		// register to force a recalibration
	kAWACsRecalibrate			=	0x00000004,		// recalibrate
	
	kAWACsOutputAAttenReg		=	0x00000002,		// register for output A attenuation
	kAWACsOutputCAttenReg		=	0x00000004,		// register for output A attenuation	
	kAWACsOutputLeftAtten		=	0x000003C0,		// output left attenuation
	kAWACsOutputLeftShift		=	0x00000006,		// shift for left attenuation
	kAWACsOutputRightAtten		=	0x0000000F,		// output right attenuation
	kAWACsOutputAttenField		=	kAWACsOutputLeftAtten | kAWACsOutputRightAtten,	// mask to get entire output attenuation field
	
	kAWACsPlayThruAttenReg		=	0x00000005,		// playthrough attenuation register (not used in meaningful way)
	
	kAWACsPowerReg				=	0x00000006,		// register for power handling
	kAWACsSettlingTimeField		=	0x00000180,		// settling time bits
	kAWACsSettlingTimeLong		=	0x00000100,		// big discharge bit
	kAWACsSettlingTimeShort		=	0x00000080,		// little discharge bit
	kAWACsAnalogShutdown		=	0x00000040,		// analog shutdown bit
	
	kAWACsPCMCIAAttenReg		=	0x00000006,		// register for PCMCIA volume
	kAWACsPCMCIAAttenField		=	0x00000038,		// the entire field
	kAWACsPCMCIAOn				=	0x00000008,		// PCMCIA on
	kAWACsPCMCIAOff				=	0x00000000,		// PCMCIA off
	
	kAWACsPreampAReg			=	0x00000006,		// register for input A preamp
	kAWACsPreampA				= 	0x00000004,		// input A preamp enable and mask
	
	kAWACsPowerStateField		=	0x00000003,		// state bits on Screamer
	kAWACsPowerStateIdle		=	0x00000002,		// Screamer idle bit
	kAWACsPowerStateDoze		=	0x00000001,		// Screamer doze bit
	kAWACsPowerStateRun			=	0x00000000,		// Screamer run setting
	
	kAWACsMinHardwareGain		=	0,
	kAWACsMaxHardwareGain		=	15,
	kAWACsMaxHardwareGainPreAmp	=	31,
	kAWACsHWdBStepSize			=	0x00018000,		// Fixed 1.5
	
	kAWACsMinVolume				=	15,
	kAWACsInvalidVolumeMask		=	0xFE00FE00,
	kAWACsMaxVolumeA			=	2,
	kAWACsMaxVolumeC			=	0
};

// AWACS CODEC control register general equates
enum AwacsSndHWCtrl {
	kAWACsCtlAddressMask		=		0x003FF000,	// Mask off the address field of the control register
	kAWACsCtlAddressShift		=		12,		// Shift to place address in address field

	kAWACsReadbackRegister		=		7,		// register to do hardware readback
	kAWACsReadbackRegAddrMask	=		0x0000000E,	// mask to isolate the readback register address
	kAWACsReadbackRegAddrShift	=		1,		// shift to place address in proper field
	kAWACsReadbackEnable		=		0x00000001,	// set/clear readback enable
	kAWACsReadbackMask			=		0x0000000F,	// mask to isolate the readback register address and enable bits
	kAWACsReadbackDataShift		=		4,		// shift to place return in the right place
	kAWACsReadbackDataMask		=		0x00000FFF	// mask to isolate the nibbles of the returned data
};

// AWACS CODEC status register equates
enum AwacsSndHWStatus {
	kAWACsManufacturerIDMask	=	0x00000F00,		// AWACS chip manufacturer ID bits
	kAWACsManfCrystal			=	0x00000100,		// crystal part
	kAWACsManfNational			=	0x00000200,		// national part
	kAWACsManfTI				=	0x00000300,		// texas instruments part
	
	kAWACsRevisionNumberMask	=	0x0000F000,			// AWACS chip revision bits
	kAWACsRevisionShift			=	12,			// Shift to get the version number
	kAWACsValidData				=	0x00400000,		// AWACS has valid data
	kAWACsRecalTimeOut			=	1000,			// Number of milliseconds to wait before timing out a recalibrate

	kAWACsStatusMask			=	0x00FFFFFF,		// AWACS chip status bits
        kAWACsStatusInSenseMask	=	0x0000000F,
	kAWACsAwacsRevision			=	2,			// AWACs revision
	kAWACsScreamerRevision		=	3,			// Screamer revision
	
	kAWACsInSenseMask			=	0x0000000F,		// mask for status bits
	kAWACsInSense0				=	0x00000008,		// in sense bit 0
	kAWACsInSense1				=	0x00000004,		// in sense bit 1
	kAWACsInSense2				=	0x00000002,		// in sense bit 2
	kAWACsInSense3				=	0x00000001,		// in sense bit 3

	// screamer specific hardware bit states
	kScreamerRunState1			=	0,			// idle and doze clear, run state one
	kScreamerRunState2			=	3,			// idle and doze set, run state two
	kScreamerDozeState			=	1,			// hardware doze bit set
	kScreamerIdleState			=	2,			// hardware idle bit set
	kScreamerStateField			=	3			// field containing state bits
};


enum GeneralHardware {
	kSampleRatesCount			=	3,

	kMaxPCMCIAVolume			=	7,
	kMinPCMCIAVolume			=	0,

	kInvalidGainMask			= 	0xFFFE0000,	// mask to check gain settings against
	kMinSoftwareGain			=	0x8000,		// 0.5 setting for the software API
	kMaxSoftwareGain			=	0x18000,	// 1.5 setting for the software API
	kUnitySoftwareGain			=	0x10000,	// 1.0 setting for the software API
	kUnitySoftwareBass			=	0x10000,	// 1.0 setting for the software API
	kUnitySoftwareTreble		=	0x10000,		// 1.0 setting for the software API

	kMaxSndHWRegisters			= 	8,		// Number of registers in sndHW (8 in Screamer)
	kInvalidRegNumber			=	3,		// register 3 is not a valid register to read or write
	
	kMaxAsyncEvents				=	384,		// most async events that we allow
	kAsyncEventDelay			=	1,		// delay event, data2 = delay time
	kAsyncEventSetReg			=	2,		// set register contents, data1 = async, data2 = contents to write
	kAsyncEventWaitReady		=	3,		// wait for sound hardware ready, data2 = number of milliseconds to try
	kAsyncEventWaitIdle			=	4,		// wait for idle hardware, data2 = number of milliseconds to try
	kAsyncEventWakeDMA			=	5,		// call SndHWDMAWakeUp, no params
	kAsyncEventCallback			=	6,		// perform a callback, data2 = refCon1, data3 = refCon2, data4 = SndHWAsyncCallbackUPP
	
	kByteMask					=	0x00FF,		// mask to get a byte
	kAsyncWaitTime				=	1,		// number of milliseconds allowed for async
	kMicroPerMilli				=	1000,		// number of micro whatevers in one milli whatever
		
	kMaxHWAtten					=	0xF,		// maximum attenuation on the hardware
	kNumVolumeSteps				=	16,		// 16 volume steps on the hardware
	kMaxHWAttenLR				=	0x3CF,		// maximum hardware attenuation for both channels
	kMinHWGain					=	0,		// minimum hardware gain
	kPreRecalDelayCrystal		=	750,		// number of milliseconds to delay before setting recalibrate with a Crystal part 'cause it's broken
	kPreRecalDelayNational		=	0,		// number of milliseconds to delay before setting recalibrate with a National part 'cause it's not broken
	kRecalibrateDelay			=	2,		// number of milliseconds to delay after setting recalibrate
	kRampDelayCrystal			=	10,		// number of milliseconds to delay after each step of the attenuation ramp
	kRampDelayNational			=	0,		// number of milliseconds to delay after each step of the attenuation ramp

	kIdleRunDelay				=	5,	// idle <-> run transition delay milliseconds i
	kIdleDozeDelay				=	5,	// idle <-> doze transition delay milliseconds
	kDozeRunDelay				=	0		// doze <-> run transition delay milliseconds (the spec says 5ms, but that's audible - keep it at zero and it works OK but is no longer audible)
};


//some constants
#define kScreamerSampleLatency		32
#define	kScreamerAttenStep			1.5
#define kScreamerMaxVolume			0.0
#define kScreamerMinVolume			-22.5
#define kScreamerVolumeRange		(kScreamerMaxVolume - kScreamerMinVolume)
#define	kMAX_SW_VOL					256.0