initial commit from files downloaded at:

http://www.echoaudio.com/Download/Developer/developer.htm
please see the enclosed open-source license. (MIT variant)


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1286 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty 2002-09-29 11:00:20 +00:00
parent 348ee26939
commit 3895766d9c
88 changed files with 80106 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,664 @@
// ****************************************************************************
//
// CChannelMask.cpp
//
// Implementation file for the CChannelMask class.
//
// CChannelMask is a handy way to specify a group of pipes simultaneously.
// It should really be called "CPipeMask", but the class name predates
// the term "pipe".
//
// Since these masks are sometimes passed to the DSP, they must be kept in
// little-endian format; the class does this for you.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
/****************************************************************************
CChannelMask
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CChannelMask::CChannelMask()
{
Clear();
} // CChannelMask::CChannelMask()
//===========================================================================
//
// SetMask, SetOutMask, and SetInMask all allow you to just set
// the masks directly.
//
//===========================================================================
void CChannelMask::SetMask( CH_MASK OutMask, CH_MASK InMask, int nOutputs )
{
m_MaskRegs[ 0 ] = SWAP( OutMask );
m_MaskRegs[ 0 ] |= SWAP( (CH_MASK) ( InMask << nOutputs ) );
m_MaskRegs[ 1 ] = SWAP( (CH_MASK) ( InMask >> ( CH_MASK_BITS - nOutputs ) ) );
} // void CChannelMask::SetMask( ... )
void CChannelMask::SetOutMask( CH_MASK OutMask, int nOutputs )
{
m_MaskRegs[ 0 ] &= SWAP( (CH_MASK) ( (CH_MASK) -1 << nOutputs ) );
m_MaskRegs[ 0 ] |= SWAP( OutMask );
} // void CChannelMask::SetOutMask( CH_MASK OutMask, int nOutputs )
void CChannelMask::SetInMask( CH_MASK InMask, int nOutputs )
{
m_MaskRegs[ 0 ] &= SWAP( (CH_MASK) (~( (CH_MASK) -1 << nOutputs ) ) );
m_MaskRegs[ 0 ] |= SWAP( (CH_MASK) ( InMask << nOutputs ) );
m_MaskRegs[ 1 ] = SWAP( (CH_MASK) ( InMask >> ( CH_MASK_BITS - nOutputs ) ) );
} // void CChannelMask::SetInMask( CH_MASK InMask, int nOutputs )
//===========================================================================
//
// Retrieve an output bit mask and an input bitmask.
//
//===========================================================================
void CChannelMask::GetMask( CH_MASK & OutMask, CH_MASK & InMask, int nOutputs )
{
OutMask = GetOutMask( nOutputs );
InMask = GetInMask( nOutputs );
} // void CChannelMask::GetMask( ... )
CH_MASK CChannelMask::GetOutMask( int nOutputs )
{
return SWAP( m_MaskRegs[ 0 ] ) & ~( (CH_MASK) -1 << nOutputs );
} // CH_MASK CChannelMask::GetOutMask( int nOutputs )
CH_MASK CChannelMask::GetInMask( int nOutputs )
{
return ( SWAP( m_MaskRegs[ 0 ] ) >> nOutputs ) |
( SWAP( m_MaskRegs[ 1 ] ) << ( CH_MASK_BITS - nOutputs ) );
} // CH_MASK CChannelMask::GetIntMask( int nOutputs )
//===========================================================================
//
// IsEmpty returns TRUE if mask has no bits set
//
//===========================================================================
BOOL CChannelMask::IsEmpty()
{
int i;
for ( i = 0; i < CH_MASK_SZ; i++ )
if ( 0 != m_MaskRegs[ i ] )
return FALSE;
return TRUE;
} // void CChannelMask::IsEmpty()
//===========================================================================
//
// Call SetIndexInMask and ClearIndexInMask to set or clear a single bit.
//
//===========================================================================
// Set driver channel index into DSP mask format
void CChannelMask::SetIndexInMask( WORD wPipeIndex )
{
m_MaskRegs[ wPipeIndex / CH_MASK_BITS ] |=
SWAP( (CH_MASK) (( (CH_MASK) 1 ) << ( wPipeIndex % CH_MASK_BITS ) ) );
} // void CChannelMask::SetIndexInMask( WORD wPipeIndex )
// Clear driver channel index into DSP mask format
void CChannelMask::ClearIndexInMask( WORD wPipeIndex )
{
m_MaskRegs[ wPipeIndex / CH_MASK_BITS ] &=
SWAP( (CH_MASK)(~( ( (CH_MASK) 1 ) << ( wPipeIndex % CH_MASK_BITS ) ) ) );
} // void CChannelMask::ClearIndexInMask( WORD wPipeIndex )
//===========================================================================
//
// Use GetIndexFromMask to search the mask for bits that are set.
//
// The search starts at the bit specified by wStartPipeIndex and returns
// the pipe index for the first non-zero bit found.
//
// Returns ECHO_INVALID_CHANNEL if none are found.
//
//===========================================================================
WORD CChannelMask::GetIndexFromMask( WORD wStartPipeIndex )
{
WORD wIndex = wStartPipeIndex % CH_MASK_BITS;
WORD wCt = wStartPipeIndex / CH_MASK_BITS;
CH_MASK Mask;
for ( ; wCt < CH_MASK_SZ; wCt++ )
{
Mask = SWAP( m_MaskRegs[ wCt ] );
if ( 0 != Mask )
{
while( !( Mask & (1<<wIndex) ) &&
wIndex < CH_MASK_BITS )
wIndex++;
if ( wIndex < CH_MASK_BITS )
return( wIndex + ( wCt * CH_MASK_BITS ) );
}
wIndex = 0;
}
return( (WORD) ECHO_INVALID_CHANNEL );
} // WORD CChannelMask::GetIndexFromMask( WORD wStartIndex )
//===========================================================================
//
// Returns TRUE if the bit specified by the pipe index is set.
//
//===========================================================================
BOOL CChannelMask::TestIndexInMask( WORD wPipeIndex )
{
if ( SWAP( m_MaskRegs[ wPipeIndex / CH_MASK_BITS ] ) &
(CH_MASK)( ( (CH_MASK) 1 ) << ( wPipeIndex % CH_MASK_BITS ) )
)
return TRUE;
return FALSE;
} // BOOL CChannelMask::TestIndexInMask( WORD wPipeIndex )
//===========================================================================
//
// Clear bits in this mask that are in SrcMask - this is just like
// operator -=, below.
//
//===========================================================================
void CChannelMask::ClearMask( CChannelMask SrcMask )
{
int i;
for ( i = 0; i < CH_MASK_SZ; i++ )
{
m_MaskRegs[ i ] &= ~SrcMask.m_MaskRegs[ i ];
}
} // void CChannelMask::ClearMask( CChannelMask SrcMask )
//===========================================================================
//
// Clear all channels in this mask
//
//===========================================================================
void CChannelMask::Clear()
{
int i;
for ( i = 0; i < CH_MASK_SZ; i++ )
m_MaskRegs[ i ] = 0;
} // void CChannelMask::Clear()
//===========================================================================
//
// operator += Add channels in source mask to this mask
//
//===========================================================================
VOID CChannelMask::operator += (CONST CChannelMask & RVal)
{
int i;
for ( i = 0; i < CH_MASK_SZ; i++ )
m_MaskRegs[ i ] |= RVal.m_MaskRegs[ i ];
} // VOID operator += (CONST CChannelMask & RVal)
//===========================================================================
//
// operator -= Remove channels in source mask from this mask
//
//===========================================================================
VOID CChannelMask::operator -= (CONST CChannelMask & RVal)
{
int i;
for ( i = 0; i < CH_MASK_SZ; i++ )
m_MaskRegs[ i ] &= ~RVal.m_MaskRegs[ i ];
} // VOID operator -= (CONST CChannelMask & RVal)
//===========================================================================
//
// Test returns TRUE if any bits in source mask are set in this mask
//
//===========================================================================
BOOL CChannelMask::Test( PCChannelMask pSrcMask )
{
int i;
for ( i = 0; i < CH_MASK_SZ; i++ )
if ( m_MaskRegs[ i ] & pSrcMask->m_MaskRegs[ i ] )
return TRUE;
return FALSE;
} // BOOL CChannelMask::Test( PChannelMask pSrcMask )
//===========================================================================
//
// IsSubsetOf returns TRUE if all of the channels in TstMask are set in
// m_MaskRegs.
//
// Use to be sure all channels in this instance exist in
// another instance.
//
//===========================================================================
BOOL CChannelMask::IsSubsetOf
(
CChannelMask& TstMask
)
{
for ( int i = 0; i < CH_MASK_SZ; i++ )
{
CH_MASK ThisMask;
ThisMask = SWAP( m_MaskRegs[ i ]);
if ( ( ThisMask & TstMask[ i ] ) != ThisMask )
return FALSE;
}
return TRUE;
} // BOOL CChannelMask::IsSubsetOf
//===========================================================================
//
// IsIntersectionOf returns TRUE if TstMask contains at least one of the
// channels enabled in this instance.
//
// Use this to find out if any channels in this instance exist in
// another instance.
//
//===========================================================================
BOOL CChannelMask::IsIntersectionOf
(
CChannelMask& TstMask
)
{
for ( int i = 0; i < CH_MASK_SZ; i++ )
if ( 0 != ( m_MaskRegs[ i ] & TstMask[ i ] ) )
return TRUE;
return FALSE;
} // BOOL CChannelMask::IsIntersectionOf
//===========================================================================
//
// Operator == is just what you'd expect - it tells you if one mask is
// the same as another
//
//===========================================================================
BOOLEAN operator == ( CONST CChannelMask &LVal, CONST CChannelMask &RVal )
{
for ( int i = 0; i < CH_MASK_SZ; i++ )
if ( LVal.m_MaskRegs[ i ] != RVal.m_MaskRegs[ i ] )
return FALSE;
return TRUE;
} // BOOLEAN operator == ( CONST CChannelMask &LVal, CONST CChannelMask &RVal )
//===========================================================================
//
// Operator = just copies from one mask to another.
//
//===========================================================================
CChannelMask& CChannelMask::operator =(CONST CChannelMask & RVal)
{
if ( &RVal == this )
return *this;
for ( int i = 0; i < CH_MASK_SZ; i++ )
m_MaskRegs[ i ] = RVal.m_MaskRegs[ i ];
return *this;
} // CChannelMask& CChannelMask::operator = (CONTS CChannelMask & RVal)
CChannelMask& CChannelMask::operator =(CONST CChMaskDsp & RVal)
{
CH_MASK * pMask = (CH_MASK *) &RVal.m_MaskRegs[ 0 ];
m_MaskRegs[ 0 ] = *pMask;
m_MaskRegs[ 1 ] = 0;
return *this;
} // CChannelMask& CChannelMask::operator =(CONST CChMaskDsp & RVal)
//===========================================================================
//
// Operator & performs a bitwise logical AND
//
//===========================================================================
VOID CChannelMask::operator &= (CONST CChannelMask & RVal)
{
if ( &RVal == this )
return;
for ( int i = 0; i < CH_MASK_SZ; i++ )
m_MaskRegs[ i ] &= RVal.m_MaskRegs[ i ];
} // VOID CChannelMask::operator &= (CONST CChannelMask & RVal)
//===========================================================================
//
// Operator & performs a bitwise logical OR
//
//===========================================================================
VOID CChannelMask::operator |= (CONST CChannelMask & RVal)
{
if ( &RVal == this )
return;
for ( int i = 0; i < CH_MASK_SZ; i++ )
m_MaskRegs[ i ] |= RVal.m_MaskRegs[ i ];
} // VOID CChannelMask::operator |= (CONST CChannelMask & RVal)
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CChannelMask::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CChannelMask::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CChannelMask::operator new( size_t Size )
VOID CChannelMask::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("CChannelMask::operator delete memory free failed\n"));
}
} // VOID CChannelMask::operator delete( PVOID pVoid )
/****************************************************************************
CChMaskDsp
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CChMaskDsp::CChMaskDsp()
{
Clear();
} // CChMaskDsp::CChMaskDsp()
//===========================================================================
//
// IsEmpty returns TRUE if mask has no bits set
//
//===========================================================================
BOOL CChMaskDsp::IsEmpty()
{
int i;
for ( i = 0; i < CH_MASK_SZ; i++ )
if ( 0 != m_MaskRegs[ i ] )
return FALSE;
return TRUE;
} // void CChMaskDsp::IsEmpty()
//===========================================================================
//
// Call SetIndexInMask and ClearIndexInMask to set or clear a single bit.
//
//===========================================================================
// Set driver channel index into DSP mask format
void CChMaskDsp::SetIndexInMask( WORD wPipeIndex )
{
m_MaskRegs[ wPipeIndex / CH_MASK_DSP_BITS ] |=
SWAP( (CH_MASK_DSP)(( (CH_MASK_DSP) 1 ) << ( wPipeIndex % CH_MASK_DSP_BITS ) ) );
} // void CChMaskDsp::SetIndexInMask( WORD wPipeIndex )
// Clear driver channel index into DSP mask format
void CChMaskDsp::ClearIndexInMask( WORD wPipeIndex )
{
m_MaskRegs[ wPipeIndex / CH_MASK_DSP_BITS ] &=
SWAP( (CH_MASK_DSP)(~( ( (CH_MASK_DSP) 1 ) << ( wPipeIndex % CH_MASK_DSP_BITS ) ) ) );
} // void CChMaskDsp::SetIndexInMask( WORD wPipeIndex )
//===========================================================================
//
// Returns TRUE if the bit specified by the pipe index is set.
//
//===========================================================================
BOOL CChMaskDsp::TestIndexInMask( WORD wPipeIndex )
{
if ( m_MaskRegs[ wPipeIndex / CH_MASK_DSP_BITS ] &
SWAP( (CH_MASK_DSP)( ( (CH_MASK_DSP) 1 ) << ( wPipeIndex % CH_MASK_DSP_BITS ) ) ) )
return TRUE;
return FALSE;
} // BOOL CChMaskDsp::TestIndexInMask( WORD wPipeIndex )
//===========================================================================
//
// Clear all channels in this mask
//
//===========================================================================
void CChMaskDsp::Clear()
{
int i;
for ( i = 0; i < CH_MASK_SZ; i++ )
m_MaskRegs[ i ] = 0;
} // void CChMaskDsp::Clear()
//===========================================================================
//
// operator += Add channels in source mask to this mask
//
//===========================================================================
VOID CChMaskDsp::operator += (CONST CChannelMask & RVal)
{
CH_MASK * pMask = (CH_MASK *) &m_MaskRegs[ 0 ];
*pMask |= RVal.m_MaskRegs[ 0 ];
} // VOID operator += (CONST CChMaskDsp & RVal)
//===========================================================================
//
// operator -= Remove channels in source mask from this mask
//
//===========================================================================
VOID CChMaskDsp::operator -= (CONST CChannelMask & RVal)
{
CH_MASK * pMask = (CH_MASK *) &m_MaskRegs[ 0 ];
*pMask &= ~RVal.m_MaskRegs[ 0 ];
} // VOID operator += (CONST CChMaskDsp & RVal)
//===========================================================================
//
// Operator = just copies from one mask to another.
//
//===========================================================================
CChMaskDsp& CChMaskDsp::operator =(CONST CChannelMask & RVal)
{
CH_MASK * pMask = (CH_MASK *) &m_MaskRegs[ 0 ];
*pMask = RVal.m_MaskRegs[ 0 ];
return *this;
} // CChMaskDsp& CChMaskDsp::operator =(CONST CChannelMask & RVal)
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CChMaskDsp::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CChMaskDsp::operator new memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CChMaskDsp::operator new( size_t Size )
VOID CChMaskDsp::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("CChMaskDsp::operator delete memory free failed\n"));
}
} // VOID CChMaskDsp::operator delete( PVOID pVoid )
// ChannelMask.cpp

View File

@ -0,0 +1,261 @@
// ****************************************************************************
//
// CChannelMask.h
//
// Include file for interfacing with the CChannelMask and CChMaskDsp
// classes.
// Set editor tabs to 3 for your viewing pleasure.
//
// CChannelMask is a handy way to specify a group of pipes simultaneously.
// It should really be called "CPipeMask", but the class name predates
// the term "pipe".
//
// CChMaskDsp is used in the comm page to specify a group of channels
// at once; these are read by the DSP and must therefore be kept
// in little-endian format.
//
//---------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _CHMASKOBJECT_
#define _CHMASKOBJECT_
//
// Defines
//
typedef unsigned long CH_MASK;
#define CH_MASK_SZ (2) // Max channel mask array size
#define CH_MASK_BITS (sizeof( CH_MASK ) * 8)
// Max bits per mask entry
#define ECHO_INVALID_CHANNEL ((WORD)(-1))
// Marks unused channel #
typedef unsigned short CH_MASK_DSP;
#define CH_MASK_DSP_BITS (sizeof( CH_MASK_DSP ) * 8)
// Max bits per mask entry
/****************************************************************************
CChannelMask
****************************************************************************/
class CChannelMask
{
protected:
#ifdef ECHO_OS9
friend class CInOutChannelMask;
#endif
CH_MASK m_MaskRegs[ CH_MASK_SZ ]; // One bit per output or input channel
public:
CChannelMask();
~CChannelMask() {}
// Returns TRUE if no bits set
BOOL IsEmpty();
// Set the wPipeIndex bit in the mask
void SetIndexInMask( WORD wPipeIndex );
// Clear the wPipeIndex bit in the mask
void ClearIndexInMask( WORD wPipeIndex );
// Return the next bit set starting with wStartPipeIndex as an index.
// If nothing set, returns ECHO_INVALID_CHANNEL.
// Use this interface for enumerating thru a channel mask.
WORD GetIndexFromMask( WORD wStartPipeIndex );
// Test driver channel index in mask.
// Return TRUE if set
BOOL TestIndexInMask( WORD wPipeIndex );
// Clear all bits in the mask
void Clear();
// Clear bits in this mask that are in SrcMask
void ClearMask( CChannelMask SrcMask );
// Return TRUE if any bits in source mask are set in this mask
BOOL Test( CChannelMask * pSrcMask );
//
// Return TRUE if the Test Mask contains all of the channels
// enabled in this instance.
// Use to be sure all channels in this instance exist in
// another instance.
//
BOOL IsSubsetOf( CChannelMask& TstMask );
//
// Return TRUE if the Test Mask contains at least one of the channels
// enabled in this instance.
// Use to find out if any channels in this instance exist in
// another instance.
//
BOOL IsIntersectionOf( CChannelMask& TstMask );
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
//
// Macintosh compiler likes "class" after friend, PC doesn't care
//
friend class CChMaskDsp;
inline CH_MASK operator [] ( int iNdx )
{ return SWAP( m_MaskRegs[ iNdx ] ); }
// Return TRUE if source mask equals this mask
friend BOOLEAN operator == ( CONST CChannelMask &LVal,
CONST CChannelMask &RVal );
// Copy mask bits in source to this mask
CChannelMask& operator = (CONST CChannelMask & RVal);
// Copy mask bits in source to this mask
CChannelMask& operator = (CONST CChMaskDsp & RVal);
// Add mask bits in source to this mask
VOID operator += (CONST CChannelMask & RVal);
// Subtract mask bits in source to this mask
VOID operator -= (CONST CChannelMask & RVal);
// AND mask bits in source to this mask
VOID operator &= (CONST CChannelMask & RVal);
// OR mask bits in source to this mask
VOID operator |= (CONST CChannelMask & RVal);
protected :
//
// Store an output bit mask and an input bitmask.
// We assume here that the # of outputs fits in one mask reg
//
void SetMask( CH_MASK OutMask, CH_MASK InMask, int nOutputs );
void SetOutMask( CH_MASK OutMask, int nOutputs );
void SetInMask( CH_MASK InMask, int nOutputs );
//
// Retrieve an output bit mask and an input bitmask.
// We assume here that the # of outputs fits in one mask reg
//
void GetMask( CH_MASK & OutMask, CH_MASK & InMask, int nOutputs );
CH_MASK GetOutMask( int nOutputs );
CH_MASK GetInMask( int nOutputs );
}; // class CChannelMask
typedef CChannelMask * PCChannelMask;
/****************************************************************************
CChMaskDsp
****************************************************************************/
class CChMaskDsp
{
protected:
CH_MASK_DSP m_MaskRegs[ CH_MASK_SZ ]; // One bit per output or input channel
public:
CChMaskDsp();
~CChMaskDsp() {}
// Returns TRUE if no bits set
BOOL IsEmpty();
// Set the wPipeIndex bit in the mask
void SetIndexInMask( WORD wPipeIndex );
// Clear the wPipeIndex bit in the mask
void ClearIndexInMask( WORD wPipeIndex );
// Test pipe index in mask.
// Return TRUE if set
BOOL TestIndexInMask( WORD wPipeIndex );
// Clear all bits in the mask
void Clear();
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
//
// Macintosh compiler likes "class" after friend, PC doesn't care
//
friend class CChannelMask;
inline CH_MASK_DSP operator [] ( int iNdx )
{ return SWAP( m_MaskRegs[ iNdx ] ); }
// Copy mask bits in source to this mask
CChMaskDsp& operator = (CONST CChannelMask & RVal);
// Add mask bits in source to this mask
VOID operator += (CONST CChannelMask & RVal);
// Subtract mask bits in source to this mask
VOID operator -= (CONST CChannelMask & RVal);
protected :
}; // class CChMaskDsp
typedef CChMaskDsp * PCChMaskDsp;
#endif // _CHMASKOBJECT_
// CChannelMask.h

View File

@ -0,0 +1,789 @@
// ****************************************************************************
//
// CDaffyDuck.CPP
//
// Implementation file for the CDaffyDuck class.
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
//---------------------------------------------------------------------------
//
// The head pointer tracks the next free slot in the circular buffers
// The tail pointer tracks the oldest mapping.
//
//****************************************************************************
#include "CEchoGals.h"
/****************************************************************************
Construction/destruction
****************************************************************************/
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CDaffyDuck::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CDaffyDuck::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CDaffyDuck::operator new( size_t Size )
VOID CDaffyDuck::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("CDaffyDuck::operator delete memory free failed\n"));
}
} // VOID CDaffyDuck::operator delete( PVOID pVoid )
//===========================================================================
//
// Constructor
//
//===========================================================================
CDaffyDuck::CDaffyDuck
(
PCOsSupport pOsSupport,
CDspCommObject *pDspCommObject,
WORD wPipeIndex
)
{
//
// Allocate the page for the duck entries
//
if ( ECHOSTATUS_OK != pOsSupport->OsPageAllocate( 1,
(PVOID *) &m_DuckEntries,
&m_dwDuckEntriesPhys ) )
{
ECHO_DEBUGPRINTF( ("CDaffyDuck: memory allocation failed\n") );
return;
}
//
// Stash stuff
//
m_pOsSupport = pOsSupport;
m_pDspCommObject = pDspCommObject;
m_wPipeIndex = wPipeIndex;
//
// Put the physical address of the duck at the end of
// the m_DuckEntries array so the DSP will wrap around
// to the start of the duck.
//
m_DuckEntries[MAX_ENTRIES].PhysAddr = SWAP( m_dwDuckEntriesPhys );
} // CDaffyDuck::CDaffyDuck()
//===========================================================================
//
// Destructor
//
//===========================================================================
CDaffyDuck::~CDaffyDuck()
{
m_pOsSupport->OsPageFree(1,m_DuckEntries,m_dwDuckEntriesPhys);
} // CDaffyDuck::~CDaffyDuck()
/****************************************************************************
Setup and initialization
****************************************************************************/
//===========================================================================
//
// InitCheck - returns ECHOSTATUS_OK if the duck created OK
//
//===========================================================================
ECHOSTATUS CDaffyDuck::InitCheck()
{
if (NULL == m_DuckEntries)
return ECHOSTATUS_NO_MEM;
return ECHOSTATUS_OK;
} // InitCheck
//===========================================================================
//
// Reset - resets the mapping and duck entry circular buffers
//
//===========================================================================
void CDaffyDuck::Reset()
{
//
// Zero everything
//
OsZeroMemory(m_DuckEntries,4096);
OsZeroMemory(m_Mappings,sizeof(m_Mappings));
m_dwHead = 0;
m_dwTail = 0;
m_dwCount = 0;
m_ullLastEndPos = 0;
//
// Put the physical address of the duck at the end of
// the m_DuckEntries array so the DSP will wrap around
// to the start of the duck.
//
m_DuckEntries[MAX_ENTRIES].PhysAddr = SWAP( m_dwDuckEntriesPhys );
} // Reset
//===========================================================================
//
// ResetStartPos - Takes the current list and re-calculates the
// DMA end position for each mapping, starting at DMA position zero.
//
//===========================================================================
void CDaffyDuck::ResetStartPos()
{
DWORD dwRemaining,dwIndex,dwNumEntries;
m_ullLastEndPos = 0L;
//
// See if the mapping at the buffer tail has been consumed
//
dwRemaining = m_dwCount;
dwIndex = m_dwTail;
while (0 != dwRemaining)
{
m_Mappings[dwIndex].ullEndPos =
m_ullLastEndPos + SWAP( m_DuckEntries[dwIndex].dwSize );
m_ullLastEndPos = m_Mappings[dwIndex].ullEndPos;
dwNumEntries = m_Mappings[m_dwTail].dwNumEntries;
ASSERT(dwRemaining >= dwNumEntries);
dwIndex += dwNumEntries;
if (dwIndex >= MAX_ENTRIES)
dwIndex -= MAX_ENTRIES;
dwRemaining -= dwNumEntries;
}
} // ResetStartPos
/****************************************************************************
Mapping management
****************************************************************************/
//===========================================================================
//
// AddMapping
//
// Take a mapping and add it to the circular buffer.
//
// Note that the m_DuckEntries array is read by the DSP; entries must
// therefore be stored in little-endian format.
//
// The buffer pointed to by dwPhysAddr and dwBytes must be
// physically contiguous.
//
//===========================================================================
ECHOSTATUS CDaffyDuck::AddMapping
(
DWORD dwPhysAddr,
DWORD dwBytes,
DWORD dwTag,
DWORD dwInterrupt,
DWORD &dwNumFreeEntries
)
{
#ifdef INTEGRITY_CHECK
CheckIntegrity();
#endif
//
// The caller should only be trying to do this if
// there are at least two free entries
//
ASSERT((MAX_ENTRIES - m_dwCount) >= 2);
//
// At least two slots are available in the circular
// buffer, so it's OK to add either a regular mapping or
// a mapping with a double zero
//
m_DuckEntries[m_dwHead].PhysAddr = SWAP( dwPhysAddr );
m_DuckEntries[m_dwHead].dwSize = SWAP( dwBytes );
m_Mappings[m_dwHead].dwTag = dwTag;
m_Mappings[m_dwHead].ullEndPos = m_ullLastEndPos + dwBytes;
m_ullLastEndPos = m_Mappings[m_dwHead].ullEndPos;
/*
ECHO_DEBUGPRINTF(("CDaffyDuck::AddMapping m_dwCount %ld pipe index %d end pos %I64x\n",
m_dwCount,m_wPipeIndex,m_ullLastEndPos));
*/
//
// If the caller wants an interrupt after this mapping, then
// dwInterrupt will be non-zero
//
if (dwInterrupt)
{
DWORD dwNext;
//
// Interrupt wanted - need to add an extra slot with the double zero
//
m_Mappings[m_dwHead].dwNumEntries = 2;
//
// Put in the double zero so the DSP will
// generate an interrupt
//
dwNext = m_dwHead + 1;
if (dwNext >= MAX_ENTRIES)
dwNext -= MAX_ENTRIES;
m_DuckEntries[dwNext].PhysAddr = 0; // no need to swap zero!
m_DuckEntries[dwNext].dwSize = 0;
m_dwCount += 2;
}
else
{
m_Mappings[m_dwHead].dwNumEntries = 1;
m_dwCount++;
}
//
// Move the head to point to the next empty slot
//
m_dwHead += m_Mappings[m_dwHead].dwNumEntries;
if (m_dwHead >= MAX_ENTRIES)
m_dwHead -= MAX_ENTRIES; // circular buffer wrap
//
// Return value to the caller
//
dwNumFreeEntries = MAX_ENTRIES - m_dwCount;
//
// Tell the DSP about the new buffer if the
// interrupt flag is set
//
if (dwInterrupt != 0)
{
m_pDspCommObject->AddBuffer( m_wPipeIndex );
}
//#ifdef _DEBUG
#if 0
DWORD hi,lo;
hi = (DWORD) (m_ullLastEndPos >> 32);
lo = (DWORD) (m_ullLastEndPos & 0xffffffffL);
ECHO_DEBUGPRINTF(("Added tag %ld, end pos 0x%08lx%08lx (int %ld)\n",dwTag,hi,lo,dwInterrupt));
#ifdef INTEGRITY_CHECK
CheckIntegrity();
#endif
ECHO_DEBUGPRINTF(("Daffy duck count is %ld\n",m_dwCount));
#endif
return ECHOSTATUS_OK;
} // AddMapping
//===========================================================================
//
// AddDoubleZero
//
// Adds a double zero to the circular buffer to cause the DSP to generate an
// IRQ. If the buffer is full -or- the most recent entry already has a
// double zero, nothing happens.
//
//===========================================================================
void CDaffyDuck::AddDoubleZero()
{
//
// Skip if the circular buffer is full or empty
//
if ((MAX_ENTRIES == m_dwCount) || (0 == m_dwCount))
return;
//ECHO_DEBUGPRINTF(("CDaffyDuck::AddDoubleZero m_dwCount %ld\n",m_dwCount));
//
// Search back before the head and find the most recent entry
//
DWORD dwEntry;
#ifdef _DEBUG
DWORD dwCount = 0;
#endif
do
{
#ifdef _DEBUG
dwCount++;
if (dwCount > 2)
{
ECHO_DEBUGPRINTF(("CDaffyDuck::AddDoubleZero - shouldn't search back more "
"than two entries!\n"));
ECHO_DEBUGBREAK();
}
#endif
dwEntry = m_dwHead - 1;
if (dwEntry >= 0x80000000)
dwEntry += MAX_ENTRIES; // circular buffer wrap
if (m_Mappings[dwEntry].dwNumEntries != 0)
break;
} while (dwEntry != m_dwTail);
//
// Quit if this entry already has a double zero
//
ASSERT(m_Mappings[dwEntry].dwNumEntries <= 2);
if (2 == m_Mappings[dwEntry].dwNumEntries)
return;
//
// Add the double zero
//
DWORD dwNext;
dwNext = dwEntry + 1;
if (dwNext >= MAX_ENTRIES)
dwNext -= MAX_ENTRIES;
m_DuckEntries[dwNext].PhysAddr = 0;
m_DuckEntries[dwNext].dwSize = 0;
m_Mappings[dwEntry].dwNumEntries += 1;
m_dwCount++;
m_dwHead = dwEntry + m_Mappings[dwEntry].dwNumEntries;
if (m_dwHead >= MAX_ENTRIES)
m_dwHead -= MAX_ENTRIES;
//
// Tell the DSP about it
//
m_pDspCommObject->AddBuffer( m_wPipeIndex );
//ECHO_DEBUGPRINTF(("Added double zero\n"));
} // AddDoubleZero
//===========================================================================
//
// Wrap
//
// Put a "next PLE" pointer at the end of the duck to make the DSP
// wrap around to the start; this creates a circular buffer.
//
//===========================================================================
void CDaffyDuck::Wrap()
{
ASSERT(m_dwCount != MAX_ENTRIES);
//
// Put in the address of the start of the duck entries
// and a count of zero; a count of zero tells the DSP
// "Go look again for a duck entry at this address"
//
m_DuckEntries[m_dwHead].PhysAddr = SWAP( m_dwDuckEntriesPhys );
m_DuckEntries[m_dwHead].dwSize = 0;
m_Mappings[m_dwHead].dwNumEntries = 1;
m_dwHead++;
if (m_dwHead >= MAX_ENTRIES)
m_dwHead -= MAX_ENTRIES;
m_dwCount++;
m_fWrapped = TRUE;
} // Wrap
//===========================================================================
//
// ReleaseUsedMapping
//
// Find a mapping that's been consumed and return it
//
//===========================================================================
ECHOSTATUS CDaffyDuck::ReleaseUsedMapping
(
ULONGLONG ullDmaPos,
DWORD &dwTag
)
{
#ifdef INTERGRITY_CHECK
CheckIntegrity();
#endif
//
// See if there are any mappings and if the oldest mapping has
// been consumed by the DSP.
//
if ((0 != m_dwCount) && (ullDmaPos >= m_Mappings[m_dwTail].ullEndPos))
{
DWORD dwNumEntries;
//
// Time to release the mapping at the tail
//
dwTag = m_Mappings[m_dwTail].dwTag;
//
// Remove the mapping from the circular buffer,
// taking dwNumEntries into consideration
//
dwNumEntries = m_Mappings[m_dwTail].dwNumEntries;
m_Mappings[m_dwTail].dwNumEntries = 0;
ASSERT(m_dwCount >= dwNumEntries);
m_dwTail += dwNumEntries;
if (m_dwTail >= MAX_ENTRIES)
m_dwTail -= MAX_ENTRIES;
m_dwCount -= dwNumEntries;
#ifdef INTEGRITY_CHECK
CheckIntegrity();
#endif
#if 0
//#ifdef _DEBUG
ULONGLONG ullRemaining;
ullRemaining = m_ullLastEndPos - ullDmaPos;
ECHO_DEBUGPRINTF(("Released mapping for pipe index %d - bytes remaining %I64x\n",
m_wPipeIndex,ullRemaining));
#endif
return ECHOSTATUS_OK;
}
//
// No bananas today, thanks.
//
return ECHOSTATUS_NO_DATA;
} // ReleaseUsedMappings
//===========================================================================
//
// RevokeMappings
//
// Returns the number actually revoked
//
//===========================================================================
DWORD CDaffyDuck::RevokeMappings(DWORD dwFirstTag,DWORD dwLastTag)
{
MAPPING *TempMappings = NULL;
DUCKENTRY *TempEntries = NULL;
DWORD dwNumTemp;
DWORD dwOffset;
DWORD dwNumRevoked = 0;
//
// Allocate the arrays
//
OsAllocateNonPaged( sizeof(MAPPING) * MAX_ENTRIES, // fixme make this part of the duck
(void **) &TempMappings );
OsAllocateNonPaged( sizeof(DUCKENTRY) * MAX_ENTRIES,
(void **) &TempEntries );
if ( (NULL == TempMappings) ||
(NULL == TempEntries))
{
goto exit;
}
//
// Tweak the end position so it's set OK
// when the duck is rebuilt
//
SetLastEndPos(GetStartPos());
//----------------------------------------------------------------------
//
// The tags are 32 bit counters, so it is possible that they will
// wrap around (that is, dwLastTag may be less than dwFirstTag). If the
// tags have wrapped, use an offset so the compares work correctly.
//
//----------------------------------------------------------------------
dwOffset = 0;
if (dwLastTag < dwFirstTag)
{
dwOffset = 0x80000000;
dwLastTag -= dwOffset;
dwFirstTag -= dwOffset;
}
//----------------------------------------------------------------------
//
// Empty out the duck into the temp arrays, throwing away
// the revoked mappings.
//
//----------------------------------------------------------------------
ECHOSTATUS Status;
DWORD dwAdjustedTag;
dwNumTemp = 0;
do
{
Status = GetTail( TempEntries + dwNumTemp,
TempMappings + dwNumTemp);
if (ECHOSTATUS_OK == Status)
{
dwAdjustedTag = TempMappings[dwNumTemp].dwTag - dwOffset;
if ((dwFirstTag <= dwAdjustedTag) &&
(dwAdjustedTag <= dwLastTag))
{
//
// Revoke this tag
//
dwNumRevoked++;
}
else
{
//
// Save this tag
//
dwNumTemp++;
}
}
} while (ECHOSTATUS_OK == Status);
//----------------------------------------------------------------------
//
// Add all the saved mappings back into this duck.
//
//----------------------------------------------------------------------
DWORD i,dwDummy;
//
// Partially reset this duck
//
m_dwHead = 0;
m_dwTail = 0;
m_dwCount = 0;
//
// Put all the non-revoked mappings back
//
for (i = 0; i < dwNumTemp; i++)
{
AddMapping( TempEntries[i].PhysAddr,
TempEntries[i].dwSize,
TempMappings[i].dwTag,
TempMappings[i].dwNumEntries - 1,
dwDummy);
}
ECHO_DEBUGPRINTF(("CDaffyDuck::RevokeMappings for pipe index %d - m_dwHead %ld m_dwTail %ld m_dwCount %ld\n",
m_wPipeIndex,m_dwHead,m_dwTail,m_dwCount));
exit:
if (TempEntries) OsFreeNonPaged(TempEntries);
if (TempMappings) OsFreeNonPaged(TempMappings);
return dwNumRevoked;
} // RevokeMappings
//===========================================================================
//
// GetTail
//
// Unconditionally returns the mapping information from the tail of the
// circular buffer.
//
//===========================================================================
ECHOSTATUS CDaffyDuck::GetTail(DUCKENTRY *pDuckEntry,MAPPING *pMapping)
{
//
// Punt if there are no entries in the circular buffer
//
if (0 == m_dwCount)
return ECHOSTATUS_NO_DATA;
//
// Copy the data
//
OsCopyMemory( pDuckEntry,
m_DuckEntries + m_dwTail,
sizeof(DUCKENTRY));
OsCopyMemory( pMapping,
m_Mappings + m_dwTail,
sizeof(MAPPING));
//
// Buffer housekeeping
//
DWORD dwNumEntries = m_Mappings[m_dwTail].dwNumEntries;
m_Mappings[m_dwTail].dwNumEntries = 0;
ASSERT(m_dwCount >= dwNumEntries);
m_dwTail += dwNumEntries;
if (m_dwTail >= MAX_ENTRIES)
m_dwTail -= MAX_ENTRIES;
m_dwCount -= dwNumEntries;
#ifdef INTEGRITY_CHECK
CheckIntegrity();
#endif
return ECHOSTATUS_OK;
} // GetTail
//===========================================================================
//
// CheckIntegrity
//
// Debug code - makes sure that the buffer count, head, and tail all agree
//
//===========================================================================
#ifdef INTEGRITY_CHECK
void CDaffyDuck::CheckIntegrity()
{
DWORD dwDiff;
dwDiff = m_dwHead - m_dwTail;
if (dwDiff > 0x80000000)
dwDiff += MAX_ENTRIES;
if ((0 == dwDiff) && (MAX_ENTRIES == m_dwCount))
return;
if (dwDiff != m_dwCount)
{
ECHO_DEBUGPRINTF(("CDaffyDuck integrity check fail! m_dwHead %ld m_dwTail %ld "
"m_dwCount %ld m_Mappings[m_dwHead].dwNumEntries %ld\n",
m_dwHead,m_dwTail,m_dwCount,m_Mappings[m_dwHead].dwNumEntries));
ECHO_DEBUGBREAK();
}
} // CheckIntegrity
#endif // INTEGRITY_CHECK
// *** CDaffyDuck.cpp ***

View File

@ -0,0 +1,302 @@
// ****************************************************************************
//
// CDaffyDuck.H
//
// Include file for interfacing with the CDaffyDuck class.
//
// A daffy duck maintains a scatter-gather list used by the DSP to
// transfer audio data via bus mastering.
//
// The scatter-gather list takes the form of a circular buffer of
// duck entries; each duck entry is an address/count pair that points
// to an audio data buffer somewhere in memory.
//
// Although the scatter-gather list itself is a circular buffer, that
// does not mean that the audio data pointed to by the scatter-gather
// list is necessarily a circular buffer. The audio buffers pointed to
// by the SG list may be either a non-circular linked list of buffers
// or a ring buffer.
//
// If you want a ring DMA buffer for your audio data, refer to the
// Wrap() method, below.
//
// The name "daffy duck" is an inside joke that dates back to the
// original VxD for Windows 95.
//
// Set editor tabs to 3 for your viewing pleasure.
//
//---------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _DAFFYDUCKOBJECT_
#define _DAFFYDUCKOBJECT_
#ifdef _DEBUG
#define INTEGRITY_CHECK
#endif
//
// DUCKENTRY is a single entry for the scatter-gather list. A DUCKENTRY
// struct is read by the DSP.
//
typedef struct
{
DWORD PhysAddr;
DWORD dwSize;
} DUCKENTRY, * PDUCKENTRY;
//
// The CDaffyDuck class keeps a parallel array of MAPPING structures
// that corresponds to the DUCKENTRY array. You can't just pack everything
// into one struct since the DSP reads the DUCKENTRY structs and wouldn't
// know what to do with the other fields.
//
typedef struct
{
DWORD dwNumEntries; // How many slots in the array are used
// = 1 for an audio mapping
// = 2 for an audio mapping + double zero
DWORD dwTag; // Unique ID for this mapping
ULONGLONG ullEndPos; // The cumulative 64-bit end position for this mapping
// = (previous ullEndPos) + (# of bytes mapped)
} MAPPING;
class CDspCommObject;
class CDaffyDuck
{
public:
//
// Number of entries in the circular buffer.
//
// If MAX_ENTRIES is set too high, SONAR crashes in Windows XP if you are
// using super-interleave mode. 64 seems to work.
//
enum
{
MAX_ENTRIES = 64
};
//
// Construction/destruction
//
CDaffyDuck
(
PCOsSupport pOsSupport,
CDspCommObject *pDspCommObject,
WORD wPipeIndex
);
~CDaffyDuck();
protected:
WORD m_wPipeIndex;
DUCKENTRY *m_DuckEntries; // Points to a locked physical page (4096 bytes)
// These are for the benefit of the DSP
MAPPING m_Mappings[MAX_ENTRIES];// Parallel circular buffer to m_DuckEntries;
// these are for the benefit of port class
DWORD m_dwHead; // Index for most recently adding mapping
DWORD m_dwTail; // Next mapping to discard (read index)
DWORD m_dwCount; // Number of entries in the circular buffer
DWORD m_dwDuckEntriesPhys; // The DSP needs this - physical address
// of page pointed to by m_DuckEntries
ULONGLONG m_ullLastEndPos;
PCOsSupport m_pOsSupport;
CDspCommObject *m_pDspCommObject;
BOOL m_fWrapped;
#ifdef INTEGRITY_CHECK
void CheckIntegrity();
#endif
ECHOSTATUS GetTail
(
DUCKENTRY *pDuckEntry,
MAPPING *pMapping
);
public:
//
// InitCheck should be called after constructing the CDaffyDuck; this
// is needed because you can't use exceptions in the Windows kernel.
//
ECHOSTATUS InitCheck();
void Reset();
void ResetStartPos();
//
// Call AddMapping to add a buffer of audio data to the scatter-gather list.
// Note that dwPhysAddr will be asserted on the PCI bus; you will need
// to make the appropriate translation between the virtual address of
// the page and the bus address *before* calling this function.
//
// The buffer must be physically contiguous.
//
// The dwTag parameter is a unique ID for this mapping that is used by
// ReleaseUsedMapping and RevokeMappings; if you are building a circular
// buffer, the tag isn't important.
//
// dwInterrupt is true if you want the DSP to generate an IRQ after it
// consumes this audio buffer.
//
// dwNumFreeEntries is useful if you are calling this in a loop and
// want to know when to stop;
//
ECHOSTATUS AddMapping
(
DWORD dwPhysAddr,
DWORD dwBytes,
DWORD dwTag, // Unique ID for this mapping
DWORD dwInterrupt, // Set TRUE if you want an IRQ after this mapping
DWORD &dwNumFreeEntries // Return value - number of slots left in the list
);
//
// AddDoubleZero is used to have the DSP generate an interrupt;
// calling AddDoubleZero will cause the DSP to interrupt after it finishes the
// previous duck entry.
//
void AddDoubleZero();
//
// Call Wrap if you are creating a circular DMA buffer; to make a circular
// double buffer, do this:
//
// AddMapping() Several times
// AddDoubleZero() First half-buffer interrupt
// AddMapping() Several more times
// AddDoubleZero() Second half-buffer interrupt
// Wrap() Wraps the scatter list around to make a circular buffer
//
// Once you call Wrap, you shouldn't add any more mappings.
//
void Wrap();
//
// Call ReleaseUsedMapping to conditionally remove the oldest duck entry.
// ReleaseUsedMapping looks at the DMA position you pass in; if the DMA position
// is past the end of the oldest mapping, the oldest mapping is removed
// from the list and the tag number is returned in the dwTag parameter.
//
ECHOSTATUS ReleaseUsedMapping
(
ULONGLONG ullDmaPos,
DWORD &dwTag
);
//
// This returns the physical address of the start of the scatter-gather
// list; used to tell the DSP where to start looking for duck entries.
//
DWORD GetPhysStartAddr()
{
return m_dwDuckEntriesPhys + (m_dwTail * sizeof(DUCKENTRY));
}
//
// Any more room in the s.g. list?
//
DWORD GetNumFreeEntries()
{
return MAX_ENTRIES - m_dwCount;
}
//
// Used to reset the end pos for rebuilding the duck; this
// is used by the WDM driver to handle revoking.
//
void SetLastEndPos(ULONGLONG ullPos)
{
m_ullLastEndPos = ullPos;
}
//
// Returns the 64 bit DMA position of the start of the oldest entry
//
ULONGLONG GetStartPos()
{
return m_Mappings[ m_dwTail ].ullEndPos -
(ULONGLONG) (m_DuckEntries[ m_dwTail ].dwSize);
}
//
// RevokeMappings is here specifically to support WDM; it removes
// any entries from the list if their tag is >= dwFirstTag and <= dwLastTag.
//
DWORD RevokeMappings
(
DWORD dwFirstTag,
DWORD dwLastTag
);
//
// Returns TRUE if Wrap has been called for this duck
//
BOOL Wrapped()
{
return m_fWrapped;
}
//
// Overload new & delete to make sure these objects are allocated from
// non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
}; // class CDaffyDuck
typedef CDaffyDuck * PCDaffyDuck;
#endif // _DAFFYDUCKOBJECT_
// *** CDaffyDuck.H ***

View File

@ -0,0 +1,209 @@
// ****************************************************************************
//
// CDarla.cpp
//
// Implementation file for the CDarla driver class; this supports 20 bit
// Darla, not Darla24.
//
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CDarla.h"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CDarla::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CDarla::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CDarla::operator new( size_t Size )
VOID CDarla::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("CDarla::operator delete memory free failed\n"));
}
} // VOID CDarla::operator delete( PVOID pVoid )
//===========================================================================
//
// Constructor and destructor
//
//===========================================================================
CDarla::CDarla( PCOsSupport pOsSupport )
: CEchoGals( pOsSupport )
{
ECHO_DEBUGPRINTF( ( "CDarla::CDarla() is born!\n" ) );
}
CDarla::~CDarla()
{
ECHO_DEBUGPRINTF( ( "CDarla::~CDarla() is toast!\n" ) );
}
/****************************************************************************
Setup and hardware initialization
****************************************************************************/
//===========================================================================
//
// Every card has an InitHw method
//
//===========================================================================
ECHOSTATUS CDarla::InitHw()
{
ECHOSTATUS Status;
//
// Call the base InitHw method
//
if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
return Status;
//
// Create the DSP comm object
//
ASSERT( NULL == m_pDspCommObject );
m_pDspCommObject = new CDarlaDspCommObject( (PDWORD) m_pvSharedMemory,
m_pOsSupport );
if (NULL == m_pDspCommObject)
{
ECHO_DEBUGPRINTF(("CDarla::InitHw - could not create DSP comm object\n"));
return ECHOSTATUS_NO_MEM;
}
//
// Load the DSP
//
GetDspCommObject()->LoadFirmware();
if ( GetDspCommObject()->IsBoardBad() )
return ECHOSTATUS_DSP_DEAD;
//
// Clear the "bad board" flag
//
m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
//
// Must call this here *after* DSP is init
//
Status = InitLineLevels();
//
// Get default sample rate from DSP
//
m_dwSampleRate = GetDspCommObject()->GetSampleRate();
ECHO_DEBUGPRINTF( ( "CDarla::InitHw()\n" ) );
return Status;
} // ECHOSTATUS CDarla::InitHw()
/****************************************************************************
Informational methods
****************************************************************************/
//===========================================================================
//
// QueryAudioSampleRate is used to find out if this card can handle a
// given sample rate.
//
//===========================================================================
ECHOSTATUS CDarla::QueryAudioSampleRate
(
DWORD dwSampleRate
)
{
if ( dwSampleRate != 44100 &&
dwSampleRate != 48000 )
{
ECHO_DEBUGPRINTF(
("CDarla::QueryAudioSampleRate() Sample rate must be"
" 44,100 Hz or 48,000 Hz\n") );
return ECHOSTATUS_BAD_FORMAT;
}
ECHO_DEBUGPRINTF( ( "CDarla::QueryAudioSampleRate()\n" ) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CDarla::QueryAudioSampleRate
// *** CDarla.cpp ***

View File

@ -0,0 +1,96 @@
// ****************************************************************************
//
// CDarla.H
//
// Include file for interfacing with the CDarla generic driver class
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _DARLAOBJECT_
#define _DARLAOBJECT_
#include "CEchoGals.h"
#include "CDarlaDspCommObject.h"
//
// Class used for interfacing with the Darla audio card.
//
class CDarla : public CEchoGals
{
public:
//
// Construction/destruction
//
CDarla( PCOsSupport pOsSupport );
virtual ~CDarla();
//
// Setup & initialization methods
//
virtual ECHOSTATUS InitHw();
//
// Audio Interface methods
//
virtual ECHOSTATUS QueryAudioSampleRate
(
DWORD dwSampleRate
);
//
// Overload new & delete so memory for this object is allocated from non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
protected:
//
// Get access to the appropriate DSP comm object
//
PCDarlaDspCommObject GetDspCommObject()
{ return( (PCDarlaDspCommObject) m_pDspCommObject ); }
}; // class CDarla
typedef CDarla * PCDarla;
#endif
// *** CDarla.H ***

View File

@ -0,0 +1,301 @@
// ****************************************************************************
//
// CDarla24.cpp
//
// Implementation file for the CDarla24 driver class.
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CDarla24.h"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CDarla24::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CDarla24::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CDarla24::operator new( size_t Size )
VOID CDarla24::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("CDarla24::operator delete memory free failed\n"));
}
} // VOID CDarla24::operator delete( PVOID pVoid )
//===========================================================================
//
// Constructor and destructor
//
//===========================================================================
CDarla24::CDarla24( PCOsSupport pOsSupport )
: CEchoGals( pOsSupport )
{
ECHO_DEBUGPRINTF( ( "CDarla24::CDarla24() is born!\n" ) );
}
CDarla24::~CDarla24()
{
ECHO_DEBUGPRINTF( ( "CDarla24::~CDarla24() is toast!\n" ) );
}
/****************************************************************************
Setup and hardware initialization
****************************************************************************/
//===========================================================================
//
// Every card has an InitHw method
//
//===========================================================================
ECHOSTATUS CDarla24::InitHw()
{
ECHOSTATUS Status;
WORD i;
//
// Call the base method
//
if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
return Status;
//
// Create the DSP comm object
//
ASSERT( NULL == m_pDspCommObject );
m_pDspCommObject = new CDarla24DspCommObject( (PDWORD) m_pvSharedMemory,
m_pOsSupport );
if (NULL == m_pDspCommObject)
{
ECHO_DEBUGPRINTF(("CDarla24::InitHw - could not create DSP comm object\n"));
return ECHOSTATUS_NO_MEM;
}
//
// Load the DSP
//
GetDspCommObject()->LoadFirmware();
if ( GetDspCommObject()->IsBoardBad() )
return ECHOSTATUS_DSP_DEAD;
//
// Clear the "bad board" flag; set the flag to indicate that
// Darla24 can handle super-interleave.
//
m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK;
//
// Must call this here after DSP is init to
// init gains
//
Status = InitLineLevels();
if ( ECHOSTATUS_OK != Status )
return Status;
//
// Set defaults for +4/-10
//
for (i = 0; i < GetNumBusses(); i++ )
{
GetDspCommObject()->SetNominalLevel( i, FALSE ); // FALSE is +4 here
}
//
// Get default sample rate from DSP
//
m_dwSampleRate = GetDspCommObject()->GetSampleRate();
ECHO_DEBUGPRINTF( ( "CDarla24::InitHw()\n" ) );
return Status;
} // ECHOSTATUS CDarla24::InitHw()
/****************************************************************************
Informational methods
****************************************************************************/
//===========================================================================
//
// QueryAudioSampleRate is used to find out if this card can handle a
// given sample rate.
//
//===========================================================================
ECHOSTATUS CDarla24::GetCapabilities
(
PECHOGALS_CAPS pCapabilities
)
{
ECHOSTATUS Status;
WORD i;
Status = GetBaseCapabilities(pCapabilities);
//
// Add nominal level control to in & out busses
//
for (i = 0 ; i < GetNumBussesOut(); i++)
{
pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
}
for (i = 0 ; i < GetNumBussesIn(); i++)
{
pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
}
if ( ECHOSTATUS_OK != Status )
return Status;
pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_ESYNC;
return Status;
} // ECHOSTATUS CDarla24::GetCapabilities
//===========================================================================
//
// GetInputClockDetect returns a bitmask consisting of all the input
// clocks currently connected to the hardware; this changes as the user
// connects and disconnects clock inputs.
//
// You should use this information to determine which clocks the user is
// allowed to select.
//
// Darla24 only supports Esync input clock.
//
//===========================================================================
ECHOSTATUS CDarla24::GetInputClockDetect(DWORD &dwClockDetectBits)
{
if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
{
ECHO_DEBUGPRINTF( ("CDarla24::GetInputClockDetect: DSP Dead!\n") );
return ECHOSTATUS_DSP_DEAD;
}
DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_ESYNC))
dwClockDetectBits |= ECHO_CLOCK_BIT_ESYNC;
return ECHOSTATUS_OK;
} // GetInputClockDetect
//===========================================================================
//
// QueryAudioSampleRate is used to find out if this card can handle a
// given sample rate.
//
//===========================================================================
ECHOSTATUS CDarla24::QueryAudioSampleRate
(
DWORD dwSampleRate
)
{
if ( dwSampleRate != 8000 &&
dwSampleRate != 11025 &&
dwSampleRate != 16000 &&
dwSampleRate != 22050 &&
dwSampleRate != 32000 &&
dwSampleRate != 44100 &&
dwSampleRate != 48000 &&
dwSampleRate != 88200 &&
dwSampleRate != 96000 )
{
ECHO_DEBUGPRINTF(
("CDarla24::QueryAudioSampleRate() Sample rate must be 8,000 Hz,"
" 11,025 Hz, 16,000 Hz, 22,050 Hz, 32,000 Hz, 44,100 Hz, "
"48,000 Hz, 88,200 Hz or 96,000 Hz\n") );
return ECHOSTATUS_BAD_FORMAT;
}
ECHO_DEBUGPRINTF( ( "CDarla24::QueryAudioSampleRate()\n" ) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CDarla24::QueryAudioSampleRate
// *** CDarla24.cpp ***

View File

@ -0,0 +1,116 @@
// ****************************************************************************
//
// CDarla24.H
//
// Include file for interfacing with the CDarla24 generic driver class
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _DARLA24OBJECT_
#define _DARLA24OBJECT_
#include "CEchoGals.h"
#include "CDarla24DspCommObject.h"
//
// Class used for interfacing with the Darla audio card.
//
class CDarla24 : public CEchoGals
{
public:
//
// Construction/destruction
//
CDarla24( PCOsSupport pOsSupport );
virtual ~CDarla24();
//
// Setup & initialization methods
//
virtual ECHOSTATUS InitHw();
//
// Adapter information methods
//
//
// Return the capabilities of this card; card type, card name,
// # analog inputs, # analog outputs, # digital channels,
// # MIDI ports and supported clocks.
// See ECHOGALS_CAPS definition above.
//
virtual ECHOSTATUS GetCapabilities
(
PECHOGALS_CAPS pCapabilities
);
//
// Get a bitmask of all the clocks the hardware is currently detecting
//
virtual ECHOSTATUS GetInputClockDetect(DWORD &dwClockDetectBits);
//
// Audio Interface methods
//
virtual ECHOSTATUS QueryAudioSampleRate
(
DWORD dwSampleRate
);
//
// Overload new & delete so memory for this object is allocated from
// non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
protected:
//
// Get access to the appropriate DSP comm object
//
PCDarla24DspCommObject GetDspCommObject()
{ return( (PCDarla24DspCommObject) m_pDspCommObject ); }
}; // class CDarla24
typedef CDarla24 * PCDarla24;
#endif
// *** CDarla24.H ***

View File

@ -0,0 +1,232 @@
// ****************************************************************************
//
// CDarla24DspCommObject.cpp
//
// Implementation file for Darla24 DSP interface class.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CDarla24DspCommObject.h"
#include "Darla24DSP.c"
/****************************************************************************
Magic constants for the Darla24 hardware
****************************************************************************/
#define GD24_96000 0x0
#define GD24_48000 0x1
#define GD24_44100 0x2
#define GD24_32000 0x3
#define GD24_22050 0x4
#define GD24_16000 0x5
#define GD24_11025 0x6
#define GD24_8000 0x7
#define GD24_88200 0x8
#define GD24_EXT_SYNC 0x9
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CDarla24DspCommObject::CDarla24DspCommObject
(
PDWORD pdwRegBase, // Virtual ptr to DSP registers
PCOsSupport pOsSupport
) : CGdDspCommObject( pdwRegBase, pOsSupport )
{
strcpy( m_szCardName, "Darla24" );
m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base
m_wNumPipesOut = 8;
m_wNumPipesIn = 2;
m_wNumBussesOut = 8;
m_wNumBussesIn = 2;
m_wFirstDigitalBusOut = 8;
m_wFirstDigitalBusIn = 2;
m_fHasVmixer = FALSE;
m_wNumMidiOut = 0; // # MIDI out channels
m_wNumMidiIn = 0; // # MIDI in channels
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 44100 );
// Need this in case we start with ESYNC
m_pwDspCodeToLoad = pwDarla24DSP;
//
// Since this card has no ASIC, mark it as loaded so everything works OK
//
m_bASICLoaded = TRUE;
} // CDarla24DspCommObject::CDarla24DspCommObject( DWORD dwPhysRegBase )
//===========================================================================
//
// Destructor
//
//===========================================================================
CDarla24DspCommObject::~CDarla24DspCommObject()
{
} // CDarla24DspCommObject::~CDarla24DspCommObject()
/****************************************************************************
Hardware config
****************************************************************************/
//===========================================================================
//
// SetSampleRate
//
// Set the audio sample rate for Darla24; this is fairly simple. You
// just pick the right magic number.
//
//===========================================================================
DWORD CDarla24DspCommObject::SetSampleRate( DWORD dwNewSampleRate )
{
BYTE bClock;
//
// Pick the magic number
//
switch ( dwNewSampleRate )
{
case 96000 :
bClock = GD24_96000;
break;
case 88200 :
bClock = GD24_88200;
break;
case 48000 :
bClock = GD24_48000;
break;
case 44100 :
bClock = GD24_44100;
break;
case 32000 :
bClock = GD24_32000;
break;
case 22050 :
bClock = GD24_22050;
break;
case 16000 :
bClock = GD24_16000;
break;
case 11025 :
bClock = GD24_11025;
break;
case 8000 :
bClock = GD24_8000;
break;
default :
ECHO_DEBUGPRINTF( ("CDarla24DspCommObject::SetSampleRate: Error, "
"invalid sample rate 0x%lx\n", dwNewSampleRate) );
return 0xffffffff;
}
if ( !WaitForHandshake() )
return 0xffffffff;
//
// Override the sample rate if this card is set to Echo sync.
// m_pDspCommPage->wInputClock is just being used as a parameter here;
// the DSP ignores it.
//
if ( ECHO_CLOCK_ESYNC == GetInputClock() )
bClock = GD24_EXT_SYNC;
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
//
// Write the audio state to the comm page
//
m_pDspCommPage->byGDClockState = bClock;
// Send command to DSP
ClearHandshake();
SendVector( DSP_VC_SET_GD_AUDIO_STATE );
ECHO_DEBUGPRINTF( ("CDarla24DspCommObject::SetSampleRate: 0x%lx "
"clocks %s\n", dwNewSampleRate) );
return GetSampleRate();
} // DWORD CDarla24DspCommObject::SetSampleRate( DWORD dwNewSampleRate )
//===========================================================================
//
// Set input clock
//
// Darla24 supports internal and Esync clock.
//
//===========================================================================
ECHOSTATUS CDarla24DspCommObject::SetInputClock(WORD wClock)
{
if ( (ECHO_CLOCK_INTERNAL != wClock) &&
(ECHO_CLOCK_ESYNC != wClock))
return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
m_wInputClock = wClock;
return SetSampleRate( GetSampleRate() );
} // SetInputClock
// **** Darla24DspCommObject.cpp ****

View File

@ -0,0 +1,82 @@
// ****************************************************************************
//
// CDarla24DspCommObject.H
//
// Include file for EchoGals generic driver Darla 24 DSP interface class.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _DARLA24DSPCOMMOBJECT_
#define _DARLA24DSPCOMMOBJECT_
#include "CGdDspCommObject.h"
class CDarla24DspCommObject : public CGdDspCommObject
{
public:
//
// Construction/destruction
//
CDarla24DspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport );
virtual ~CDarla24DspCommObject();
//
// Set the DSP sample rate.
// Return rate that was set, -1 if error
//
virtual DWORD SetSampleRate( DWORD dwNewSampleRate );
//
// Card information
//
virtual WORD GetCardType()
{ return DARLA24; }
//
// Set input clock
//
virtual ECHOSTATUS SetInputClock(WORD wClock);
protected:
}; // class CDarla24DspCommObject
typedef CDarla24DspCommObject * PCDarla24DspCommObject;
#endif
// **** Darla24DspCommObject.h ****

View File

@ -0,0 +1,99 @@
// ****************************************************************************
//
// CDarlaDspCommObject.cpp
//
// Implementation file for Darla20 DSP interface class.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CDarlaDspCommObject.h"
#include "Darla20DSP.c"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CDarlaDspCommObject::CDarlaDspCommObject
(
PDWORD pdwRegBase, // Virtual ptr to DSP registers
PCOsSupport pOsSupport
) : CGdDspCommObject( pdwRegBase, pOsSupport )
{
strcpy( m_szCardName, "Darla" );
m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base
m_wNumPipesOut = 8;
m_wNumPipesIn = 2;
m_wNumBussesOut = 8;
m_wNumBussesIn = 2;
m_wFirstDigitalBusOut = 8;
m_wFirstDigitalBusIn = 2;
m_fHasVmixer = FALSE;
m_wNumMidiOut = 0; // # MIDI out channels
m_wNumMidiIn = 0; // # MIDI in channels
m_pwDspCodeToLoad = pwDarla20DSP;
//
// Since this card has no ASIC, mark it as loaded so everything works OK
//
m_bASICLoaded = TRUE;
} // CDarlaDspCommObject::CDarlaDspCommObject( DWORD dwPhysRegBase )
//===========================================================================
//
// Destructor
//
//===========================================================================
CDarlaDspCommObject::~CDarlaDspCommObject()
{
} // CDarlaDspCommObject::~CDarlaDspCommObject()
// **** DarlaDspCommObject.cpp ****

View File

@ -0,0 +1,77 @@
// ****************************************************************************
//
// CDarlaDspCommObject.H
//
// Include file for Darla20 DSP interface class.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _DARLADSPCOMMOBJECT_
#define _DARLADSPCOMMOBJECT_
#include "CGdDspCommObject.h"
class CDarlaDspCommObject : public CGdDspCommObject
{
public:
//
// Construction/destruction
//
CDarlaDspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport );
virtual ~CDarlaDspCommObject();
//
// Card information
//
virtual WORD GetCardType()
{ return DARLA; }
//
// Set input clock
//
virtual ECHOSTATUS SetInputClock(WORD wClock)
{
return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
}
protected:
}; // class CDarlaDspCommObject
typedef CDarlaDspCommObject * PCDarlaDspCommObject;
#endif
// **** DarlaDspCommObject.h ****

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,420 @@
// ****************************************************************************
//
// CEchoGals.cpp
//
// Implementation file for the CEchoGals driver class.
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
/****************************************************************************
CEchoGals construction and destruction
****************************************************************************/
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CEchoGals::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CEchoGals::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CEchoGals::operator new( size_t Size )
VOID CEchoGals::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("CEchoGals::operator delete memory free failed\n"));
}
} // VOID CEchoGals::operator delete( PVOID pVoid )
//===========================================================================
//
// Constructor
//
//===========================================================================
CEchoGals::CEchoGals
(
PCOsSupport pOsSupport
)
{
int i;
ASSERT( pOsSupport );
m_pOsSupport = pOsSupport; // Ptr to OS Support methods & data
m_wFlags = ECHOGALS_FLAG_BADBOARD |
ECHOGALS_FLAG_SPDIF_NODITHER;
for ( i = 0; i < ECHO_MAXAUDIOPIPES; i++ )
m_wBytesPerSample[ i ] = 1;
m_dwLockedSampleRate = 44100;
} // CEchoGals::CEchoGals()
//===========================================================================
//
// Destructor
//
//===========================================================================
CEchoGals::~CEchoGals()
{
//
// Free stuff
//
delete m_pDspCommObject; // This powers down the DSP
m_PipeOutCtrl.Cleanup(); // fixme put this in the destructors for these guy
m_MonitorCtrl.Cleanup();
//
// Clean up the ducks
//
WORD i;
for (i = 0; i < ECHO_MAXAUDIOPIPES; i++)
{
if (NULL != m_DaffyDucks[i])
KillDaffyDuck(i);
}
//
// Clean up the mixer client list
//
while (NULL != m_pMixerClients)
{
ECHO_MIXER_CLIENT *pDeadClient;
pDeadClient = m_pMixerClients;
m_pMixerClients = pDeadClient->pNext;
OsFreeNonPaged(pDeadClient);
}
ECHO_DEBUGPRINTF( ( "CEchoGals::~CEchoGals() is toast!\n" ) );
} // CEchoGals::~CEchoGals()
/****************************************************************************
CEchoGals setup and hardware initialization
****************************************************************************/
//===========================================================================
//
// AssignResources does just what you'd expect.
//
// Note that pvSharedMemory is a logical pointer - that is, the driver
// will dereference this pointer to access the memory-mapped regisers on
// the DSP. The caller needs to take the physical address from the PCI
// config space and map it.
//
//===========================================================================
ECHOSTATUS CEchoGals::AssignResources
(
PVOID pvSharedMemory, // Ptr to DSP registers
PCHAR pszCardName // Caller gets from registry
)
{
//
// Use ASSERT to be sure this isn't called twice!
//
ASSERT( NULL == m_pvSharedMemory );
//
// Check and store the parameters
//
ASSERT( pvSharedMemory );
if ( NULL == pszCardName )
{
return( ECHOSTATUS_BAD_CARD_NAME );
}
m_pvSharedMemory = pvSharedMemory; // Shared memory addr assigned by PNP
//
// Copy card name & make sure we don't overflow our buffer
//
strncpy( m_szCardInstallName, pszCardName, ECHO_MAXNAMELEN-1 );
m_szCardInstallName[ ECHO_MAXNAMELEN-1 ] = 0;
return ECHOSTATUS_OK;
} // ECHOSTATUS CEchoGals::AssignResources
//===========================================================================
//
// InitHw is device-specific and so does nothing here; it is overridden
// in the derived classes.
//
// The correct sequence is:
//
// Construct the appropriate CEchoGals-derived object for the card
// Call AssignResources
// Call InitHw
//
//===========================================================================
ECHOSTATUS CEchoGals::InitHw()
{
//
// Use ASSERT to be sure AssignResources was called!
//
ASSERT( m_pvSharedMemory );
return ECHOSTATUS_OK;
} // ECHOSTATUS CEchoGals::InitHw()
//===========================================================================
//
// This method initializes classes to control the mixer controls for
// the busses and pipes. This is a protected method; it is called
// from each of the CEchoGals derived classes once the DSP is up
// and running.
//
//===========================================================================
ECHOSTATUS CEchoGals::InitLineLevels()
{
ECHOSTATUS Status = ECHOSTATUS_OK;
WORD i;
m_fMixerDisabled = TRUE;
if ( (NULL == GetDspCommObject()) ||
(GetDspCommObject()->IsBoardBad() ) )
{
return ECHOSTATUS_DSP_DEAD;
}
//
// Do output busses first since output pipes & monitors
// depend on output bus values
//
for ( i = 0; i < GetNumBussesOut(); i++ )
{
m_BusOutLineLevels[ i ].Init( i, this );
}
Status = m_PipeOutCtrl.Init(this);
if (ECHOSTATUS_OK != Status)
return Status;
Status = m_MonitorCtrl.Init(this);
if (ECHOSTATUS_OK != Status)
return Status;
for ( i = 0; i < GetNumBussesIn(); i++ )
{
m_BusInLineLevels[ i ].Init( i, this );
}
m_fMixerDisabled = FALSE;
return Status;
} // ECHOSTATUS CEchoGals::InitLineLevels()
/******************************************************************************
CEchoGals interrupt handler functions
******************************************************************************/
//===========================================================================
//
// This isn't the interrupt handler itself; rather, the OS-specific layer
// of the driver has an interrupt handler that calls this function.
//
//===========================================================================
ECHOSTATUS CEchoGals::ServiceIrq(BOOL &fMidiReceived)
{
CDspCommObject *pDCO;
//
// Read the DSP status register and see if this DSP
// generated this interrupt
//
fMidiReceived = FALSE;
pDCO = GetDspCommObject();
if ( pDCO->GetStatusReg() & CHI32_STATUS_IRQ )
{
#ifdef MIDI_SUPPORT
//
// If this was a MIDI input interrupt, get the MIDI input data
//
DWORD dwMidiInCount;
pDCO->ReadMidi( 0, dwMidiInCount ); // The count is at index 0
if ( 0 != dwMidiInCount )
{
m_MidiIn.ServiceIrq();
fMidiReceived = TRUE;
}
#endif // MIDI_SUPPORT
//
// Clear the hardware interrupt
//
pDCO->AckInt();
return ECHOSTATUS_OK;
}
//
// This interrupt line must be shared
//
/*
ECHO_DEBUGPRINTF( ("CEchoGals::ServiceIrq() %s\tInterrupt not ours!\n",
GetDeviceName()) );
*/
return ECHOSTATUS_IRQ_NOT_OURS;
} // ECHOSTATUS CEchoGals::ServiceIrq()
/****************************************************************************
Character strings for the ECHOSTATUS return values -
useful for debugging.
****************************************************************************/
//
// pStatusStrs is used if you want to print out a friendlier version of
// the various ECHOSTATUS codes.
//
char * pStatusStrs[ECHOSTATUS_LAST] =
{
"ECHOSTATUS_OK",
"ECHOSTATUS_BAD_FORMAT",
"ECHOSTATUS_BAD_BUFFER_SIZE",
"ECHOSTATUS_CANT_OPEN",
"ECHOSTATUS_CANT_CLOSE",
"ECHOSTATUS_CHANNEL_NOT_OPEN",
"ECHOSTATUS_BUSY",
"ECHOSTATUS_BAD_LEVEL",
"ECHOSTATUS_NO_MIDI",
"ECHOSTATUS_CLOCK_NOT_SUPPORTED",
"ECHOSTATUS_CLOCK_NOT_AVAILABLE",
"ECHOSTATUS_BAD_CARDID",
"ECHOSTATUS_NOT_SUPPORTED",
"ECHOSTATUS_BAD_NOTIFY_SIZE",
"ECHOSTATUS_INVALID_PARAM",
"ECHOSTATUS_NO_MEM",
"ECHOSTATUS_NOT_SHAREABLE",
"ECHOSTATUS_FIRMWARE_LOADED",
"ECHOSTATUS_DSP_DEAD",
"ECHOSTATUS_DSP_TIMEOUT",
"ECHOSTATUS_INVALID_CHANNEL",
"ECHOSTATUS_CHANNEL_ALREADY_OPEN",
"ECHOSTATUS_DUCK_FULL",
"ECHOSTATUS_INVALID_INDEX",
"ECHOSTATUS_BAD_CARD_NAME",
"ECHOSTATUS_IRQ_NOT_OURS",
"",
"",
"",
"",
"",
"ECHOSTATUS_BUFFER_OVERFLOW",
"ECHOSTATUS_OPERATION_CANCELED",
"ECHOSTATUS_EVENT_NOT_OPEN",
"ECHOSTATUS_ASIC_NOT_LOADED"
"ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED",
"ECHOSTATUS_RESERVED",
"ECHOSTATUS_BAD_COOKIE",
"ECHOSTATUS_MIXER_DISABLED",
"ECHOSTATUS_NO_SUPER_INTERLEAVE",
"ECHOSTATUS_DUCK_NOT_WRAPPED"
};
// *** CEchoGals.cpp ***

View File

@ -0,0 +1,869 @@
// ****************************************************************************
//
// CEchoGals.H
//
// Include file for the CEchoGals generic driver class.
// Set editor tabs to 3 for your viewing pleasure.
//
// CEchoGals is the big daddy class of the generic code. It is the upper
// edge of the generic code - that is, it is the interface between the
// operating system-specific code and the generic driver.
//
// There are a number of terms in this file that won't make any sense unless
// you go read EchoGalsXface.h first.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
/*
*/
// Prevent problems with multiple includes
#ifndef _ECHOGALSOBJECT_
#define _ECHOGALSOBJECT_
#ifdef _DEBUG
#ifdef ECHO_WDM
#pragma optimize("",off)
#endif
#endif
//
// Each project creates this file to support the OS it is targeted for
//
#include "OsSupport.h"
//
// Include the definitions for the card family
//
#include "family.h"
//
// Interface definitions
//
#include "EchoGalsXface.h"
#include "MixerXface.h"
#include "CLineLevel.h"
#include "CPipeOutCtrl.h"
#include "CMonitorCtrl.h"
#include "CEchoGals_mixer.h"
#include "CChannelMask.h"
#include "CDspCommObject.h"
#include "CMidiInQ.h"
//
// Pipe states
//
#define PIPE_STATE_RESET 0 // Pipe has been reset
#define PIPE_STATE_STOPPED 1 // Pipe has been stopped
#define PIPE_STATE_STARTED 2 // Pipe has been started
#define PIPE_STATE_PENDING 3 // Pipe has pending start
//
// Prototypes to make the Mac compiler happy
//
ECHOSTATUS CheckSetting(INT32 iValue,INT32 iMin,INT32 iMax);
INT32 PanToDb( INT32 iPan );
//
// Base class used for interfacing with the audio card.
//
class CEchoGals
{
public:
//***********************************************************************
//
// Initialization (public)
//
//***********************************************************************
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
//
// Constructor and destructor
//
// Note that you must call AssignResources and InitHw
// before you can do anything useful.
//
CEchoGals( PCOsSupport pOsSupport );
virtual ~CEchoGals();
//
// Validate and save resources assigned by PNP.
// Each card uses one IRQ vector and accesses the DSP through
// shared memory
//
virtual ECHOSTATUS AssignResources
(
PVOID pvSharedMemory, // Virtual pointer to DSP registers
PCHAR pszCardName // Caller gets from registry
);
//
// Initialize the hardware using data from AssignResources,
// create the CDspCommObject class, return status.
//
virtual ECHOSTATUS InitHw();
//***********************************************************************
//
// PCI card information (public)
//
//***********************************************************************
//
// Return the capabilities of this card; card type, card name,
// # analog inputs, # analog outputs, # digital channels,
// # MIDI ports and supported clocks.
// See ECHOGALS_CAPS definition above.
//
virtual ECHOSTATUS GetCapabilities
(
PECHOGALS_CAPS pCapabilities
)
{ return GetBaseCapabilities(pCapabilities); }
CONST PCHAR GetDeviceName();
WORD MakePipeIndex(WORD wPipe,BOOL fInput);
//***********************************************************************
//
// Mixer interface (public) - used to set volume levels and other
// miscellaneous stuff.
//
//***********************************************************************
//
// Open and close the mixer
//
ECHOSTATUS OpenMixer(DWORD &dwCookie);
ECHOSTATUS CloseMixer(DWORD dwCookie);
//
// Is the mixer open by one or more clients?
//
BOOL IsMixerOpen();
//
// Process mixer functions
//
virtual ECHOSTATUS ProcessMixerFunction
(
PMIXER_FUNCTION pMixerFunction, // Request from mixer
INT32 & iRtnDataSz // # bytes returned (if any)
);
//
// Process multiple mixer functions
//
virtual ECHOSTATUS ProcessMixerMultiFunction
(
PMIXER_MULTI_FUNCTION pMixerFunctions, // Request from mixer
INT32 & iRtnDataSz // # bytes returned (if any)
);
//
// Get all the control notifies since last time this was called
// for this client. dwNumNotifies is the size of the array passed in
// pNotifies; dwNumReturned specifies how many were actually copied in.
//
ECHOSTATUS GetControlChanges
(
PMIXER_MULTI_NOTIFY pNotifies
);
//
// Get a bunch of useful polled stuff- audio meters,
// clock detect bits, and pending notifies
//
ECHOSTATUS GetPolledStuff(ECHO_POLLED_STUFF *pPolledStuff);
//
// Get the digital mode
//
virtual BYTE GetDigitalMode()
{ return( ( NULL == GetDspCommObject() )
? DIGITAL_MODE_SPDIF_RCA
: GetDspCommObject()->GetDigitalMode() ); }
//
// Get, set and clear CEchoGals flags.
// See ECHOGALS_FLAG_??? definitions in EchoGalsXface.h
//
virtual WORD GetFlags()
{
return m_wFlags;
}
virtual ECHOSTATUS SetFlags(WORD wFlags);
virtual ECHOSTATUS ClearFlags(WORD wFlags);
//
// Get/set the locked sample rate - if the sample rate is locked,
// the card will be fixed at the locked rate. Only applies if
// the card is set to internal clock.
//
virtual ECHOSTATUS GetAudioLockedSampleRate
(
DWORD &dwSampleRate
);
virtual ECHOSTATUS SetAudioLockedSampleRate
(
DWORD dwSampleRate
);
//
// Enable/disable audio metering.
//
ECHOSTATUS GetMetersOn( BOOL & bOn )
{ return( ( NULL == GetDspCommObject() )
? ECHOSTATUS_DSP_DEAD
: GetDspCommObject()->GetMetersOn( bOn ) ); }
ECHOSTATUS SetMetersOn( BOOL bOn )
{ return( ( NULL == GetDspCommObject() )
? ECHOSTATUS_DSP_DEAD
: GetDspCommObject()->SetMetersOn( bOn ) ); }
//
// Get/Set Professional or consumer S/PDIF status
//
virtual BOOL IsProfessionalSpdif()
{ return( ( NULL == GetDspCommObject() )
? FALSE
: GetDspCommObject()->IsProfessionalSpdif() ); }
virtual void SetProfessionalSpdif( BOOL bNewStatus );
//
// Set digital mode
//
virtual ECHOSTATUS SetDigitalMode( BYTE byDigitalMode );
//
// Get and set input and output clocks
//
virtual ECHOSTATUS SetInputClock(WORD wClock);
virtual ECHOSTATUS GetInputClock(WORD &wClock);
virtual ECHOSTATUS SetOutputClock(WORD wClock);
virtual ECHOSTATUS GetOutputClock(WORD &wClock);
//
// Audio Line Levels Functions:
// Nominal level is either -10dBV or +4dBu.
// Output level data is scaled by 256 and ranges from -128dB to
// +6dB (0xffff8000 to 0x600).
// Input level data is scaled by 256 and ranges from -25dB to +25dB
// ( 0xffffe700 to 0x1900 ).
//
virtual ECHOSTATUS GetAudioLineLevel
(
PMIXER_FUNCTION pMF
);
virtual ECHOSTATUS SetAudioLineLevel
(
PMIXER_FUNCTION pMF
);
virtual ECHOSTATUS GetAudioNominal
(
PMIXER_FUNCTION pMF
);
virtual ECHOSTATUS SetAudioNominal
(
PMIXER_FUNCTION pMF
);
//
// Audio mute controls
//
virtual ECHOSTATUS SetAudioMute
(
PMIXER_FUNCTION pMF
);
virtual ECHOSTATUS GetAudioMute
(
PMIXER_FUNCTION pMF
);
//
// Audio Monitors Functions:
//
virtual ECHOSTATUS SetAudioMonitor
(
WORD wBusIn,
WORD wBusOut,
INT32 iGain // New gain
);
virtual ECHOSTATUS GetAudioMonitor
(
WORD wBusIn,
WORD wBusOut,
INT32 & iGain // Returns current gain
);
virtual ECHOSTATUS SetAudioMonitorPan
(
WORD wBusIn,
WORD wBusOut,
INT32 iPan // New pan (0 - MAX_MIXER_PAN)
);
virtual ECHOSTATUS GetAudioMonitorPan
(
WORD wBusIn,
WORD wBusOut,
INT32 & iPan // Returns current pan (0 - MAX_MIXER_PAN)
);
virtual ECHOSTATUS SetAudioMonitorMute
(
WORD wBusIn,
WORD wBusOut,
BOOL bMute // New state
);
virtual ECHOSTATUS GetAudioMonitorMute
(
WORD wBusIn,
WORD wBusOut,
BOOL &bMute // Returns current state
);
//
// Get and set audio pan
//
virtual ECHOSTATUS GetAudioPan(PMIXER_FUNCTION pMixerFunction);
virtual ECHOSTATUS SetAudioPan(PMIXER_FUNCTION pMixerFunction);
//
// Get a bitmask of all the clocks the hardware is currently detecting
//
virtual ECHOSTATUS GetInputClockDetect(DWORD &dwClockDetectBits);
//***********************************************************************
//
// Audio transport (public) - playing and recording audio
//
//***********************************************************************
//
// Reserve a pipe. Please refer to the definition of
// ECHOGALS_OPENAUDIOPARAMETERS.
//
virtual ECHOSTATUS OpenAudio
(
PECHOGALS_OPENAUDIOPARAMETERS pOpenParameters, // Info on channel
PWORD pwPipeIndex // Ptr to pipe index
);
//
// Close a pipe
//
virtual ECHOSTATUS CloseAudio
(
PECHOGALS_CLOSEAUDIOPARAMETERS pCloseParameters
);
//
// Find out if the audio format is supported.
//
virtual ECHOSTATUS QueryAudioFormat
(
WORD wPipeIndex,
PECHOGALS_AUDIOFORMAT pAudioFormat
);
//
// Set the audio format for a single pipe
virtual ECHOSTATUS SetAudioFormat
(
WORD wPipeIndex,
PECHOGALS_AUDIOFORMAT pAudioFormat
);
//
// Set the audio format for a bunch of pipes at once
//
virtual ECHOSTATUS SetAudioFormat
(
PCChannelMask pChannelMask,
PECHOGALS_AUDIOFORMAT pAudioFormat
);
//
// Get the current audio format for a pipe
//
virtual ECHOSTATUS GetAudioFormat
(
WORD wPipeIndex,
PECHOGALS_AUDIOFORMAT pAudioFormat
);
//
// Call this to find out if this card can handle a given sample rate
//
virtual ECHOSTATUS QueryAudioSampleRate
(
DWORD dwSampleRate
)
{ return( ECHOSTATUS_NOT_SUPPORTED ); }
//
// I'm not going to tell you what the next two functions do; you'll just
// have to guess.
//
virtual ECHOSTATUS SetAudioSampleRate
(
DWORD dwSampleRate
);
virtual ECHOSTATUS GetAudioSampleRate
(
PDWORD pdwSampleRate
);
//
// Start transport for several pipes at once
//
virtual ECHOSTATUS Start
(
PCChannelMask pChannelMask
);
//
// Start transport for a single audio pipe
//
virtual ECHOSTATUS Start
(
WORD wPipeIndex
);
//
// Stop transport for several pipes at once
//
virtual ECHOSTATUS Stop
(
PCChannelMask pChannelMask
);
//
// Stop transport for a single pipe
//
virtual ECHOSTATUS Stop
(
WORD wPipeIndex
);
//
// Stop and reset selected output and/or input audio pipes
//
virtual ECHOSTATUS Reset
(
PCChannelMask pChannelMask
);
//
// Stop and reset single audio pipe
//
virtual ECHOSTATUS Reset
(
WORD wPipeIndex
);
//
// Get mask with active pipes - that is, those pipes that
// are currently moving data.
//
virtual ECHOSTATUS GetActivePipes
(
PCChannelMask pChannelMask
);
//
// Get mask with open pipes
//
virtual ECHOSTATUS GetOpenPipes
(
PCChannelMask pChannelMask
);
//
// Get a pointer that can be dereferenced to read
// the DSP's DMA counter for this pipe; see CEchoGals_transport.cpp
// for more info.
//
virtual ECHOSTATUS GetAudioPositionPtr
(
WORD wPipeIndex,
PDWORD (&pdwPosition)
);
//
// Get the daffy duck pointer for a pipe
//
CDaffyDuck *GetDaffyDuck(WORD wPipeIndex);
//
// Reset the 64 bit DMA position for this pipe
//
void ResetDmaPos( WORD wPipe );
//
// Update the 64 bit DMA position for this pipe
//
void UpdateDmaPos( WORD wPipeIndex );
//
// Get the 64 bit DMA position for this pipe
//
void GetDmaPos( WORD wPipeIndex, PULONGLONG pPos )
{
UpdateDmaPos( wPipeIndex );
*pPos = m_ullDmaPos[ wPipeIndex ];
}
//
// Get the state of a given pipe
//
DWORD GetPipeState( WORD wPipeIndex )
{
return (DWORD) m_byPipeState[ wPipeIndex ];
}
//
// Verify a pipe is open and ready for business!
//
ECHOSTATUS VerifyAudioOpen
(
WORD wPipeIndex
);
//***********************************************************************
//
// MIDI (public)
//
//***********************************************************************
#ifdef MIDI_SUPPORT
virtual ECHOSTATUS OpenMidiInput();
virtual ECHOSTATUS CloseMidiInput();
//
// Reset the MIDI input buffer; MIDI input remains enabled and open
//
virtual ECHOSTATUS ResetMidiInput();
virtual ECHOSTATUS WriteMidi
(
DWORD dwExpectedCt,
PBYTE pBuffer,
PDWORD pdwActualCt
);
virtual ECHOSTATUS ReadMidiByte(BYTE &Midi);
virtual BOOL MidiOutFull()
{
return GetDspCommObject()->MidiOutFull();
}
#endif // MIDI_SUPPORT
//***********************************************************************
//
// Interrupt handler methods (public)
//
//***********************************************************************
//
// This is called from within an interrupt handler. It starts interrupt
// handling. Returns error status if this interrupt is not ours.
// Returns ECHOSTATUS_OK if it is.
//
// OS dependent code handles routing to this point.
//
virtual ECHOSTATUS ServiceIrq(BOOL &fMidiReceived);
//***********************************************************************
//
// Power management (public)
//
// Please do not do silly things like try and set a volume level or
// play audio after calling GoComatose; be sure and call WakeUp first!
//
//***********************************************************************
//
// Tell the hardware to go to sleep
//
virtual ECHOSTATUS GoComatose();
//
// Tell the hardware to wake up
//
virtual ECHOSTATUS WakeUp();
protected:
//***********************************************************************
//
// Member variables (protected)
//
//***********************************************************************
PCOsSupport m_pOsSupport; // Ptr to OS Support methods & data
WORD m_wFlags; // See ECHOGALS_FLAG_??? flags defined
// in EchoGalsXface.h
PVOID m_pvSharedMemory; // Shared memory addr assigned by PNP
CHAR m_szCardInstallName[ ECHO_MAXNAMELEN ];
// Same as card except when multiple
// boards of the same type installed.
// Then becomes "Layla1", "Layla2" etc.
CChannelMask m_cmAudioOpen; // Audio channels open mask
CChannelMask m_cmAudioCyclic; // Audio use cyclic buffers mask
DWORD m_dwSampleRate; // Card sample rate in Hz
DWORD m_dwLockedSampleRate;
// Card sample rate when locked
ECHOGALS_AUDIO_PIPE
m_Pipes[ ECHO_MAXAUDIOPIPES ];
// Keep mapping info on open pipes
WORD m_wBytesPerSample[ ECHO_MAXAUDIOPIPES ];
// Keep conversion info on open pipes
BYTE m_byPipeState[ ECHO_MAXAUDIOPIPES ];
// Track state of all pipes
PVOID m_ProcessId[ ECHO_MAXAUDIOPIPES ];
// Caller process ID for implementing
// synchronous wave start
DWORD m_dwMeterOnCount; // Track need for meter updates by DSP
PCDspCommObject
m_pDspCommObject; // Ptr to DSP communication object
DWORD m_dwMidiInOpen; // Midi in channels open mask
DWORD m_dwMidiOutOpen; // Midi out channels open mask
BOOL m_fMixerDisabled;
//
// Monitor state info
//
CMonitorCtrl m_MonitorCtrl;
//
// Output pipe control
//
CPipeOutCtrl m_PipeOutCtrl;
//
// Input bus mute and gain settings
//
CBusInLineLevel m_BusInLineLevels[ ECHO_MAXAUDIOINPUTS ];
//
// Output bus mute and gain settings
//
CBusOutLineLevel m_BusOutLineLevels[ ECHO_MAXAUDIOOUTPUTS ];
//
//
// Linked list of mixer clients
//
ECHO_MIXER_CLIENT *m_pMixerClients;
//
// DMA position, in bytes, for each pipe
//
ULONGLONG m_ullDmaPos[ ECHO_MAXAUDIOPIPES ];
DWORD m_dwLastDspPos[ ECHO_MAXAUDIOPIPES ];
//
// Pointers to daffy ducks for each pipe
//
PCDaffyDuck m_DaffyDucks[ ECHO_MAXAUDIOPIPES ];
#ifdef MIDI_SUPPORT
//
// MIDI input buffer
//
CMidiInQ m_MidiIn;
#endif
//
// Macintosh compiler likes "class" after friend, PC doesn't care
//
friend class CLineLevel;
friend class CBusOutLineLevel;
friend class CBusInLineLevel;
friend class CPipeOutCtrl;
friend class CMonitorCtrl;
friend class CMidiInQ;
//***********************************************************************
//
// Initialization (protected)
//
//***********************************************************************
//
// Init the line level classes.
// This MUST be called from within any derived classes as part of
// InitHw after the DSP is up and running!
//
virtual ECHOSTATUS InitLineLevels();
//***********************************************************************
//
// Information (protected)
//
//***********************************************************************
ECHOSTATUS GetBaseCapabilities(PECHOGALS_CAPS pCapabilities);
WORD GetNumPipesOut();
WORD GetNumPipesIn();
WORD GetNumBussesOut();
WORD GetNumBussesIn();
WORD GetNumBusses();
WORD GetNumPipes();
WORD GetFirstDigitalBusOut();
WORD GetFirstDigitalBusIn();
BOOL HasVmixer();
PCDspCommObject GetDspCommObject();
//***********************************************************************
//
// Audio transport (protected)
//
// Daffy ducks are objects that manage scatter-gather lists.
//
//***********************************************************************
ECHOSTATUS MakeDaffyDuck(WORD wPipeIndex);
void KillDaffyDuck(WORD wPipeIndex);
//***********************************************************************
//
// Mixer interface (protected)
//
//***********************************************************************
//
// Match a mixer cookie to a mixer client
//
ECHO_MIXER_CLIENT *GetMixerClient(DWORD dwCookie);
//
// Adjust all the monitor levels for a particular output bus; this is
// used to implement the master output level.
//
ECHOSTATUS AdjustMonitorsForBusOut(WORD wBusOut);
//
// Adjust all the output pipe levels for a particular output bus; this is
// also used to implement the master output level.
//
virtual ECHOSTATUS AdjustPipesOutForBusOut(WORD wBusOut,int iBusOutGain);
//
// A mixer control has changed; store the notify
//
ECHOSTATUS MixerControlChanged
(
WORD wType, // One of the ECHO_CHANNEL_TYPES
WORD wParameter, // One of the MXN_* values
WORD wCh1 = ECHO_CHANNEL_UNUSED, // Depends on the wType value
WORD wCh2 = ECHO_CHANNEL_UNUSED // Also depends on wType value
);
#ifdef DIGITAL_INPUT_AUTO_MUTE_SUPPORT
//
// Digital input auto-mute - Gina24, Layla24, and Mona only
//
virtual ECHOSTATUS GetDigitalInAutoMute(PMIXER_FUNCTION pMixerFunction);
virtual ECHOSTATUS SetDigitalInAutoMute(PMIXER_FUNCTION pMixerFunction);
#endif
}; // class CEchoGals
typedef CEchoGals * PCEchoGals;
#endif
// *** CEchoGals.h ***

View File

@ -0,0 +1,197 @@
// ****************************************************************************
//
// CEchoGals_WDM.cpp
//
// Implementation file for the CEchoGals driver class.
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#pragma optimize("",off)
//
// Make new daffy ducks for all channels
//
ECHOSTATUS CEchoGals::MakeDaffyDuck(WORD wPipeIndex)
{
ECHOSTATUS Status = ECHOSTATUS_OK;
//---------------------------------------------------------
//
// Allocate the main daffy duck for this channel
//
//---------------------------------------------------------
m_pDaffyDucks[wPipeIndex] = new CDaffyDuck( m_pOsSupport,
GetDspCommObject(),
wPipeIndex );
if (NULL == m_pDaffyDucks[wPipeIndex])
{
return ECHOSTATUS_NO_MEM;
}
//
// Check the daffy duck
//
Status = m_pDaffyDucks[wPipeIndex]->InitCheck();
if (ECHOSTATUS_OK != Status)
{
return Status;
}
//
// Put the daffy duck in the comm page
//
GetDspCommObject()->
SetAudioDuckListPhys( wPipeIndex,
m_pDaffyDucks[wPipeIndex]->GetPhysStartAddr() );
return Status;
} // MakeDaffyDuck
//
// Kill the daffy duck for a pipe
//
void CEchoGals::KillDaffyDuck(WORD wPipeIndex)
{
if (NULL != m_pDaffyDucks[wPipeIndex])
{
delete m_pDaffyDucks[wPipeIndex];
m_pDaffyDucks[wPipeIndex] = NULL;
}
} // KillDaffyDuck
//
// Get the daffy duck for a given pipe index
//
CDaffyDuck *CEchoGals::GetDaffyDuck(WORD wPipeIndex)
{
if (wPipeIndex >= GetNumPipes())
return NULL;
return m_pDaffyDucks[wPipeIndex];
}
//
// Update the 64 bit DMA counter for this channel, allowing
// for DSP position counter wraparound.
//
void CEchoGals::UpdateDmaPos( WORD wPipeIndex )
{
DWORD dwDspPos;
DWORD dwDelta;
dwDspPos = GetDspCommObject()->GetAudioPosition( wPipeIndex );
dwDelta = dwDspPos - m_dwLastDspPos[ wPipeIndex ];
m_ullDmaPos[ wPipeIndex ] += dwDelta;
m_dwLastDspPos[ wPipeIndex ] = dwDspPos;
} // UpdateDmaPos
void CEchoGals::ResetDmaPos(WORD wCh)
{
m_ullDmaPos[ wCh ] = 0;
m_dwLastDspPos[ wCh ] = 0;
//
// There may still be mappings in the daffy duck; if so,
// tell them to reset their DMA positions starting at zero
//
if (NULL != m_pDaffyDucks[wCh])
m_pDaffyDucks[wCh]->ResetStartPos();
}
#ifdef SIMPHONICS_EXTENSIONS
/*-----------------------------------------------------------------------------
CEchoGals::SetMixerUberGain
Set an array of gains to simultaneously set all monitor, virtual output,
and output bus gains, as per the SimPhonics specifications.
The structure of the array is as follows:
Monitor gains
0 I0->O0 I1->O0 ... I15->O0
16 I0->O1 I1->O1 ... I15->O1
...
240 I0->O15 I1->O15 ... I15->O15
Virtual output gains
256 V0->O0 V1->O0 ... V15->O0
272 V0->O1 V1->O1 ... V15->O1
...
498 V0->O15 V1->O15 ... V15->O15
Master output bus gains
512 B0 B1 ... B15
Values are signed bytes, ranging from +6 to -128 dB.
Right now, this is hard-coded for Layla24v - 16 inputs,
16 output busses, 16 virtual outputs.
-----------------------------------------------------------------------------*/
#define LAYLA24V_CHANNELS 16
ECHOSTATUS CEchoGals::SetLayla24vUberGain(LAYLA24V_UBER_GAIN *pLug)
{
if (GetDspCommObject())
GetDspCommObject()->SetLayla24vUberGain(pLug);
return ECHOSTATUS_OK;
} // SetLayla24vMixerUberGain
#endif // SIMPHONICS_EXTENSIONS

View File

@ -0,0 +1,289 @@
// ****************************************************************************
//
// CEchoGals_info.cpp
//
// Implementation file for the CEchoGals driver class (info functions).
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
/****************************************************************************
CEchoGals informational methods
****************************************************************************/
//===========================================================================
//
// GetBaseCapabilities is used by the CEchoGals-derived classes to
// help fill out the ECHOGALS_CAPS struct.
//
//===========================================================================
ECHOSTATUS CEchoGals::GetBaseCapabilities
(
PECHOGALS_CAPS pCapabilities
)
{
CChannelMask DigMask, ChMask, AdatMask;
WORD i;
//
// Test only for no DSP object. We can still get capabilities even if
// board is bad.
//
if ( NULL == GetDspCommObject() )
return ECHOSTATUS_DSP_DEAD;
memset( pCapabilities, 0, sizeof(ECHOGALS_CAPS) );
strcpy( pCapabilities->szName, m_szCardInstallName );
pCapabilities->wCardType = GetDspCommObject()->GetCardType();
pCapabilities->wNumPipesOut = GetNumPipesOut();
pCapabilities->wNumPipesIn = GetNumPipesIn();
pCapabilities->wNumBussesOut = GetNumBussesOut();
pCapabilities->wNumBussesIn = GetNumBussesIn();
pCapabilities->wFirstDigitalBusOut = GetFirstDigitalBusOut();
pCapabilities->wFirstDigitalBusIn = GetFirstDigitalBusIn();
pCapabilities->wNumMidiOut = GetDspCommObject()->GetNumMidiOutChannels();
pCapabilities->wNumMidiIn = GetDspCommObject()->GetNumMidiInChannels();
pCapabilities->dwOutClockTypes = 0;
pCapabilities->dwInClockTypes = ECHO_CLOCK_BIT_INTERNAL;;
//
// Add the controls to the output pipes that are
// the same for all cards
//
for (i = 0; i < GetNumPipesOut(); i++)
{
pCapabilities->dwPipeOutCaps[i] = ECHOCAPS_GAIN |
ECHOCAPS_MUTE;
}
//
// Add controls to the input busses that are the same for all cards
//
WORD wFirstDigitalBusIn = GetFirstDigitalBusIn();
for (i = 0; i < GetNumBussesIn(); i++)
{
pCapabilities->dwBusInCaps[i] = ECHOCAPS_PEAK_METER |
ECHOCAPS_VU_METER;
if (i >= wFirstDigitalBusIn)
pCapabilities->dwBusInCaps[i] |= ECHOCAPS_DIGITAL;
}
//
// And the output busses
//
WORD wFirstDigitalBusOut = GetFirstDigitalBusOut();
for (i = 0; i < GetNumBussesOut(); i++)
{
pCapabilities->dwBusOutCaps[i] = ECHOCAPS_PEAK_METER |
ECHOCAPS_VU_METER |
ECHOCAPS_GAIN |
ECHOCAPS_MUTE;
if (i >= wFirstDigitalBusOut)
pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_DIGITAL;
}
//
// Digital modes & vmixer flag
//
pCapabilities->dwDigitalModes = GetDspCommObject()->GetDigitalModes();
pCapabilities->fHasVmixer = GetDspCommObject()->HasVmixer();
//
// If this is not a vmixer card, output pipes are hard-wired to output busses.
// Mark those pipes that are hard-wired to digital busses as digital pipes
//
if (GetDspCommObject()->HasVmixer())
{
pCapabilities->wFirstDigitalPipeOut = pCapabilities->wNumPipesOut;
}
else
{
pCapabilities->wFirstDigitalPipeOut = pCapabilities->wFirstDigitalBusOut;
for ( i = pCapabilities->wFirstDigitalPipeOut;
i < GetNumPipesOut();
i++)
{
pCapabilities->dwPipeOutCaps[i] |= ECHOCAPS_DIGITAL;
}
}
//
// Input pipes are the same, vmixer or no vmixer
//
pCapabilities->wFirstDigitalPipeIn = pCapabilities->wFirstDigitalBusIn;
for ( i = pCapabilities->wFirstDigitalPipeIn;
i < GetNumPipesIn();
i++)
{
pCapabilities->dwPipeInCaps[i] |= ECHOCAPS_DIGITAL;
}
return ECHOSTATUS_OK;
} // ECHOSTATUS CEchoGals::GetBaseCapabilities
//===========================================================================
//
// MakePipeIndex is a utility function; it takes a pipe number and an
// input or output flag and returns the pipe index. Refer to
// EchoGalsXface.h for more information.
//
//===========================================================================
WORD CEchoGals::MakePipeIndex(WORD wPipe,BOOL fInput)
{
if (fInput)
return wPipe + GetNumPipesOut();
return wPipe;
} // MakePipeIndex
//===========================================================================
//
// Get the card name as an ASCII zero-terminated string
//
//===========================================================================
CONST PCHAR CEchoGals::GetDeviceName()
{
return m_szCardInstallName;
}
//===========================================================================
//
// Get numbers of pipes and busses
//
//===========================================================================
WORD CEchoGals::GetNumPipesOut()
{
if (NULL == GetDspCommObject())
return 0;
return GetDspCommObject()->GetNumPipesOut();
}
WORD CEchoGals::GetNumPipesIn()
{
if (NULL == GetDspCommObject())
return 0;
return GetDspCommObject()->GetNumPipesIn();
}
WORD CEchoGals::GetNumBussesOut()
{
if (NULL == GetDspCommObject())
return 0;
return GetDspCommObject()->GetNumBussesOut();
}
WORD CEchoGals::GetNumBussesIn()
{
if (NULL == GetDspCommObject())
return 0;
return GetDspCommObject()->GetNumBussesIn();
}
WORD CEchoGals::GetNumBusses()
{
if (NULL == GetDspCommObject())
return 0;
return GetDspCommObject()->GetNumBusses();
}
WORD CEchoGals::GetNumPipes()
{
if (NULL == GetDspCommObject())
return 0;
return GetDspCommObject()->GetNumPipes();
}
WORD CEchoGals::GetFirstDigitalBusOut()
{
if (NULL == GetDspCommObject())
return 0;
return GetDspCommObject()->GetFirstDigitalBusOut();
}
WORD CEchoGals::GetFirstDigitalBusIn()
{
if (NULL == GetDspCommObject())
return 0;
return GetDspCommObject()->GetFirstDigitalBusIn();
}
BOOL CEchoGals::HasVmixer()
{
if (NULL == GetDspCommObject())
return 0;
return GetDspCommObject()->HasVmixer();
}
//===========================================================================
//
// Get access to the DSP comm object
//
//===========================================================================
PCDspCommObject CEchoGals::GetDspCommObject()
{
return m_pDspCommObject;
}

View File

@ -0,0 +1,143 @@
// ****************************************************************************
//
// CEchoGals_midi.cpp
//
// Implementation file for the CEchoGals driver class (midi functions).
//
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#ifdef MIDI_SUPPORT
/****************************************************************************
MIDI output
****************************************************************************/
//===========================================================================
//
// Write a bunch of MIDI data to the MIDI output
//
// The DSP only buffers up 16 bytes internally for MIDI output; if you try
// to send more than the DSP can handle, the actual count sent will be returned
// to you and you get ECHOSTATUS_BUSY as the return value.
//
//===========================================================================
ECHOSTATUS CEchoGals::WriteMidi
(
DWORD dwExpectedCt,
PBYTE pBuffer,
PDWORD pdwActualCt
)
{
return GetDspCommObject()->WriteMidi( pBuffer,
dwExpectedCt,
pdwActualCt );
} // ECHOSTATUS CLayla24::WriteMidi
/****************************************************************************
MIDI input
****************************************************************************/
//===========================================================================
//
// Read a single MIDI byte from the circular MIDI input buffer
//
//===========================================================================
ECHOSTATUS CEchoGals::ReadMidiByte(BYTE &Midi)
{
return m_MidiIn.GetMidi(Midi);
} // ReadMidiByte
//===========================================================================
//
// Open and enable the MIDI input
//
//===========================================================================
ECHOSTATUS CEchoGals::OpenMidiInput()
{
return m_MidiIn.Arm();
} // OpenMidiInput
//===========================================================================
//
// Close and disable the MIDI input
//
//===========================================================================
ECHOSTATUS CEchoGals::CloseMidiInput()
{
m_MidiIn.Disarm();
return ECHOSTATUS_OK;
}
//===========================================================================
//
// Reset the MIDI input, but leave it open and enabled
//
//===========================================================================
ECHOSTATUS CEchoGals::ResetMidiInput()
{
m_MidiIn.Reset();
return ECHOSTATUS_OK;
}
#endif // MIDI_SUPPORT

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
// ****************************************************************************
//
// CEchoGals_mixer.h
//
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _CEchoGals_mixer_h_
#define _CEchoGals_mixer_h_
//===========================================================================
//
// Mixer client stuff
//
//===========================================================================
//
// Max number of notifies stored per card
//
#define MAX_MIXER_NOTIFIES 2048
//
// Structure describing a mixer client. The notifies are stored in a circular
// buffer
//
typedef struct tECHO_MIXER_CLIENT
{
DWORD dwCookie; // Unique ID for this client
DWORD dwCount;
DWORD dwHead;
DWORD dwTail;
MIXER_NOTIFY Notifies[MAX_MIXER_NOTIFIES];
struct tECHO_MIXER_CLIENT *pNext;
} ECHO_MIXER_CLIENT;
#endif // _CEchoGals_mixer_h_

View File

@ -0,0 +1,107 @@
// ****************************************************************************
//
// CEchoGals_power.cpp
//
// Power management functions for the CEchoGals driver class.
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
//===========================================================================
//
// Tell the hardware to go into a low-power state - the converters are
// shut off and the DSP powers down.
//
//===========================================================================
ECHOSTATUS CEchoGals::GoComatose()
{
//
// Pass the call through to the DSP comm object
//
return GetDspCommObject()->GoComatose();
} // GoComatose
//===========================================================================
//
// Tell the hardware to wake up - go back to the full-power state
//
// You can call WakeUp() if you just want to be sure
// that the firmware is loaded OK
//
//===========================================================================
ECHOSTATUS CEchoGals::WakeUp()
{
//
// Load the firmware
//
ECHOSTATUS Status;
CDspCommObject *pDCO = GetDspCommObject();
Status = pDCO->LoadFirmware();
// fixme need to not do this if the DSP was already awake
if (ECHOSTATUS_OK == Status)
{
//
// For any pipes that have daffy ducks,
// reset the pointer to the first PLE in the comm page
//
WORD wPipeIndex;
for (wPipeIndex = 0; wPipeIndex < GetNumPipes(); wPipeIndex++)
{
if (NULL != m_DaffyDucks[wPipeIndex])
{
DWORD dwPhysStartAddr;
dwPhysStartAddr = m_DaffyDucks[wPipeIndex]->GetPhysStartAddr();
pDCO->SetAudioDuckListPhys(wPipeIndex,dwPhysStartAddr);
}
}
}
return Status;
} // WakeUp

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
// ****************************************************************************
//
// CGMLDspCommObject.H
//
// Common DSP interface class for Gina24, Layla24, and Mona
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _GMLDSPCOMMOBJECT_
#define _GMLDSPCOMMOBJECT_
class CGMLDspCommObject : public CDspCommObject
{
public:
CGMLDspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport )
: CDspCommObject(pdwRegBase, pOsSupport)
{
}
virtual ~CGMLDspCommObject() {}
protected:
//
// Set get S/PDIF output format
//
virtual void SetProfessionalSpdif( BOOL bNewStatus );
virtual BOOL IsProfessionalSpdif()
{ return( m_bProfessionalSpdif ); }
//
// Write the Gina24/Mona/Layla24 control reg
//
virtual ECHOSTATUS WriteControlReg( DWORD dwControlReg );
//
// Member variables
//
BOOL m_bProfessionalSpdif;
}; // class CGMLDspCommObject
#endif // _GMLDSPCOMMOBJECT_
// **** GMLDspCommObject.h ****

View File

@ -0,0 +1,229 @@
// ****************************************************************************
//
// CGdDspCommObject.cpp
//
// Implementation file for Gina20/Darla20 DSP interface class.
//
// Darla20 and Gina20 are very similar; this class is used for both.
// CGinaDspCommObject and CDarlaDspCommObject dervie from this class, in
// turn.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CGinaDspCommObject.h"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CGdDspCommObject::CGdDspCommObject
(
PDWORD pdwRegBase, // Virtual ptr to DSP registers
PCOsSupport pOsSupport
) : CDspCommObject( pdwRegBase, pOsSupport )
{
m_byGDCurrentSpdifStatus = GD_SPDIF_STATUS_UNDEF;
m_byGDCurrentClockState = GD_CLOCK_UNDEF;
} // CGdDspCommObject::CGinaDspCommObject( DWORD dwPhysRegBase )
//===========================================================================
//
// Destructor
//
//===========================================================================
CGdDspCommObject::~CGdDspCommObject()
{
} // CGdDspCommObject::~CGdDspCommObject()
/****************************************************************************
Hardware config
****************************************************************************/
//===========================================================================
//
// Called after LoadFirmware to restore old gains, meters on, monitors, etc.
// No error checking is done here.
//
//===========================================================================
void CGdDspCommObject::RestoreDspSettings()
{
m_pDspCommPage->byGDClockState = GD_CLOCK_UNDEF;
m_pDspCommPage->byGDSpdifStatus = GD_SPDIF_STATUS_UNDEF;
CDspCommObject::RestoreDspSettings();
} // void CLaylaDspCommObject::RestoreDspSettings()
//===========================================================================
//
// SetSampleRate
//
// Set the audio sample rate for Gina/Darla
//
// For Gina and Darla, three parameters need to be set: the resampler state,
// the clock state, and the S/PDIF output status state. The idea is that
// these parameters are changed as infrequently as possible.
//
// Resampling is no longer supported.
//
//===========================================================================
DWORD CGdDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
{
BYTE byGDClockState, byGDSpdifStatus;
DWORD fUseSpdifInClock;
if ( !WaitForHandshake() )
return ECHOSTATUS_DSP_DEAD;
//
// Pick the clock
//
fUseSpdifInClock = (GetCardType() == GINA) &&
(GetInputClock() == ECHO_CLOCK_SPDIF);
if (fUseSpdifInClock)
{
byGDClockState = GD_CLOCK_SPDIFIN;
}
else
{
switch (dwNewSampleRate)
{
case 44100 :
byGDClockState = GD_CLOCK_44;
break;
case 48000 :
byGDClockState = GD_CLOCK_48;
break;
default :
byGDClockState = GD_CLOCK_NOCHANGE;
break;
}
}
if ( m_byGDCurrentClockState == byGDClockState )
{
byGDClockState = GD_CLOCK_NOCHANGE;
}
//
// Select S/PDIF output status
//
byGDSpdifStatus = SelectGinaDarlaSpdifStatus( dwNewSampleRate );
//
// Write the audio state to the comm page
//
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
m_pDspCommPage->byGDClockState = byGDClockState;
m_pDspCommPage->byGDSpdifStatus = byGDSpdifStatus;
m_pDspCommPage->byGDResamplerState = 3; // magic number -
// should always be 3
//
// Send command to DSP
//
ClearHandshake();
SendVector( DSP_VC_SET_GD_AUDIO_STATE );
//
// Save the new audio state
//
if ( byGDClockState != GD_CLOCK_NOCHANGE )
m_byGDCurrentClockState = byGDClockState;
if ( byGDSpdifStatus != GD_SPDIF_STATUS_NOCHANGE )
m_byGDCurrentSpdifStatus = byGDSpdifStatus;
return dwNewSampleRate;
} // DWORD CGdDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
//===========================================================================
//
// SelectGinaDarlaSpdifStatus
//
//===========================================================================
BYTE CGdDspCommObject::SelectGinaDarlaSpdifStatus( DWORD dwNewSampleRate )
{
BYTE byNewStatus = 0;
switch (dwNewSampleRate)
{
case 44100 :
byNewStatus = GD_SPDIF_STATUS_44;
break;
case 48000 :
byNewStatus = GD_SPDIF_STATUS_48;
break;
default :
byNewStatus = GD_SPDIF_STATUS_NOCHANGE;
break;
}
if (byNewStatus == m_byGDCurrentSpdifStatus)
{
byNewStatus = GD_SPDIF_STATUS_NOCHANGE;
}
return byNewStatus;
} // BYTE CGdDspCommObject::SelectGinaDarlaSpdifStatus( DWORD dwNewSampleRate )
// **** GinaDspCommObject.cpp ****

View File

@ -0,0 +1,89 @@
// ****************************************************************************
//
// CGdDspCommObject.H
//
// Darla20 and Gina20 are very similar; this class is used for both.
// CGinaDspCommObject and CDarlaDspCommObject dervie from this class, in
// turn.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _GDDSPCOMMOBJECT_
#define _GDDSPCOMMOBJECT_
#include "CDspCommObject.h"
class CGdDspCommObject : public CDspCommObject
{
public:
//
// Construction/destruction
//
CGdDspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport );
virtual ~CGdDspCommObject();
//
// Set the DSP sample rate.
// Return rate that was set, -1 if error
//
virtual DWORD SetSampleRate( DWORD dwNewSampleRate );
//
// Send current setting to DSP & return what it is
//
virtual DWORD SetSampleRate()
{ return SetSampleRate( GetSampleRate() ); }
protected:
BYTE m_byGDCurrentSpdifStatus;
BYTE m_byGDCurrentClockState;
//
// Called after load firmware to restore old gains, meters on, monitors, etc.
// No error checking is done here.
//
virtual void RestoreDspSettings();
// SelectGinaDarlaSpdifStatus
BYTE SelectGinaDarlaSpdifStatus( DWORD dwNewSampleRate );
}; // class CGdDspCommObject
typedef CGdDspCommObject * PCGdDspCommObject;
#endif
// **** GdDspCommObject.h ****

View File

@ -0,0 +1,276 @@
// ****************************************************************************
//
// CGina.cpp
//
// Implementation file for the CGina driver class. CGina is for
// 20-bit Gina, not Gina24.
//
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CGina.h"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CGina::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CGina::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CGina::operator new( size_t Size )
VOID CGina::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("CGina::operator delete memory free failed\n"));
}
} // VOID CGina::operator delete( PVOID pVoid )
//===========================================================================
//
// Constructor and destructor
//
//===========================================================================
CGina::CGina( PCOsSupport pOsSupport )
: CEchoGals( pOsSupport )
{
ECHO_DEBUGPRINTF( ( "CGina::CGina() is born!\n" ) );
}
CGina::~CGina()
{
ECHO_DEBUGPRINTF( ( "CGina::~CGina() is toast!\n" ) );
}
/****************************************************************************
Setup and hardware initialization
****************************************************************************/
//===========================================================================
//
// Every card has an InitHw method
//
//===========================================================================
ECHOSTATUS CGina::InitHw()
{
ECHOSTATUS Status;
//
// Call the base method
//
if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
return Status;
//
// Create the DSP comm object
//
ASSERT( NULL == m_pDspCommObject );
m_pDspCommObject = new CGinaDspCommObject( (PDWORD) m_pvSharedMemory,
m_pOsSupport );
if (NULL == m_pDspCommObject)
{
ECHO_DEBUGPRINTF(("CGina::InitHw - could not create DSP comm object\n"));
return ECHOSTATUS_NO_MEM;
}
//
// Load the firmware
//
GetDspCommObject()->LoadFirmware();
if ( GetDspCommObject()->IsBoardBad() )
return ECHOSTATUS_DSP_DEAD;
//
// Clear the "bad board" flag
//
m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
//
// Must call this here after DSP is init to
// init gains and mutes
//
Status = InitLineLevels();
//
// Set the S/PDIF output format to "professional"
//
SetProfessionalSpdif( TRUE );
//
// Get default sample rate from DSP
//
m_dwSampleRate = GetDspCommObject()->GetSampleRate();
ECHO_DEBUGPRINTF( ( "CGina::InitHw()\n" ) );
return Status;
} // ECHOSTATUS CGina::InitHw()
/****************************************************************************
Informational methods
****************************************************************************/
//===========================================================================
//
// Override GetCapabilities to enumerate unique capabilties for this card
//
//===========================================================================
ECHOSTATUS CGina::GetCapabilities
(
PECHOGALS_CAPS pCapabilities
)
{
WORD i;
GetBaseCapabilities(pCapabilities);
//
// Add input gain to input busses
//
for (i = 0; i < GetFirstDigitalBusIn(); i++)
{
pCapabilities->dwBusInCaps[i] |= ECHOCAPS_GAIN |
ECHOCAPS_MUTE;
}
pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_SPDIF;
return ECHOSTATUS_OK;
}
//===========================================================================
//
// GetInputClockDetect returns a bitmask consisting of all the input
// clocks currently connected to the hardware; this changes as the user
// connects and disconnects clock inputs.
//
// You should use this information to determine which clocks the user is
// allowed to select.
//
// Gina20 only supports S/PDIF input clock.
//
//===========================================================================
ECHOSTATUS CGina::GetInputClockDetect(DWORD &dwClockDetectBits)
{
if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
{
ECHO_DEBUGPRINTF( ("CGina::GetInputClockDetect: DSP Dead!\n") );
return ECHOSTATUS_DSP_DEAD;
}
DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SPDIF))
dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
return ECHOSTATUS_OK;
} // GetInputClockDetect
//===========================================================================
//
// QueryAudioSampleRate is used to find out if this card can handle a
// given sample rate.
//
//===========================================================================
ECHOSTATUS CGina::QueryAudioSampleRate
(
DWORD dwSampleRate
)
{
if ( dwSampleRate != 44100 &&
dwSampleRate != 48000 )
{
ECHO_DEBUGPRINTF(
("CGina::QueryAudioSampleRate() Sample rate must be "
"44,100 Hz or 48,000 Hz\n") );
return ECHOSTATUS_BAD_FORMAT;
}
ECHO_DEBUGPRINTF( ( "CGina::QueryAudioSampleRate()\n" ) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CGina::QueryAudioSampleRate
// *** CGina.cpp ***

View File

@ -0,0 +1,108 @@
// ****************************************************************************
//
// CGina.H
//
// Include file for interfacing with the CGina generic driver class
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _GINAOBJECT_
#define _GINAOBJECT_
#include "CEchoGals.h"
#include "CGinaDspCommObject.h"
//
// Class used for interfacing with the Gina audio card.
//
class CGina : public CEchoGals
{
public:
//
// Construction/destruction
//
CGina( PCOsSupport pOsSupport );
virtual ~CGina();
//
// Setup & initialization methods
//
virtual ECHOSTATUS InitHw();
//
// Adapter information methods
//
virtual ECHOSTATUS GetCapabilities
(
PECHOGALS_CAPS pCapabilities
);
//
// Get a bitmask of all the clocks the hardware is currently detecting
//
virtual ECHOSTATUS GetInputClockDetect(DWORD &dwClockDetectBits);
//
// Audio Interface methods
//
virtual ECHOSTATUS QueryAudioSampleRate
(
DWORD dwSampleRate
);
//
// Overload new & delete so memory for this object is allocated from non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
protected:
//
// Get access to the appropriate DSP comm object
//
PCGinaDspCommObject GetDspCommObject()
{ return( (PCGinaDspCommObject) m_pDspCommObject ); }
}; // class CGina
typedef CGina * PCGina;
#endif
// *** CGina.H ***

View File

@ -0,0 +1,340 @@
// ****************************************************************************
//
// CGina24.cpp
//
// Implementation file for the CGina24 driver class.
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CGina24.h"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CGina24::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CGina::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CGina24::operator new( size_t Size )
VOID CGina24::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("CGina24::operator delete memory free failed\n"));
}
} // VOID CGina24::operator delete( PVOID pVoid )
//===========================================================================
//
// Constructor and destructor
//
//===========================================================================
CGina24::CGina24( PCOsSupport pOsSupport )
: CEchoGals( pOsSupport )
{
ECHO_DEBUGPRINTF( ( "CGina24::CGina24() is born!\n" ) );
}
CGina24::~CGina24()
{
ECHO_DEBUGPRINTF( ( "CGina24::~CGina24() is toast!\n" ) );
}
/****************************************************************************
Setup and hardware initialization
****************************************************************************/
//===========================================================================
//
// Every card has an InitHw method
//
//===========================================================================
ECHOSTATUS CGina24::InitHw()
{
ECHOSTATUS Status;
//
// Call the base method
//
if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
return Status;
//
// Create the DSP comm object
//
ASSERT( NULL == m_pDspCommObject );
m_pDspCommObject = new CGina24DspCommObject( (PDWORD) m_pvSharedMemory,
m_pOsSupport );
if (NULL == m_pDspCommObject)
{
ECHO_DEBUGPRINTF(("CGina24::InitHw - could not create DSP comm object\n"));
return ECHOSTATUS_NO_MEM;
}
ASSERT( GetDspCommObject() );
//
// Load the DSP and the ASIC on the PCI card
//
GetDspCommObject()->LoadFirmware();
if ( GetDspCommObject()->IsBoardBad() )
return ECHOSTATUS_DSP_DEAD;
//
// Clear the "bad board" flag; set the flags to indicate that
// Gina24 can handle super-interleave and supports the digital
// input auto-mute.
//
m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK |
ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE;
//
// Must call this here after DSP is init to
// init gains and mutes
//
Status = InitLineLevels();
if ( ECHOSTATUS_OK != Status )
return Status;
//
// Set defaults for +4/-10
//
WORD i;
for (i = 0; i < GetFirstDigitalBusOut(); i++ )
{
Status = GetDspCommObject()->
SetNominalLevel( i, FALSE ); // FALSE is +4 here
}
for ( i = 0; i < GetFirstDigitalBusIn(); i++ )
{
Status = GetDspCommObject()->
SetNominalLevel( GetNumBussesOut() + i, FALSE );
}
//
// Set the digital mode to S/PDIF RCA
//
SetDigitalMode( DIGITAL_MODE_SPDIF_RCA );
//
// Set the S/PDIF output format to "professional"
//
SetProfessionalSpdif( TRUE );
//
// Get default sample rate from DSP
//
m_dwSampleRate = GetDspCommObject()->GetSampleRate();
ECHO_DEBUGPRINTF( ( "CGina24::InitHw()\n" ) );
return Status;
} // ECHOSTATUS CGina24::InitHw()
/****************************************************************************
Informational methods
****************************************************************************/
//===========================================================================
//
// Override GetCapabilities to enumerate unique capabilties for Gina24
//
//===========================================================================
ECHOSTATUS CGina24::GetCapabilities
(
PECHOGALS_CAPS pCapabilities
)
{
ECHOSTATUS Status;
Status = GetBaseCapabilities(pCapabilities);
//
// Add nominal level control to analog ins & outs
//
WORD i;
for (i = 0 ; i < GetFirstDigitalBusOut(); i++)
{
pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
}
for (i = 0 ; i < GetFirstDigitalBusIn(); i++)
{
pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
}
if ( ECHOSTATUS_OK != Status )
return Status;
pCapabilities->dwInClockTypes |=
ECHO_CLOCK_BIT_SPDIF |
ECHO_CLOCK_BIT_ESYNC |
ECHO_CLOCK_BIT_ESYNC96 |
ECHO_CLOCK_BIT_ADAT;
return Status;
} // ECHOSTATUS CGina24::GetCapabilities
//===========================================================================
//
// QueryAudioSampleRate is used to find out if this card can handle a
// given sample rate.
//
//===========================================================================
ECHOSTATUS CGina24::QueryAudioSampleRate
(
DWORD dwSampleRate
)
{
if ( dwSampleRate != 8000 &&
dwSampleRate != 11025 &&
dwSampleRate != 16000 &&
dwSampleRate != 22050 &&
dwSampleRate != 32000 &&
dwSampleRate != 44100 &&
dwSampleRate != 48000 &&
dwSampleRate != 88200 &&
dwSampleRate != 96000 )
{
ECHO_DEBUGPRINTF(
("CGina24::QueryAudioSampleRate() Sample rate must be "
" 8,000 Hz, 11,025 Hz, 16,000 Hz, 22,050 Hz, 32,000 Hz, "
"44,100 Hz, 48,000 Hz, 88,200 Hz or 96,000 Hz\n") );
return ECHOSTATUS_BAD_FORMAT;
}
if ( dwSampleRate >= 88200 && DIGITAL_MODE_ADAT == GetDigitalMode() )
{
ECHO_DEBUGPRINTF(
("CGina24::QueryAudioSampleRate() Sample rate cannot be "
"set to 88,200 Hz or 96,000 Hz in ADAT mode\n") );
return ECHOSTATUS_BAD_FORMAT;
}
ECHO_DEBUGPRINTF( ( "CGina24::QueryAudioSampleRate()\n" ) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CGina24::QueryAudioSampleRate
//===========================================================================
//
// GetInputClockDetect returns a bitmask consisting of all the input
// clocks currently connected to the hardware; this changes as the user
// connects and disconnects clock inputs.
//
// You should use this information to determine which clocks the user is
// allowed to select.
//
// Gina24 supports S/PDIF, Esync, and ADAT input clocks.
//
//===========================================================================
ECHOSTATUS CGina24::GetInputClockDetect(DWORD &dwClockDetectBits)
{
//ECHO_DEBUGPRINTF(("CGina24::GetInputClockDetect\n"));
if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
{
ECHO_DEBUGPRINTF( ("CGina24::GetInputClockDetect: DSP Dead!\n") );
return ECHOSTATUS_DSP_DEAD;
}
//
// Map the DSP clock detect bits to the generic driver clock detect bits
//
DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF))
dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT))
dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT;
if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ESYNC))
dwClockDetectBits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96;
return ECHOSTATUS_OK;
} // GetInputClockDetect
// *** CGina24.cpp ***

View File

@ -0,0 +1,117 @@
// ****************************************************************************
//
// CGina24.H
//
// Include file for interfacing with the CGina24 generic driver class
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _GINA24OBJECT_
#define _GINA24OBJECT_
#include "CEchoGals.h"
#include "CGina24DspCommObject.h"
//
// Class used for interfacing with the Darla audio card.
//
class CGina24 : public CEchoGals
{
public:
//
// Construction/destruction
//
CGina24( PCOsSupport pOsSupport );
virtual ~CGina24();
//
// Setup & initialization methods
//
virtual ECHOSTATUS InitHw();
//
// Adapter information methods
//
//
// Return the capabilities of this card; card type, card name,
// # analog inputs, # analog outputs, # digital channels,
// # MIDI ports and supported clocks.
// See ECHOGALS_CAPS definition above.
//
virtual ECHOSTATUS GetCapabilities
(
PECHOGALS_CAPS pCapabilities
);
//
// Audio Interface methods
//
virtual ECHOSTATUS QueryAudioSampleRate
(
DWORD dwSampleRate
);
//
// Get a bitmask of all the clocks the hardware is currently detecting
//
virtual ECHOSTATUS GetInputClockDetect(DWORD &dwClockDetectBits);
//
// Overload new & delete so memory for this object is allocated from
// non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
protected:
//
// Get access to the appropriate DSP comm object
//
PCGina24DspCommObject GetDspCommObject()
{ return( (PCGina24DspCommObject) m_pDspCommObject ); }
}; // class CGina24
typedef CGina24 * PCGina24;
#endif
// *** CGina24.H ***

View File

@ -0,0 +1,658 @@
// ****************************************************************************
//
// CGina24DspCommObject.cpp
//
// Implementation file for Gina24 DSP interface class.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CGina24DspCommObject.h"
#include "Gina24DSP.c"
#include "Gina24_361DSP.c"
#include "Gina24ASIC.c"
#include "Gina24ASIC_361.c"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CGina24DspCommObject::CGina24DspCommObject
(
PDWORD pdwRegBase, // Virtual ptr to DSP registers
PCOsSupport pOsSupport
) : CGMLDspCommObject( pdwRegBase, pOsSupport )
{
strcpy( m_szCardName, "Gina24" );
m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base
m_wNumPipesOut = 16;
m_wNumPipesIn = 10;
m_wNumBussesOut = 16;
m_wNumBussesIn = 10;
m_wFirstDigitalBusOut = 8;
m_wFirstDigitalBusIn = 2;
m_fHasVmixer = FALSE;
m_wNumMidiOut = 0; // # MIDI out channels
m_wNumMidiIn = 0; // # MIDI in channels
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 44100 );
// Need this in cse we start with ESYNC
m_bHasASIC = TRUE;
//
// Gina24 comes in both '301 and '361 flavors; pick the correct one.
//
if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() )
m_pwDspCodeToLoad = pwGina24_361DSP;
else
m_pwDspCodeToLoad = pwGina24DSP;
m_byDigitalMode = DIGITAL_MODE_SPDIF_RCA;
m_bProfessionalSpdif = FALSE;
} // CGina24DspCommObject::CGina24DspCommObject( DWORD dwPhysRegBase )
//===========================================================================
//
// Destructor
//
//===========================================================================
CGina24DspCommObject::~CGina24DspCommObject()
{
ECHO_DEBUGPRINTF(("CGina24DspCommObject::~CGina24DspCommObject - "
"hasta la vista!\n"));
} // CGina24DspCommObject::~CGina24DspCommObject()
/****************************************************************************
Hardware setup and config
****************************************************************************/
//===========================================================================
//
// Gina24 has an ASIC on the PCI card which must be loaded for anything
// interesting to happen.
//
//===========================================================================
BOOL CGina24DspCommObject::LoadASIC()
{
DWORD dwControlReg, dwSize;
PBYTE pbAsic;
if ( m_bASICLoaded )
return TRUE;
//
// Give the DSP a few milliseconds to settle down
//
m_pOsSupport->OsSnooze( 10000 );
//
// Pick the correct ASIC for '301 or '361 Gina24
//
if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() )
{
pbAsic = pbGina24ASIC_361;
dwSize = sizeof( pbGina24ASIC_361 );
}
else
{
pbAsic = pbGina24ASIC;
dwSize = sizeof( pbGina24ASIC );
}
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_GINA24_ASIC,
pbAsic,
dwSize ) )
return FALSE;
m_pbyAsic = pbAsic;
//
// Now give the new ASIC a little time to set up
//
m_pOsSupport->OsSnooze( 10000 );
//
// See if it worked
//
CheckAsicStatus();
//
// Set up the control register if the load succeeded -
//
// 48 kHz, internal clock, S/PDIF RCA mode
//
if ( m_bASICLoaded )
{
dwControlReg = GML_CONVERTER_ENABLE | GML_48KHZ;
WriteControlReg( dwControlReg );
}
return m_bASICLoaded;
} // BOOL CGina24DspCommObject::LoadASIC()
//===========================================================================
//
// Set the input clock to internal, S/PDIF, ADAT
//
//===========================================================================
ECHOSTATUS CGina24DspCommObject::SetInputClock(WORD wClock)
{
BOOL bSetRate;
BOOL bWriteControlReg;
DWORD dwControlReg, dwSampleRate;
ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetInputClock:\n") );
dwControlReg = GetControlRegister();
//
// Mask off the clock select bits
//
dwControlReg &= GML_CLOCK_CLEAR_MASK;
dwSampleRate = GetSampleRate();
bSetRate = FALSE;
bWriteControlReg = TRUE;
switch ( wClock )
{
case ECHO_CLOCK_INTERNAL :
{
ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to INTERNAL\n" ) );
// If the sample rate is out of range for some reason, set it
// to a reasonable value. mattg
if ( ( dwSampleRate < 8000 ) ||
( dwSampleRate > 96000 ) )
{
dwSampleRate = 48000;
}
bSetRate = TRUE;
bWriteControlReg = FALSE;
break;
} // ECHO_CLOCK_INTERNAL
case ECHO_CLOCK_SPDIF :
{
if ( DIGITAL_MODE_ADAT == GetDigitalMode() )
{
return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
}
ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to SPDIF\n" ) );
dwControlReg |= GML_SPDIF_CLOCK;
if ( GML_CLOCK_DETECT_BIT_SPDIF96 & GetInputClockDetect() )
{
dwControlReg |= GML_DOUBLE_SPEED_MODE;
}
else
{
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
}
break;
} // ECHO_CLOCK_SPDIF
case ECHO_CLOCK_ADAT :
{
ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ADAT\n" ) );
if ( DIGITAL_MODE_ADAT != GetDigitalMode() )
{
return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
}
dwControlReg |= GML_ADAT_CLOCK;
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
break;
} // ECHO_CLOCK_ADAT
case ECHO_CLOCK_ESYNC :
{
ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ESYNC\n" ) );
dwControlReg |= GML_ESYNC_CLOCK;
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
break;
} // ECHO_CLOCK_ESYNC
case ECHO_CLOCK_ESYNC96 :
{
ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ESYNC96\n" ) );
dwControlReg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE;
break;
} // ECHO_CLOCK_ESYNC96
default :
ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for Gina24\n",wClock));
ECHO_DEBUGBREAK();
return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
} // switch (wInputClock)
//
// Winner! Save the new input clock.
//
m_wInputClock = wClock;
//
// Write the control reg if that's called for
//
if ( bWriteControlReg )
{
WriteControlReg( dwControlReg );
}
// Set Gina24 sample rate to something sane if word or superword is
// being turned off
if ( bSetRate )
{
SetSampleRate( GetSampleRate() );
}
return ECHOSTATUS_OK;
} // ECHOSTATUS CGina24DspCommObject::SetInputClock
//===========================================================================
//
// SetSampleRate
//
// Set the audio sample rate for Gina24 - fixme make this common for
// Gina24 & Mona
//
//===========================================================================
DWORD CGina24DspCommObject::SetSampleRate( DWORD dwNewSampleRate )
{
DWORD dwControlReg, dwNewClock;
//
// Only set the clock for internal mode. If the clock is not set to
// internal, try and re-set the input clock; this more transparently
// handles switching between single and double-speed mode
//
if ( GetInputClock() != ECHO_CLOCK_INTERNAL )
{
ECHO_DEBUGPRINTF( ( "CGina24DspCommObject::SetSampleRate: Cannot set sample rate - "
"clock not set to CLK_CLOCKININTERNAL\n" ) );
//
// Save the rate anyhow
//
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
//
// Set the input clock to the current value
//
SetInputClock( m_wInputClock );
return GetSampleRate();
}
//
// Set the sample rate
//
dwNewClock = 0;
dwControlReg = GetControlRegister();
dwControlReg &= GML_CLOCK_CLEAR_MASK;
dwControlReg &= GML_SPDIF_RATE_CLEAR_MASK;
switch ( dwNewSampleRate )
{
case 96000 :
dwNewClock = GML_96KHZ;
break;
case 88200 :
dwNewClock = GML_88KHZ;
break;
case 48000 :
dwNewClock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
break;
case 44100 :
dwNewClock = GML_44KHZ;
//
// Professional mode
//
if ( dwControlReg & GML_SPDIF_PRO_MODE )
{
dwNewClock |= GML_SPDIF_SAMPLE_RATE0;
}
break;
case 32000 :
dwNewClock = GML_32KHZ |
GML_SPDIF_SAMPLE_RATE0 |
GML_SPDIF_SAMPLE_RATE1;
break;
case 22050 :
dwNewClock = GML_22KHZ;
break;
case 16000 :
dwNewClock = GML_16KHZ;
break;
case 11025 :
dwNewClock = GML_11KHZ;
break;
case 8000 :
dwNewClock = GML_8KHZ;
break;
default :
ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetSampleRate: %ld "
"invalid!\n", dwNewSampleRate) );
ECHO_DEBUGBREAK();
return( GetSampleRate() );
}
dwControlReg |= dwNewClock;
//
// Send the new value to the DSP
//
if ( ECHOSTATUS_OK == WriteControlReg( dwControlReg ) )
{
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetSampleRate: %ld "
"clock %ld\n", dwNewSampleRate, dwNewClock) );
}
return GetSampleRate();
} // DWORD CGina24DspCommObject::SetSampleRate( DWORD dwNewSampleRate )
//===========================================================================
//
// SetDigitalMode
//
//===========================================================================
ECHOSTATUS CGina24DspCommObject::SetDigitalMode
(
BYTE byNewMode
)
{
DWORD dwControlReg;
//
// '361 Gina24 cards do not have the S/PDIF CD-ROM mode
//
if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() &&
( DIGITAL_MODE_SPDIF_CDROM == byNewMode ) )
{
return FALSE;
}
dwControlReg = GetControlRegister();
//
// Clear the current digital mode
//
dwControlReg &= GML_DIGITAL_MODE_CLEAR_MASK;
//
// Tweak the control reg
//
switch ( byNewMode )
{
default :
return ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED;
case DIGITAL_MODE_SPDIF_OPTICAL :
dwControlReg |= GML_SPDIF_OPTICAL_MODE;
goto ChkClk;
case DIGITAL_MODE_SPDIF_CDROM :
dwControlReg |= GML_SPDIF_CDROM_MODE;
// fall through
case DIGITAL_MODE_SPDIF_RCA :
ChkClk:
//
// If the input clock is set to ADAT, set the
// input clock to internal and the sample rate to 48 KHz
//
if ( ECHO_CLOCK_ADAT == GetInputClock() )
{
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 );
SetInputClock( ECHO_CLOCK_INTERNAL );
}
break;
case DIGITAL_MODE_ADAT :
//
// If the input clock is set to S/PDIF, set the
// input clock to internal and the sample rate to 48 KHz
//
if ( ECHO_CLOCK_SPDIF == GetInputClock() )
{
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 );
SetInputClock( ECHO_CLOCK_INTERNAL );
}
dwControlReg |= GML_ADAT_MODE;
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
break;
}
//
// Write the control reg
//
WriteControlReg( dwControlReg );
m_byDigitalMode = byNewMode;
ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetDigitalMode to %ld\n",
(DWORD) m_byDigitalMode) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CGina24DspCommObject::SetDigitalMode
/****************************************************************************
Common for Gina24, Layla24, and Mona. These methods are from
CGMLDspCommObject, not CGina24DspCommObject; this is to avoid code
duplication.
****************************************************************************/
//===========================================================================
//
// Set the S/PDIF output format
//
//===========================================================================
void CGMLDspCommObject::SetProfessionalSpdif
(
BOOL bNewStatus
)
{
DWORD dwControlReg;
dwControlReg = GetControlRegister();
//
// Clear the current S/PDIF flags
//
dwControlReg &= GML_SPDIF_FORMAT_CLEAR_MASK;
//
// Set the new S/PDIF flags depending on the mode
//
dwControlReg |= GML_SPDIF_TWO_CHANNEL |
GML_SPDIF_24_BIT |
GML_SPDIF_COPY_PERMIT;
if ( bNewStatus )
{
//
// Professional mode
//
dwControlReg |= GML_SPDIF_PRO_MODE;
switch ( GetSampleRate() )
{
case 32000 :
dwControlReg |= GML_SPDIF_SAMPLE_RATE0 |
GML_SPDIF_SAMPLE_RATE1;
break;
case 44100 :
dwControlReg |= GML_SPDIF_SAMPLE_RATE0;
break;
case 48000 :
dwControlReg |= GML_SPDIF_SAMPLE_RATE1;
break;
}
}
else
{
//
// Consumer mode
//
switch ( GetSampleRate() )
{
case 32000 :
dwControlReg |= GML_SPDIF_SAMPLE_RATE0 |
GML_SPDIF_SAMPLE_RATE1;
break;
case 48000 :
dwControlReg |= GML_SPDIF_SAMPLE_RATE1;
break;
}
}
//
// Write the control reg
//
WriteControlReg( dwControlReg );
m_bProfessionalSpdif = bNewStatus;
ECHO_DEBUGPRINTF( ("CGMLDspCommObject::SetProfessionalSpdif to %s\n",
( bNewStatus ) ? "Professional" : "Consumer") );
} // void CGina24DspCommObject::SetProfessionalSpdif( ... )
//===========================================================================
//
// WriteControlReg
//
// Most configuration of Gina24, Layla24, or Mona is
// accomplished by writing the control register. WriteControlReg
// sends the new control register value to the DSP.
//
//===========================================================================
ECHOSTATUS CGMLDspCommObject::WriteControlReg( DWORD dwControlReg )
{
if ( !m_bASICLoaded )
return( ECHOSTATUS_ASIC_NOT_LOADED );
if ( !WaitForHandshake() )
return ECHOSTATUS_DSP_DEAD;
#ifdef DIGITAL_INPUT_AUTO_MUTE_SUPPORT
//
// Handle the digital input auto-mute
//
if (TRUE == m_fDigitalInAutoMute)
dwControlReg |= GML_DIGITAL_IN_AUTO_MUTE;
else
dwControlReg &= ~GML_DIGITAL_IN_AUTO_MUTE;
#endif
//
// Write the control register
//
if (dwControlReg != GetControlRegister() )
{
SetControlRegister( dwControlReg );
ECHO_DEBUGPRINTF( ("CGMLDspCommObject::WriteControlReg: 0x%lx\n",
dwControlReg) );
ClearHandshake();
return SendVector( DSP_VC_WRITE_CONTROL_REG );
}
return ECHOSTATUS_OK;
} // ECHOSTATUS CGMLDspCommObject::WriteControlReg( DWORD dwControlReg )
// **** CGina24DspCommObject.cpp ****

View File

@ -0,0 +1,106 @@
// ****************************************************************************
//
// CGina24DspCommObject.H
//
// Include file for EchoGals generic driver Gina24 DSP interface class.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _GINA24DSPCOMMOBJECT_
#define _GINA24DSPCOMMOBJECT_
#include "CGMLDspCommObject.h"
class CGina24DspCommObject : public CGMLDspCommObject
{
public:
//
// Construction/destruction
//
CGina24DspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport );
virtual ~CGina24DspCommObject();
//
// Set the DSP sample rate.
// Return rate that was set, -1 if error
//
virtual DWORD SetSampleRate( DWORD dwNewSampleRate );
//
// Send current setting to DSP & return what it is
//
virtual DWORD SetSampleRate()
{ return( SetSampleRate( GetSampleRate() ) ); }
//
// Set digital mode
//
virtual ECHOSTATUS SetDigitalMode
(
BYTE byNewMode
);
//
// Get mask of all supported digital modes
// (See ECHOCAPS_HAS_DIGITAL_MODE_??? defines in EchoGalsXface.h)
//
virtual DWORD GetDigitalModes()
{ return( ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
ECHOCAPS_HAS_DIGITAL_MODE_ADAT |
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM ); }
//
// Set input clock
//
virtual ECHOSTATUS SetInputClock(WORD wClock);
//
// Card information
//
virtual WORD GetCardType()
{ return( GINA24 ); }
protected:
virtual BOOL LoadASIC();
BYTE * m_pbyAsic; // Current ASIC code
}; // class CGina24DspCommObject
typedef CGina24DspCommObject * PCGina24DspCommObject;
#endif
// **** Gina24DspCommObject.h ****

View File

@ -0,0 +1,157 @@
// ****************************************************************************
//
// CGinaDspCommObject.cpp
//
// Implementation file Gina20 DSP interface class.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CGinaDspCommObject.h"
#include "Gina20DSP.c"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CGinaDspCommObject::CGinaDspCommObject
(
PDWORD pdwRegBase, // Virtual ptr to DSP registers
PCOsSupport pOsSupport
) : CGdDspCommObject( pdwRegBase, pOsSupport )
{
strcpy( m_szCardName, "Gina" );
m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base
m_wNumPipesOut = 10;
m_wNumPipesIn = 4;
m_wNumBussesOut = 10;
m_wNumBussesIn = 4;
m_wFirstDigitalBusOut = 8;
m_wFirstDigitalBusIn = 2;
m_fHasVmixer = FALSE;
m_wNumMidiOut = 0; // # MIDI out channels
m_wNumMidiIn = 0; // # MIDI in channels
m_pwDspCodeToLoad = pwGina20DSP;
//
// Since this card has no ASIC, mark it as loaded so everything works OK
//
m_bASICLoaded = TRUE;
} // CGinaDspCommObject::CGinaDspCommObject( DWORD dwPhysRegBase )
//===========================================================================
//
// Destructor
//
//===========================================================================
CGinaDspCommObject::~CGinaDspCommObject()
{
} // CGinaDspCommObject::~CGinaDspCommObject()
/****************************************************************************
Hardware config
****************************************************************************/
//===========================================================================
//
// Destructor
//
//===========================================================================
ECHOSTATUS CGinaDspCommObject::SetInputClock(WORD wClock)
{
ECHO_DEBUGPRINTF( ( "CGinaDspCommObject::SetInputClock:\n" ) );
switch ( wClock )
{
case ECHO_CLOCK_INTERNAL :
// Reset the audio state to unknown (just in case)
m_byGDCurrentClockState = GD_CLOCK_UNDEF;
m_byGDCurrentSpdifStatus = GD_SPDIF_STATUS_UNDEF;
SetSampleRate();
m_wInputClock = wClock;
ECHO_DEBUGPRINTF( ( "\tSet Gina clock to INTERNAL\n" ) );
break;
case ECHO_CLOCK_SPDIF :
m_pDspCommPage->byGDClockState = GD_CLOCK_SPDIFIN;
m_pDspCommPage->byGDSpdifStatus = GD_SPDIF_STATUS_NOCHANGE;
ClearHandshake();
SendVector( DSP_VC_SET_GD_AUDIO_STATE );
m_byGDCurrentClockState = GD_CLOCK_SPDIFIN;
ECHO_DEBUGPRINTF( ( "\tSet Gina clock to SPDIF\n" ) );
m_wInputClock = wClock;
break;
default :
return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
} // switch ( wClock )
return ECHOSTATUS_OK;
} // ECHOSTATUS CGinaDspCommObject::SetInputClock()
// **** GinaDspCommObject.cpp ****

View File

@ -0,0 +1,76 @@
// ****************************************************************************
//
// CGinaDspCommObject.H
//
// Include file for EchoGals generic driver Gina DSP interface class.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _GINADSPCOMMOBJECT_
#define _GINADSPCOMMOBJECT_
#include "CGdDspCommObject.h"
class CGinaDspCommObject : public CGdDspCommObject
{
public:
//
// Construction/destruction
//
CGinaDspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport );
virtual ~CGinaDspCommObject();
//
// Card information
//
virtual WORD GetCardType()
{ return( GINA ); }
//
// Set input clock
//
virtual ECHOSTATUS SetInputClock(WORD wClock);
protected:
}; // class CGinaDspCommObject
typedef CGinaDspCommObject * PCGinaDspCommObject;
#endif
// **** GinaDspCommObject.h ****

View File

@ -0,0 +1,329 @@
// ****************************************************************************
//
// CLayla.cpp
//
// Implementation file for the CLayla driver class; this is for 20-bit
// Layla.
//
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CLayla.h"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CLayla::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CLayla::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CLayla::operator new( size_t Size )
VOID CLayla::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF( ("CLayla::operator delete memory free failed\n") );
}
} // VOID CLayla::operator delete( PVOID pVoid )
//===========================================================================
//
// Constructor and destructor
//
//===========================================================================
CLayla::CLayla( PCOsSupport pOsSupport )
: CEchoGals( pOsSupport )
{
ECHO_DEBUGPRINTF( ( "CLayla::CLayla() is born!\n" ) );
} // CLayla::CLayla()
CLayla::~CLayla()
{
ECHO_DEBUGPRINTF( ( "CLayla::~CLayla() is toast!\n" ) );
} // CLayla::~CLayla()
/****************************************************************************
Setup and hardware initialization
****************************************************************************/
//===========================================================================
//
// Every card has an InitHw method
//
//===========================================================================
ECHOSTATUS CLayla::InitHw()
{
ECHOSTATUS Status;
WORD i;
//
// Call the base method
//
if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
return Status;
//
// Create the DSP comm object
//
ASSERT( NULL == m_pDspCommObject );
m_pDspCommObject = new CLaylaDspCommObject( (PDWORD) m_pvSharedMemory,
m_pOsSupport );
if (NULL == m_pDspCommObject)
{
ECHO_DEBUGPRINTF(("CLayla::InitHw - could not create DSP comm object\n"));
return ECHOSTATUS_NO_MEM;
}
//
// Load the DSP and the external box ASIC
//
GetDspCommObject()->LoadFirmware();
if ( GetDspCommObject()->IsBoardBad() )
return ECHOSTATUS_DSP_DEAD;
//
// Clear the "bad board" flag; set the flag to indicate that
// Darla24 can handle super-interleave.
//
m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK;
//
// Must call this here after DSP is init to
// init gains and mutes
//
Status = InitLineLevels();
if ( ECHOSTATUS_OK != Status )
return Status;
//
// Initialize the MIDI input
//
Status = m_MidiIn.Init( this );
if ( ECHOSTATUS_OK != Status )
return Status;
//
// Set defaults for +4/-10
//
for (i = 0; i < GetFirstDigitalBusOut(); i++ )
{
GetDspCommObject()->SetNominalLevel( i, TRUE ); // TRUE is -10 here
}
for ( i = 0; i < GetFirstDigitalBusIn(); i++ )
{
GetDspCommObject()->SetNominalLevel( GetNumBussesOut() + i, TRUE );
}
//
// Set the S/PDIF output format to "professional"
//
SetProfessionalSpdif( TRUE );
//
// Get default sample rate from DSP
//
m_dwSampleRate = GetDspCommObject()->GetSampleRate();
ECHO_DEBUGPRINTF( ( "CLayla::InitHw()\n" ) );
return Status;
} // ECHOSTATUS CLayla::InitHw()
/****************************************************************************
Informational methods
****************************************************************************/
//===========================================================================
//
// Override GetCapabilities to enumerate unique capabilties for Layla20
//
//===========================================================================
ECHOSTATUS CLayla::GetCapabilities
(
PECHOGALS_CAPS pCapabilities
)
{
ECHOSTATUS Status;
WORD i;
Status = GetBaseCapabilities(pCapabilities);
//
// Add input gain and nominal level to input busses
//
for (i = 0; i < GetFirstDigitalBusIn(); i++)
{
pCapabilities->dwBusInCaps[i] |= ECHOCAPS_GAIN |
ECHOCAPS_MUTE |
ECHOCAPS_NOMINAL_LEVEL;
}
//
// Add nominal levels to output busses
//
for (i = 0; i < GetFirstDigitalBusOut(); i++)
{
pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
}
if ( ECHOSTATUS_OK != Status )
return Status;
pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_WORD |
ECHO_CLOCK_BIT_SUPER |
ECHO_CLOCK_BIT_SPDIF;
pCapabilities->dwOutClockTypes |= ECHO_CLOCK_BIT_WORD |
ECHO_CLOCK_BIT_SUPER;
return Status;
} // ECHOSTATUS CLayla::GetCapabilities
//===========================================================================
//
// QueryAudioSampleRate is used to find out if this card can handle a
// given sample rate.
//
//===========================================================================
ECHOSTATUS CLayla::QueryAudioSampleRate
(
DWORD dwSampleRate
)
{
if ( dwSampleRate < 8000 ||
dwSampleRate > 50000 )
{
ECHO_DEBUGPRINTF(
("CLayla::QueryAudioSampleRate() Sample rate must be >= 8,000 Hz"
" and <= 50,000 Hz\n") );
return ECHOSTATUS_BAD_FORMAT;
}
ECHO_DEBUGPRINTF( ( "CLayla::QueryAudioSampleRate() %d Hz OK\n",
dwSampleRate ) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CLayla::QueryAudioSampleRate
//===========================================================================
//
// GetInputClockDetect returns a bitmask consisting of all the input
// clocks currently connected to the hardware; this changes as the user
// connects and disconnects clock inputs.
//
// You should use this information to determine which clocks the user is
// allowed to select.
//
// Layla20 supports S/PDIF clock, word clock, and super clock.
//
//===========================================================================
ECHOSTATUS CLayla::GetInputClockDetect(DWORD &dwClockDetectBits)
{
if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
{
ECHO_DEBUGPRINTF( ("CLayla::GetInputClockDetect: DSP Dead!\n") );
return ECHOSTATUS_DSP_DEAD;
}
DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SPDIF))
dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_WORD))
{
if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SUPER))
dwClockDetectBits |= ECHO_CLOCK_BIT_SUPER;
else
dwClockDetectBits |= ECHO_CLOCK_BIT_WORD;
}
return ECHOSTATUS_OK;
} // GetInputClockDetect
// *** CLayla.cpp ***

View File

@ -0,0 +1,113 @@
// ****************************************************************************
//
// CLayla.h
//
// Include file for interfacing with the CLayla generic driver class
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _LAYLAOBJECT_
#define _LAYLAOBJECT_
#include "CEchoGals.h"
#include "CMidiInQ.h"
#include "CLaylaDspCommObject.h"
//
// Class used for interfacing with the Layla audio card.
//
class CLayla : public CEchoGals
{
public:
//
// Construction/destruction
//
CLayla( PCOsSupport pOsSupport );
virtual ~CLayla();
//
// Setup & initialization methods
//
virtual ECHOSTATUS InitHw();
//
// Adapter information methods
//
virtual ECHOSTATUS GetCapabilities
(
PECHOGALS_CAPS pCapabilities
);
//
// Audio Interface methods
//
virtual ECHOSTATUS QueryAudioSampleRate
(
DWORD dwSampleRate
);
//
// Get a bitmask of all the clocks the hardware is currently detecting
//
virtual ECHOSTATUS GetInputClockDetect(DWORD &dwClockDetectBits);
//
// Overload new & delete so memory for this object is allocated from non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
protected:
//
// Get access to the appropriate DSP comm object
//
PCLaylaDspCommObject GetDspCommObject()
{ return( (PCLaylaDspCommObject) m_pDspCommObject ); }
}; // class CLayla
typedef CLayla * PCLayla;
#endif
// *** CLayla.H ***

View File

@ -0,0 +1,372 @@
// ****************************************************************************
//
// CLayla24.cpp
//
// Implementation file for the CLayla24 driver class.
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CLayla24.h"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CLayla24::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CLayla24::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CLayla24::operator new( size_t Size )
VOID CLayla24::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF( ("CLayla24::operator delete memory free failed\n") );
}
} // VOID CLayla24::operator delete( PVOID pVoid )
//===========================================================================
//
// Constructor and destructor
//
//===========================================================================
CLayla24::CLayla24( PCOsSupport pOsSupport )
: CEchoGals( pOsSupport )
{
ECHO_DEBUGPRINTF( ( "CLayla24::CLayla24() is born!\n" ) );
} // CLayla24::CLayla24()
CLayla24::~CLayla24()
{
ECHO_DEBUGPRINTF( ( "CLayla24::~CLayla24() is toast!\n" ) );
} // CLayla24::~CLayla24()
/****************************************************************************
Setup and hardware initialization
****************************************************************************/
//===========================================================================
//
// Every card has an InitHw method
//
//===========================================================================
ECHOSTATUS CLayla24::InitHw()
{
ECHOSTATUS Status;
WORD i;
//
// Call the base method
//
if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
return Status;
//
// Create the DSP comm object
//
ASSERT( NULL == m_pDspCommObject );
m_pDspCommObject = new CLayla24DspCommObject( (PDWORD) m_pvSharedMemory,
m_pOsSupport );
if (NULL == m_pDspCommObject)
{
ECHO_DEBUGPRINTF(("CLayla24::InitHw - could not create DSP comm object\n"));
return ECHOSTATUS_NO_MEM;
}
//
// Load the DSP, the PCI card ASIC, and the external box ASIC
//
GetDspCommObject()->LoadFirmware();
if ( GetDspCommObject()->IsBoardBad() )
return ECHOSTATUS_DSP_DEAD;
//
// Clear the "bad board" flag; set the flags to indicate that
// Layla24 can handle super-interleave and supports the digital
// input auto-mute.
//
m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK |
ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE;
//
// Must call this here after DSP is init to
// init gains and mutes
//
Status = InitLineLevels();
if ( ECHOSTATUS_OK != Status )
return Status;
//
// Initialize the MIDI input
//
Status = m_MidiIn.Init( this );
if ( ECHOSTATUS_OK != Status )
return Status;
//
// Set defaults for +4/-10
//
for (i = 0; i < GetFirstDigitalBusOut(); i++ )
{
GetDspCommObject()->
SetNominalLevel( i, FALSE ); // FALSE is +4 here
}
for ( i = 0; i < GetFirstDigitalBusIn(); i++ )
{
GetDspCommObject()->
SetNominalLevel( GetNumBussesOut() + i, FALSE );
}
//
// Set the digital mode to S/PDIF RCA
//
SetDigitalMode( DIGITAL_MODE_SPDIF_RCA );
//
// Set the S/PDIF output format to "professional"
//
SetProfessionalSpdif( TRUE );
//
// Get default sample rate from DSP
//
m_dwSampleRate = GetDspCommObject()->GetSampleRate();
ECHO_DEBUGPRINTF( ( "CLayla24::InitHw()\n" ) );
return Status;
} // ECHOSTATUS CLayla24::InitHw()
/****************************************************************************
Informational methods
****************************************************************************/
//===========================================================================
//
// Override GetCapabilities to enumerate unique capabilties for this card
//
//===========================================================================
ECHOSTATUS CLayla24::GetCapabilities
(
PECHOGALS_CAPS pCapabilities
)
{
ECHOSTATUS Status;
WORD i;
Status = GetBaseCapabilities(pCapabilities);
if ( ECHOSTATUS_OK != Status )
return Status;
//
// Add nominal level control to analog ins & outs
//
for (i = 0 ; i < GetFirstDigitalBusOut(); i++)
{
pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
}
for (i = 0 ; i < GetFirstDigitalBusIn(); i++)
{
pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
}
pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_WORD |
ECHO_CLOCK_BIT_SPDIF |
ECHO_CLOCK_BIT_ADAT;
return Status;
} // ECHOSTATUS CLayla24::GetCapabilities
//===========================================================================
//
// QueryAudioSampleRate is used to find out if this card can handle a
// given sample rate.
//
//===========================================================================
ECHOSTATUS CLayla24::QueryAudioSampleRate
(
DWORD dwSampleRate
)
{
//
// Standard sample rates are allowed (like Mona & Layla24)
//
switch ( dwSampleRate )
{
case 8000 :
case 11025 :
case 16000 :
case 22050 :
case 32000 :
case 44100 :
case 48000 :
goto qasr_ex;
case 88200 :
case 96000 :
//
// Double speed sample rates not allowed in ADAT mode
//
if ( DIGITAL_MODE_ADAT == GetDigitalMode() )
{
ECHO_DEBUGPRINTF(
("CLayla24::QueryAudioSampleRate() Sample rate must be < "
"50,000 Hz in ADAT mode\n") );
return ECHOSTATUS_BAD_FORMAT;
}
goto qasr_ex;
}
//
// Any rate from 25000 to 50000 is allowed
//
if ( ( dwSampleRate >= 25000 ) &&
( dwSampleRate <= 50000 ) )
goto qasr_ex;
//
// If not in ADAT mode, any rate from 50,000 to 100,000 is allowed
//
if ( DIGITAL_MODE_ADAT != GetDigitalMode() &&
( dwSampleRate >= 50000 ) &&
( dwSampleRate <= 100000 ) )
goto qasr_ex;
ECHO_DEBUGPRINTF(
("CLayla24::QueryAudioSampleRate() Sample rate must be >= 50,000 Hz"
" and <= 100,000 Hz and NOT in ADAT mode\n") );
return ECHOSTATUS_BAD_FORMAT;
qasr_ex:
ECHO_DEBUGPRINTF( ( "CLayla24::QueryAudioSampleRate() %ld Hz OK\n",
dwSampleRate ) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CLayla24::QueryAudioSampleRate
//===========================================================================
//
// GetInputClockDetect returns a bitmask consisting of all the input
// clocks currently connected to the hardware; this changes as the user
// connects and disconnects clock inputs.
//
// You should use this information to determine which clocks the user is
// allowed to select.
//
// Layla24 supports S/PDIF, word, and ADAT input clocks.
//
//===========================================================================
ECHOSTATUS CLayla24::GetInputClockDetect(DWORD &dwClockDetectBits)
{
if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
{
ECHO_DEBUGPRINTF( ("CLayla24::GetInputClockDetect: DSP Dead!\n") );
return ECHOSTATUS_DSP_DEAD;
}
//
// Map the DSP clock detect bits to the generic driver clock detect bits
//
DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF))
dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT))
dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT;
if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_WORD))
dwClockDetectBits |= ECHO_CLOCK_BIT_WORD;
return ECHOSTATUS_OK;
} // GetInputClockDetect
// *** Layla24.cpp ***

View File

@ -0,0 +1,80 @@
// ****************************************************************************
//
// CLayla24.h
//
// Include file for interfacing with the CLayla24 generic driver class
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Corporation (c) 1998 - 2000 All Rights Reserved.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _LAYLA24OBJECT_
#define _LAYLA24OBJECT_
#include "CEchoGals.h"
#include "CMidiInQ.h"
#include "CLayla24DspCommObject.h"
//
// Class used for interfacing with the Layla24 audio card.
//
class CLayla24 : public CEchoGals
{
public:
//
// Construction/destruction
//
CLayla24( PCOsSupport pOsSupport );
virtual ~CLayla24();
//
// Setup & initialization methods
//
virtual ECHOSTATUS InitHw();
//
// Adapter information methods
//
virtual ECHOSTATUS GetCapabilities
(
PECHOGALS_CAPS pCapabilities
);
//
// Audio interface methods
//
virtual ECHOSTATUS QueryAudioSampleRate
(
DWORD dwSampleRate
);
//
// Get a bitmask of all the clocks the hardware is currently detecting
//
virtual ECHOSTATUS GetInputClockDetect(DWORD &dwClockDetectBits);
//
// Overload new & delete so memory for this object is allocated from non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
protected:
//
// Get access to the appropriate DSP comm object
//
PCLayla24DspCommObject GetDspCommObject()
{ return( (PCLayla24DspCommObject) m_pDspCommObject ); }
}; // class CLayla24
typedef CLayla24 * PCLayla24;
#endif
// *** Layla24.H ***

View File

@ -0,0 +1,627 @@
// ****************************************************************************
//
// CLayla24DspCommObject.cpp
//
// Implementation file for EchoGals generic driver Layla24 DSP
// interface class.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CLayla24DspCommObject.h"
#include "Layla24DSP.c" // regular DSP code
#include "Layla24_1ASIC.c"
#include "Layla24_2A_ASIC.c"
#include "Layla24_2S_ASIC.c"
//
// The ASIC files for Layla24 are always this size
//
#define LAYLA24_ASIC_SIZE 31146
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CLayla24DspCommObject::CLayla24DspCommObject
(
PDWORD pdwRegBase, // Virtual ptr to DSP registers
PCOsSupport pOsSupport
) : CGMLDspCommObject( pdwRegBase, pOsSupport )
{
strcpy( m_szCardName, "Layla24" );
m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base
m_wNumPipesOut = 16;
m_wNumPipesIn = 16;
m_wNumBussesOut = 16;
m_wNumBussesIn = 16;
m_wFirstDigitalBusOut = 8;
m_wFirstDigitalBusIn = 8;
m_fHasVmixer = FALSE;
m_wNumMidiOut = 1; // # MIDI out channels
m_wNumMidiIn = 1; // # MIDI in channels
m_bHasASIC = TRUE;
m_pwDspCodeToLoad = pwLayla24DSP;
m_byDigitalMode = DIGITAL_MODE_SPDIF_RCA;
m_bProfessionalSpdif = FALSE;
m_wMtcState = MTC_STATE_NORMAL;
} // CLayla24DspCommObject::CLayla24DspCommObject( DWORD dwPhysRegBase )
//===========================================================================
//
// Destructor
//
//===========================================================================
CLayla24DspCommObject::~CLayla24DspCommObject()
{
ECHO_DEBUGPRINTF( ( "CLayla24DspCommObject::~CLayla24DspCommObject() "
"is toast!\n" ) );
} // CLayla24DspCommObject::~CLayla24DspCommObject()
/****************************************************************************
Hardware setup and config
****************************************************************************/
//===========================================================================
//
// Layla24 has an ASIC on the PCI card and another ASIC in the external box;
// both need to be loaded.
//
//===========================================================================
BOOL CLayla24DspCommObject::LoadASIC()
{
DWORD dwControlReg;
if ( m_bASICLoaded == TRUE )
return TRUE;
ECHO_DEBUGPRINTF(("CLayla24DspCommObject::LoadASIC\n"));
//
// Give the DSP a few milliseconds to settle down
//
m_pOsSupport->OsSnooze( 10000 );
//
// Load the ASIC for the PCI card
//
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC,
pbLayla24_1ASIC,
sizeof( pbLayla24_1ASIC ) ) )
return FALSE;
m_pbyAsic = pbLayla24_2S_ASIC;
//
// Now give the new ASIC a little time to set up
//
m_pOsSupport->OsSnooze( 10000 );
//
// Do the external one
//
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
pbLayla24_2S_ASIC,
sizeof( pbLayla24_2S_ASIC ) ) )
return FALSE;
//
// Now give the external ASIC a little time to set up
//
m_pOsSupport->OsSnooze( 10000 );
//
// See if it worked
//
CheckAsicStatus();
//
// Set up the control register if the load succeeded -
//
// 48 kHz, internal clock, S/PDIF RCA mode
//
if ( m_bASICLoaded )
{
dwControlReg = GML_CONVERTER_ENABLE | GML_48KHZ;
WriteControlReg( dwControlReg );
}
ECHO_DEBUGPRINTF(("\tFinished\n"));
return m_bASICLoaded;
} // BOOL CLayla24DspCommObject::LoadASIC()
//===========================================================================
//
// SetSampleRate
//
// Set the sample rate for Layla24
//
// Layla24 is simple; just send it the sampling rate (assuming that the clock
// mode is correct).
//
//===========================================================================
DWORD CLayla24DspCommObject::SetSampleRate( DWORD dwNewSampleRate )
{
DWORD dwControlReg, dwNewClock, dwBaseRate;
BOOL bSetFreqReg = FALSE;
//
// Only set the clock for internal mode. If the clock is not set to
// internal, try and re-set the input clock; this more transparently
// handles switching between single and double-speed mode
//
if ( GetInputClock() != ECHO_CLOCK_INTERNAL )
{
ECHO_DEBUGPRINTF( ( "CLayla24DspCommObject::SetSampleRate: Cannot set sample rate - "
"clock not set to CLK_CLOCKININTERNAL\n" ) );
//
// Save the rate anyhow
//
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
//
// Set the input clock to the current value
//
SetInputClock( m_wInputClock );
return GetSampleRate();
}
//
// Get the control register & clear the appropriate bits
//
dwControlReg = GetControlRegister();
dwControlReg &= GML_CLOCK_CLEAR_MASK;
dwControlReg &= GML_SPDIF_RATE_CLEAR_MASK;
//
// Set the sample rate
//
bSetFreqReg = FALSE;
switch ( dwNewSampleRate )
{
case 96000 :
dwNewClock = GML_96KHZ;
break;
case 88200 :
dwNewClock = GML_88KHZ;
break;
case 48000 :
dwNewClock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
break;
case 44100 :
dwNewClock = GML_44KHZ;
//
// Professional mode
//
if ( dwControlReg & GML_SPDIF_PRO_MODE )
{
dwNewClock |= GML_SPDIF_SAMPLE_RATE0;
}
break;
case 32000 :
dwNewClock = GML_32KHZ |
GML_SPDIF_SAMPLE_RATE0 |
GML_SPDIF_SAMPLE_RATE1;
break;
case 22050 :
dwNewClock = GML_22KHZ;
break;
case 16000 :
dwNewClock = GML_16KHZ;
break;
case 11025 :
dwNewClock = GML_11KHZ;
break;
case 8000 :
dwNewClock = GML_8KHZ;
break;
default :
//
// Set flag to write the frequency register
//
bSetFreqReg = TRUE;
//
// Set for continuous mode
//
dwNewClock = LAYLA24_CONTINUOUS_CLOCK;
}
dwControlReg |= dwNewClock;
//
// If this is a non-standard rate, then the driver
// needs to use Layla24's special "continuous frequency" mode
//
if ( bSetFreqReg )
{
if ( dwNewSampleRate > 50000 )
{
dwBaseRate = dwNewSampleRate >> 1;
dwControlReg |= GML_DOUBLE_SPEED_MODE;
}
else
{
dwBaseRate = dwNewSampleRate;
}
if ( dwBaseRate < 25000 )
dwBaseRate = 25000;
if ( !WaitForHandshake() )
return 0xffffffff;
m_pDspCommPage->dwSampleRate =
SWAP( LAYLA24_MAGIC_NUMBER / dwBaseRate - 2 );
ClearHandshake();
SendVector( DSP_VC_SET_LAYLA24_FREQUENCY_REG );
}
//
// Tell the DSP about it
//
if ( ECHOSTATUS_OK == WriteControlReg( dwControlReg ) )
{
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
ECHO_DEBUGPRINTF( ("CLayla24DspCommObject::SetSampleRate: %ld "
"clock %ld\n", dwNewSampleRate, dwControlReg) );
}
return GetSampleRate();
} // DWORD CLayla24DspCommObject::SetSampleRate( DWORD dwNewSampleRate )
//===========================================================================
//
// SetDigitalMode
//
//===========================================================================
ECHOSTATUS CLayla24DspCommObject::SetDigitalMode
(
BYTE byNewMode
)
{
DWORD dwControlReg;
dwControlReg = GetControlRegister();
//
// Clear the current digital mode
//
dwControlReg &= GML_DIGITAL_MODE_CLEAR_MASK;
//
// Tweak the control reg
//
switch ( byNewMode )
{
default :
return ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED;
case DIGITAL_MODE_SPDIF_OPTICAL :
dwControlReg |= GML_SPDIF_OPTICAL_MODE;
// fall through
case DIGITAL_MODE_SPDIF_RCA :
//
// If the input clock is set to ADAT, set the
// input clock to internal and the sample rate to 48 KHz
//
if ( ECHO_CLOCK_ADAT == GetInputClock() )
{
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 );
SetInputClock( ECHO_CLOCK_INTERNAL );
}
//
// If the currently loaded ASIC is the S/PDIF ASIC, switch
// to the ADAT ASIC
//
if ( !SwitchAsic( pbLayla24_2S_ASIC, sizeof( pbLayla24_2S_ASIC ) ) )
SetInputClock( ECHO_CLOCK_INTERNAL );
break;
case DIGITAL_MODE_ADAT :
//
// If the input clock is set to S/PDIF, set the
// input clock to internal and the sample rate to 48 KHz
//
if ( ECHO_CLOCK_SPDIF == GetInputClock() )
{
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 );
SetInputClock( ECHO_CLOCK_INTERNAL );
}
//
// If the currently loaded ASIC is the S/PDIF ASIC, switch
// to the ADAT ASIC
//
if ( !SwitchAsic( pbLayla24_2A_ASIC, sizeof( pbLayla24_2A_ASIC ) ) )
return( ECHOSTATUS_ASIC_NOT_LOADED );
dwControlReg |= GML_ADAT_MODE;
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
break;
}
//
// Write the control reg
//
WriteControlReg( dwControlReg );
m_byDigitalMode = byNewMode;
ECHO_DEBUGPRINTF( ("CLayla24DspCommObject::SetDigitalMode to %ld\n",
(DWORD) m_byDigitalMode) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CLaya24DspCommObject::SetDigitalMode
//===========================================================================
//
// Depending on what digital mode you want, Layla24 needs different ASICs
// loaded. This function checks the ASIC needed for the new mode and sees
// if it matches the one already loaded.
//
//===========================================================================
BOOL CLayla24DspCommObject::SwitchAsic
(
BYTE * pbyAsicNeeded,
DWORD dwAsicSize
)
{
//
// Check to see if this is already loaded
//
if ( pbyAsicNeeded != m_pbyAsic )
{
BYTE byMonitors[ MONITOR_ARRAY_SIZE ];
memmove( byMonitors, m_pDspCommPage->byMonitors, MONITOR_ARRAY_SIZE );
memset( m_pDspCommPage->byMonitors,
GENERIC_TO_DSP(ECHOGAIN_MUTED),
MONITOR_ARRAY_SIZE );
//
// Load the desired ASIC
//
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
pbyAsicNeeded,
dwAsicSize ) )
{
memmove( m_pDspCommPage->byMonitors, byMonitors, MONITOR_ARRAY_SIZE );
return FALSE;
}
m_pbyAsic = pbyAsicNeeded;
memmove( m_pDspCommPage->byMonitors, byMonitors, MONITOR_ARRAY_SIZE );
}
return TRUE;
} // BOOL CLayla24DspCommObject::SwitchAsic( DWORD dwMask96 )
//===========================================================================
//
// SetInputClock
//
//===========================================================================
ECHOSTATUS CLayla24DspCommObject::SetInputClock(WORD wClock)
{
BOOL bSetRate;
BOOL bWriteControlReg;
DWORD dwControlReg, dwSampleRate;
ECHO_DEBUGPRINTF( ( "CLayla24DspCommObject::SetInputClock:\n" ) );
dwControlReg = GetControlRegister();
//
// Mask off the clock select bits
//
dwControlReg &= GML_CLOCK_CLEAR_MASK;
dwSampleRate = GetSampleRate();
bSetRate = FALSE;
bWriteControlReg = TRUE;
//
// Pick the new clock
//
switch ( wClock )
{
case ECHO_CLOCK_INTERNAL :
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to INTERNAL\n" ) );
// If the sample rate is out of range for some reason, set it
// to a reasonable value. mattg
if ( ( GetSampleRate() < 8000 ) ||
( GetSampleRate() > 100000 ) )
{
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 );
}
bSetRate = TRUE;
bWriteControlReg = FALSE;
break;
case ECHO_CLOCK_SPDIF:
if ( DIGITAL_MODE_ADAT == GetDigitalMode() )
{
return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
}
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to SPDIF\n" ) );
dwControlReg |= GML_SPDIF_CLOCK;
/*
Since Layla24 doesn't support 96 kHz S/PDIF, this can be ignored
if ( GML_CLOCK_DETECT_BIT_SPDIF96 & GetInputClockDetect() )
{
dwControlReg |= GML_DOUBLE_SPEED_MODE;
}
else
{
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
}
*/
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to SPDIF\n" ) );
break;
case ECHO_CLOCK_WORD:
dwControlReg |= GML_WORD_CLOCK;
if ( GML_CLOCK_DETECT_BIT_WORD96 & GetInputClockDetect() )
{
dwControlReg |= GML_DOUBLE_SPEED_MODE;
}
else
{
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
}
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to WORD\n" ) );
break;
case ECHO_CLOCK_ADAT :
if ( DIGITAL_MODE_ADAT != GetDigitalMode() )
{
return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
}
dwControlReg |= GML_ADAT_CLOCK;
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to ADAT\n" ) );
break;
default :
ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for Layla24\n",wClock));
ECHO_DEBUGBREAK();
return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
} // switch (wClock)
//
// Winner! Save the new input clock.
//
m_wInputClock = wClock;
//
// Do things according to the flags
//
if ( bWriteControlReg )
{
WriteControlReg( dwControlReg );
}
//
// If the user just switched to internal clock,
// set the sample rate
//
if ( bSetRate )
SetSampleRate();
return ECHOSTATUS_OK;
} // ECHOSTATUS CLayla24DspCommObject::SetInputClock()
//===========================================================================
//
// Detect MIDI output activity
//
//===========================================================================
BOOL CLayla24DspCommObject::IsMidiOutActive()
{
ULONGLONG ullCurTime;
m_pOsSupport->OsGetSystemTime( &ullCurTime );
return( ( ( ullCurTime - m_ullMidiOutTime ) > MIDI_ACTIVITY_TIMEOUT_USEC ) ? FALSE : TRUE );
} // BOOL CLayla24DspCommObject::IsMidiOutActive()
// **** Layla24DspCommObject.cpp ****

View File

@ -0,0 +1,119 @@
// ****************************************************************************
//
// CLayla24DspCommObject.H
//
// Include file for EchoGals generic driver Layla24 DSP interface class.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _LAYLA24DSPCOMMOBJECT_
#define _LAYLA24DSPCOMMOBJECT_
#include "CGMLDspCommObject.h"
class CLayla24DspCommObject : public CGMLDspCommObject
{
protected:
public:
//
// Construction/destruction
//
CLayla24DspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport );
virtual ~CLayla24DspCommObject();
//
// Set the DSP sample rate.
// Return rate that was set, -1 if error
//
virtual DWORD SetSampleRate( DWORD dwNewSampleRate );
//
// Send current setting to DSP & return what it is
//
virtual DWORD SetSampleRate()
{ return( SetSampleRate( GetSampleRate() ) ); }
//
// Set digital mode
//
virtual ECHOSTATUS SetDigitalMode
(
BYTE byNewMode
);
//
// Get mask of all supported digital modes
// (See ECHOCAPS_HAS_DIGITAL_MODE_??? defines in EchoGalsXface.h)
//
virtual DWORD GetDigitalModes()
{ return( ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
ECHOCAPS_HAS_DIGITAL_MODE_ADAT ); }
//
// Card information
//
virtual WORD GetCardType()
{ return( LAYLA24 ); }
virtual BOOL IsMidiOutActive();
protected:
virtual BOOL LoadASIC();
//
// Switch the external ASIC if not already loaded.
// Mute monitors during this operation
//
BOOL SwitchAsic
(
BYTE * pbyAsicNeeded,
DWORD dwAsicSize
);
//
// Set input clock
//
virtual ECHOSTATUS SetInputClock(WORD wClock);
BYTE * m_pbyAsic; // Current ASIC code
}; // class CLayla24DspCommObject
typedef CLayla24DspCommObject * PCLayla24DspCommObject;
#endif
// **** Layla2424DspCommObject.h ****

View File

@ -0,0 +1,403 @@
// ****************************************************************************
//
// CLaylaDspCommObject.cpp
//
// Implementation file for EchoGals generic driver Layla DSP
// interface class.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CLaylaDspCommObject.h"
#include "Layla20DSP.c"
#include "LaylaAsic.c"
//
// The ASIC files for Layla20 are always this size
//
#define LAYLA_ASIC_SIZE 32385
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CLaylaDspCommObject::CLaylaDspCommObject
(
PDWORD pdwRegBase, // Virtual ptr to DSP registers
PCOsSupport pOsSupport
) : CDspCommObject( pdwRegBase, pOsSupport )
{
strcpy( m_szCardName, "Layla" );
m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base
m_wNumPipesOut = 12;
m_wNumPipesIn = 10;
m_wNumBussesOut = 12;
m_wNumBussesIn = 10;
m_wFirstDigitalBusOut = 10;
m_wFirstDigitalBusIn = 8;
m_fHasVmixer = FALSE;
m_wNumMidiOut = 1; // # MIDI out channels
m_wNumMidiIn = 1; // # MIDI in channels
m_bHasASIC = TRUE;
m_pwDspCodeToLoad = pwLayla20DSP;
} // CLaylaDspCommObject::CLaylaDspCommObject( DWORD dwPhysRegBase )
//===========================================================================
//
// Destructor
//
//===========================================================================
CLaylaDspCommObject::~CLaylaDspCommObject()
{
ECHO_DEBUGPRINTF( ( "CLaylaDspCommObject::~CLaylaDspCommObject() is toast!\n" ) );
} // CLaylaDspCommObject::~CLaylaDspCommObject()
/****************************************************************************
Hardware setup and config
****************************************************************************/
//===========================================================================
//
// Layla20 has an ASIC in the external box
//
//===========================================================================
BOOL CLaylaDspCommObject::LoadASIC()
{
if ( m_bASICLoaded == TRUE )
return TRUE;
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_LAYLA_ASIC,
pbLaylaASIC,
LAYLA_ASIC_SIZE ) )
return FALSE;
//
// Check if ASIC is alive and well.
//
return( CheckAsicStatus() );
} // BOOL CLaylaDspCommObject::LoadASIC()
//===========================================================================
//
// SetSampleRate
//
// Set the sample rate for Layla
//
// Layla is simple; just send it the sampling rate (assuming that the clock
// mode is correct).
//
//===========================================================================
DWORD CLaylaDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
{
//
// Only set the clock for internal mode
// Do not return failure, simply treat it as a non-event.
//
if ( GetInputClock() != ECHO_CLOCK_INTERNAL )
{
ECHO_DEBUGPRINTF( ( "SetSampleRate: Cannot set sample rate because "
"Layla clock NOT set to CLK_CLOCKININTERNAL\n" ) );
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
return GetSampleRate();
}
//
// Sanity check - check the sample rate
//
if ( ( dwNewSampleRate < 8000 ) ||
( dwNewSampleRate > 50000 ) )
{
ECHO_DEBUGPRINTF( ( "SetSampleRate: Layla sample rate %d out of range, "
"no change made\n",
dwNewSampleRate) );
return 0xffffffff;
}
if ( !WaitForHandshake() )
return 0xffffffff;
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
ClearHandshake();
SendVector( DSP_VC_SET_LAYLA_SAMPLE_RATE );
ECHO_DEBUGPRINTF( ( "SetSampleRate: Layla sample rate changed to %d\n",
dwNewSampleRate ) );
return( dwNewSampleRate );
} // DWORD CLaylaDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
//===========================================================================
//
// Send new input clock setting to DSP
//
//===========================================================================
ECHOSTATUS CLaylaDspCommObject::SetInputClock(WORD wClock)
{
BOOL bSetRate;
BOOL bWriteControlReg;
DWORD dwSampleRate;
WORD wNewClock;
ECHO_DEBUGPRINTF( ( "CLaylaDspCommObject::SetInputClock:\n" ) );
bSetRate = FALSE;
switch ( wClock )
{
case ECHO_CLOCK_INTERNAL :
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to INTERNAL\n" ) );
// If the sample rate is out of range for some reason, set it
// to a reasonable value. mattg
if ( ( GetSampleRate() < 8000 ) ||
( GetSampleRate() > 50000 ) )
{
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 );
}
bSetRate = TRUE;
wNewClock = LAYLA20_CLOCK_INTERNAL;
break;
case ECHO_CLOCK_SPDIF:
ECHO_DEBUGPRINTF( ( "\tSet Layla20 clock to SPDIF\n" ) );
wNewClock = LAYLA20_CLOCK_SPDIF;
break;
case ECHO_CLOCK_WORD:
ECHO_DEBUGPRINTF( ( "\tSet Layla20 clock to WORD\n" ) );
wNewClock = LAYLA20_CLOCK_WORD;
break;
case ECHO_CLOCK_SUPER:
ECHO_DEBUGPRINTF( ( "\tSet Layla20 clock to SUPER\n" ) );
wNewClock = LAYLA20_CLOCK_SUPER;
break;
default :
ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for Layla24\n"));
ECHO_DEBUGBREAK();
return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
} // switch (wClock)
//
// Winner! Save the new input clock.
//
m_wInputClock = wClock;
//
// Send the new clock to the DSP
//
m_pDspCommPage->wInputClock = SWAP(wNewClock);
ClearHandshake();
SendVector( DSP_VC_UPDATE_CLOCKS );
if ( bSetRate )
SetSampleRate();
return ECHOSTATUS_OK;
} // ECHOSTATUS CLaylaDspCommObject::SetInputClock()
//===========================================================================
//
// Set new output clock
//
//===========================================================================
ECHOSTATUS CLaylaDspCommObject::SetOutputClock(WORD wClock)
{
if (FALSE == m_bASICLoaded)
return ECHOSTATUS_ASIC_NOT_LOADED;
if (!WaitForHandshake())
return ECHOSTATUS_DSP_DEAD;
ECHO_DEBUGPRINTF( ("CDspCommObject::SetOutputClock:\n") );
m_pDspCommPage->wOutputClock = SWAP(wClock);
m_wOutputClock = wClock;
ClearHandshake();
ECHOSTATUS Status = SendVector(DSP_VC_UPDATE_CLOCKS);
return Status;
} // ECHOSTATUS CLaylaDspCommObject::SetOutputClock
//===========================================================================
//
// Detect MIDI output activity
//
//===========================================================================
BOOL CLaylaDspCommObject::IsMidiOutActive()
{
ULONGLONG ullCurTime;
m_pOsSupport->OsGetSystemTime( &ullCurTime );
return( ( ( ullCurTime - m_ullMidiOutTime ) > MIDI_ACTIVITY_TIMEOUT_USEC ) ? FALSE : TRUE );
} // BOOL CLaylaDspCommObject::IsMidiOutActive()
//===========================================================================
//
// Input bus gain - iGain is in units of .5 dB
//
//===========================================================================
ECHOSTATUS CLaylaDspCommObject::SetBusInGain( WORD wBusIn, int iGain)
{
//
// Store the gain for later use
//
m_byInputTrims[wBusIn] = (BYTE) iGain;
//
// Adjust the input gain depending on the nominal level switch
//
BYTE byMinus10;
GetNominalLevel( wBusIn + m_wNumBussesOut, &byMinus10);
if (0 == byMinus10)
{
//
// This channel is in +4 mode; subtract 12 dB from the input gain
// (note that iGain is in units of .5 dB)
//
iGain -= 12 << 1;
}
return CDspCommObject::SetBusInGain(wBusIn,iGain);
}
ECHOSTATUS CLaylaDspCommObject::GetBusInGain( WORD wBusIn, int &iGain)
{
ECHOSTATUS Status;
if (wBusIn > m_wNumBussesIn)
return ECHOSTATUS_INVALID_CHANNEL;
iGain = (int) m_byInputTrims[wBusIn];
return ECHOSTATUS_OK;
}
//===========================================================================
//
// Set the nominal level for an input or output bus
//
// Set bState to TRUE for -10, FALSE for +4
//
// Layla20 sets the input nominal level by adjusting the
// input trim
//
//===========================================================================
ECHOSTATUS CLaylaDspCommObject::SetNominalLevel
(
WORD wBus,
BOOL bState
)
{
if (wBus < m_wNumBussesOut)
{
//
// This is an output bus; call the base class routine to service it
//
return CDspCommObject::SetNominalLevel(wBus,bState);
}
//
// Check the bus number
//
if (wBus < (m_wNumBussesOut + m_wNumBussesIn))
{
//
// Set the nominal bit in the comm page
//
if ( bState )
m_pDspCommPage->cmdNominalLevel.SetIndexInMask( wBus );
else
m_pDspCommPage->cmdNominalLevel.ClearIndexInMask( wBus );
//
// Set the input trim, using the current gain
//
return SetBusInGain(wBus - m_wNumBussesOut,(int) m_byInputTrims[wBus]);
}
ECHO_DEBUGPRINTF( ("CLaylaDspCommObject::SetNominalOutLineLevel Invalid "
"index %d\n",
wBus ) );
return ECHOSTATUS_INVALID_CHANNEL;
} // ECHOSTATUS CLaylaDspCommObject::SetNominalLevel
// **** LaylaDspCommObject.cpp ****

View File

@ -0,0 +1,122 @@
// ****************************************************************************
//
// CLaylaDspCommObject.H
//
// Include file for EchoGals generic driver Layla DSP interface class.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _LAYLADSPCOMMOBJECT_
#define _LAYLADSPCOMMOBJECT_
#include "CDspCommObject.h"
//*****************************************************************************
//
// Layla clock numbers to send to DSP
//
//*****************************************************************************
#define LAYLA20_CLOCK_INTERNAL 0
#define LAYLA20_CLOCK_SPDIF 1
#define LAYLA20_CLOCK_WORD 2
#define LAYLA20_CLOCK_SUPER 3
//*****************************************************************************
//
// CLaylaDspCommObject
//
//*****************************************************************************
class CLaylaDspCommObject : public CDspCommObject
{
protected:
BYTE m_byInputTrims[8]; // Input trims for Layla20's 8 analog
// inputs
public:
//
// Construction/destruction
//
CLaylaDspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport );
virtual ~CLaylaDspCommObject();
//
// Set the DSP sample rate
// Return rate that was set, -1 if error
//
virtual DWORD SetSampleRate( DWORD dwNewSampleRate );
//
// Send current setting to DSP & return what it is
//
virtual DWORD SetSampleRate()
{ return( SetSampleRate( GetSampleRate() ) ); }
//
// Card information
//
virtual WORD GetCardType()
{ return( LAYLA ); }
//
// Set clocks
//
virtual ECHOSTATUS SetOutputClock(WORD wClock);
virtual ECHOSTATUS SetInputClock(WORD wClock);
//
// Input gain
//
virtual ECHOSTATUS SetBusInGain(WORD wBusIn,int iGain);
virtual ECHOSTATUS GetBusInGain(WORD wBusIn,int &iGain);
virtual ECHOSTATUS SetNominalLevel( WORD wBus, BOOL bState );
virtual BOOL IsMidiOutActive();
protected:
virtual BOOL LoadASIC();
}; // class CLaylaDspCommObject
typedef CLaylaDspCommObject * PCLaylaDspCommObject;
#endif
// **** LaylaDspCommObject.h ****

View File

@ -0,0 +1,363 @@
// ****************************************************************************
//
// CLineLevel.cpp
//
// Source file for EchoGals generic driver line level control class.
//
// Controls line levels for input and output busses.
//
// Implemented as a base class with 2 derived classes, one for
// each type of bus.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
/****************************************************************************
CLineLevel - Construction and destruction
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CLineLevel::CLineLevel()
{
Init( 0, NULL, NULL );
} // CLineLevel::CLineLevel()
//===========================================================================
//
// Destructor
//
//===========================================================================
CLineLevel::~CLineLevel()
{
} // CLineLevel::~CLineLevel()
//===========================================================================
//
// Initialization
//
//===========================================================================
void CLineLevel::Init
(
WORD wChannelIndex, // Which channel we represent
CEchoGals * pEchoGals, // For setting line levels
INT32 iGain // Initial gain setting
)
{
m_iGain = 0; // Current gain in dB X 256
m_fMuted = FALSE;
m_pEchoGals = pEchoGals; // Ptr to our creator object
m_wChannelIndex = wChannelIndex;
// pipe index for this line
if ( NULL != m_pEchoGals &&
NULL != m_pEchoGals->GetDspCommObject() &&
!m_pEchoGals->GetDspCommObject()->IsBoardBad() )
{
SetGain( iGain ); // If DSP is up, then set gain to caller's
// initial value
}
} // void CLineLevel::Init
/****************************************************************************
CLineLevel - Set and get stuff
****************************************************************************/
//===========================================================================
//
// Set the mute
//
//===========================================================================
ECHOSTATUS CLineLevel::SetMute( BOOL fMute )
{
m_fMuted = fMute;
return SetGain(ECHOGAIN_UPDATE);
}
/****************************************************************************
CBusInLineLevel - Construction and destruction
****************************************************************************/
//===========================================================================
//
// Construction/destruction
//
//===========================================================================
CBusInLineLevel::CBusInLineLevel()
{
} // CBusInLineLevel::CBusInLineLevel()
CBusInLineLevel::~CBusInLineLevel()
{
} // COutLineLevel::~COutLineLevel()
/****************************************************************************
CBusInLineLevel - Get and set stuff
****************************************************************************/
//===========================================================================
//
// Set the mute
//
//===========================================================================
ECHOSTATUS CBusInLineLevel::SetMute( BOOL fMute )
{
if (fMute != m_fMuted)
{
m_pEchoGals->MixerControlChanged(ECHO_BUS_IN,
MXN_MUTE,
m_wChannelIndex);
}
return CLineLevel::SetMute(fMute);
}
//===========================================================================
//
// Set the gain
//
//===========================================================================
ECHOSTATUS CBusInLineLevel::SetGain
(
INT32 iGain,
BOOL fImmediate
)
{
ECHOSTATUS Status;
if ( NULL == m_pEchoGals ||
NULL == m_pEchoGals->GetDspCommObject() ||
m_pEchoGals->GetDspCommObject()->IsBoardBad() )
return ECHOSTATUS_DSP_DEAD;
//
// If the magic ECHOGAIN_UPDATE value was passed in,
// use the stored gain. Otherwise, clamp the gain.
//
if ( ECHOGAIN_UPDATE == iGain )
iGain = m_iGain;
else if ( iGain < ECHOGAIN_MININP )
iGain = ECHOGAIN_MININP;
else if ( iGain > ECHOGAIN_MAXINP )
iGain = ECHOGAIN_MAXINP;
//
// Generate a control notify if necessary
//
if ( m_iGain != iGain )
{
m_iGain = iGain;
m_pEchoGals->MixerControlChanged(ECHO_BUS_IN,
MXN_LEVEL,
m_wChannelIndex);
}
//
// Mute?
//
if (m_fMuted)
{
iGain = ECHOGAIN_MININP;
}
//
// Tell the DSP what to do
//
iGain <<= 1; // Preserver half-dB steps in input gain
Status =
m_pEchoGals->GetDspCommObject()->SetBusInGain
( m_wChannelIndex,
(BYTE) ( GENERIC_TO_DSP( iGain ) ) );
// Shift iGain up by 1 to preserve half-dB steps
return Status;
} // ECHOSTATUS CBusInLineLevel::SetGain
/****************************************************************************
CBusOutLineLevel - Construction and destruction
****************************************************************************/
//===========================================================================
//
// Construction/destruction
//
//===========================================================================
//
// Construction/destruction
//
CBusOutLineLevel::CBusOutLineLevel()
{
} // CBusOutLineLevel::CBusOutLineLevel()
CBusOutLineLevel::~CBusOutLineLevel()
{
} // CBusOutLineLevel::~CBusOutLineLevel()
/****************************************************************************
CBusOutLineLevel - Get and set stuff
****************************************************************************/
//===========================================================================
//
// Set the mute
//
//===========================================================================
ECHOSTATUS CBusOutLineLevel::SetMute( BOOL fMute )
{
if (fMute != m_fMuted)
{
m_pEchoGals->MixerControlChanged(ECHO_BUS_OUT,
MXN_MUTE,
m_wChannelIndex);
}
return CLineLevel::SetMute(fMute);
}
//===========================================================================
//
// Set the gain
//
//===========================================================================
ECHOSTATUS CBusOutLineLevel::SetGain
(
INT32 iGain,
BOOL fImmediate
)
{
ECHOSTATUS Status = ECHOSTATUS_OK;
if ( NULL == m_pEchoGals ||
NULL == m_pEchoGals->GetDspCommObject() ||
m_pEchoGals->GetDspCommObject()->IsBoardBad() )
return ECHOSTATUS_DSP_DEAD;
//
// If iGain is ECHOGAIN_UPDATE, then the caller
// wants this function to re-do the gain setting
// with the currently stored value
//
// Otherwise, clamp the gain setting
//
if ( ECHOGAIN_UPDATE == iGain )
iGain = m_iGain;
else if ( iGain < ECHOGAIN_MUTED )
iGain = ECHOGAIN_MUTED;
else if ( iGain > ECHOGAIN_MAXOUT )
iGain = ECHOGAIN_MAXOUT;
//
// Mark this control as changed
//
if ( m_iGain != iGain )
{
m_iGain = iGain;
if ( ECHOSTATUS_OK == Status )
Status = m_pEchoGals->MixerControlChanged(ECHO_BUS_OUT,
MXN_LEVEL,
m_wChannelIndex);
}
//
// Set the gain to mute if this bus is muted
//
int iGainTemp = iGain;
if ( m_fMuted )
iGainTemp = ECHOGAIN_MUTED;
//
// Tell all the monitors for this output bus to
// update their gains
//
m_pEchoGals->AdjustMonitorsForBusOut(m_wChannelIndex);
//
// Tell all the output pipes for this output bus
// to update their gains
//
m_pEchoGals->AdjustPipesOutForBusOut(m_wChannelIndex,iGainTemp);
return Status;
} // ECHOSTATUS CBusOutLineLevel::SetGain
// **** CLineLevel.cpp ****

View File

@ -0,0 +1,188 @@
// ****************************************************************************
//
// CLineLevel.h
//
// Include file for EchoGals generic driver line level state machine.
//
// Class for setting and getting mixer values for input and output busses.
//
// Implemented as a base class with 3 derived classes, one for
// each type of line.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _CLineLevel_
#define _CLineLevel_
class CEchoGals;
/****************************************************************************
CLineLevel - Base class
****************************************************************************/
class CLineLevel
{
protected :
INT32 m_iGain; // Current gain in dB X 256
BOOL m_fMuted;
CEchoGals * m_pEchoGals; // Ptr to our creator object
WORD m_wChannelIndex; // pipe index for this line
public:
//
// Construction/destruction
//
CLineLevel();
virtual ~CLineLevel();
//
// Initialization function for initializing arrays of this class
//
void Init
(
WORD wChannelIndex, // Which channel we represent
CEchoGals * pEchoGals, // For setting line levels
INT32 iGain = 0 // Initial gain setting
);
//
// Mute
//
virtual ECHOSTATUS SetMute( BOOL bOn );
BOOL IsMuteOn() { return m_fMuted; }
//
// Gain functions
//
INT32 GetGain() { return( m_iGain ); }
virtual ECHOSTATUS SetGain(
INT32 iGain,
BOOL fImmediate = TRUE
) = NULL;
}; // class CLineLevel
typedef CLineLevel * PCLineLevel;
/****************************************************************************
CBusInLineLevel - Derived class for managing input bus gains
****************************************************************************/
class CBusInLineLevel : public CLineLevel
{
protected :
public:
//
// Construction/destruction
//
CBusInLineLevel();
virtual ~CBusInLineLevel();
//
// Mute
//
virtual ECHOSTATUS SetMute( BOOL bOn );
//
// Gain functions
//
virtual ECHOSTATUS SetGain
(
INT32 iGain,
BOOL fImmediate = TRUE
);
}; // class CBusInLineLevel
typedef CBusInLineLevel * PCBusInLineLevel;
/****************************************************************************
CBusOutLineLevel - Derived class for managing output bus gains
****************************************************************************/
class CBusOutLineLevel : public CLineLevel
{
protected :
public:
//
// Construction/destruction
//
CBusOutLineLevel();
virtual ~CBusOutLineLevel();
//
// Mute
//
virtual ECHOSTATUS SetMute( BOOL bOn );
//
// Gain functions
//
virtual ECHOSTATUS SetGain
(
INT32 iGain,
BOOL fImmediate = TRUE
);
}; // class CBusOutLineLevel
typedef CBusOutLineLevel * PCBusOutLineLevel;
#endif
// **** CLineLevel.h ****

View File

@ -0,0 +1,348 @@
// ****************************************************************************
//
// CMia.cpp
//
// Implementation file for the CMia driver class.
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CMia.h"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CMia::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CMia::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CMia::operator new( size_t Size )
VOID CMia::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("CMia::operator delete memory free failed\n"));
}
} // VOID CMia::operator delete( PVOID pVoid )
//===========================================================================
//
// Constructor and destructor
//
//===========================================================================
CMia::CMia( PCOsSupport pOsSupport )
: CEchoGals( pOsSupport )
{
ECHO_DEBUGPRINTF( ( "CMia::CMia() is born!\n" ) );
}
CMia::~CMia()
{
ECHO_DEBUGPRINTF( ( "CMia::~CMia() is toast!\n" ) );
}
/****************************************************************************
Setup and hardware initialization
****************************************************************************/
//===========================================================================
//
// Every card has an InitHw method
//
//===========================================================================
ECHOSTATUS CMia::InitHw()
{
ECHOSTATUS Status;
WORD i;
//
// Call the base method
//
if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
return Status;
//
// Create the DSP comm object
//
ASSERT( NULL == m_pDspCommObject );
m_pDspCommObject = new CMiaDspCommObject( (PDWORD) m_pvSharedMemory,
m_pOsSupport );
if (NULL == m_pDspCommObject)
{
ECHO_DEBUGPRINTF(("CMia::InitHw - could not create DSP comm object\n"));
return ECHOSTATUS_NO_MEM;
}
//
// Load the DSP
//
GetDspCommObject()->LoadFirmware();
if ( GetDspCommObject()->IsBoardBad() )
return ECHOSTATUS_DSP_DEAD;
//
// Clear the "bad board" flag; set the flags to indicate that
// Mia can handle super-interleave.
//
m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK;
//
// Must call this here after DSP is init to
// init gains and mutes
//
Status = InitLineLevels();
if ( ECHOSTATUS_OK != Status )
return Status;
//
// Set defaults for +4/-10
//
for (i = 0; i < GetFirstDigitalBusOut(); i++ )
{
GetDspCommObject()->
SetNominalLevel( i, FALSE ); // FALSE is +4 here
}
for ( i = 0; i < GetFirstDigitalBusIn(); i++ )
{
GetDspCommObject()->
SetNominalLevel( GetNumBussesOut() + i, FALSE );
}
//
// Set the digital mode to S/PDIF RCA
//
SetDigitalMode( DIGITAL_MODE_SPDIF_RCA );
//
// Get default sample rate from DSP
//
m_dwSampleRate = GetDspCommObject()->GetSampleRate();
ECHO_DEBUGPRINTF( ( "CMia::InitHw()\n" ) );
return Status;
} // ECHOSTATUS CMia::InitHw()
/****************************************************************************
Informational methods
****************************************************************************/
//===========================================================================
//
// Override GetCapabilities to enumerate unique capabilties for this card
//
//===========================================================================
ECHOSTATUS CMia::GetCapabilities
(
PECHOGALS_CAPS pCapabilities
)
{
ECHOSTATUS Status;
WORD i;
Status = GetBaseCapabilities(pCapabilities);
if ( ECHOSTATUS_OK != Status )
return Status;
//
// Add meters & pans to output pipes
//
for (i = 0 ; i < GetNumPipesOut(); i++)
{
pCapabilities->dwPipeOutCaps[i] |= ECHOCAPS_PEAK_METER |
ECHOCAPS_PAN;
}
//
// Add nominal level control to analog ins & outs
//
for (i = 0 ; i < GetFirstDigitalBusOut(); i++)
{
pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
}
for (i = 0 ; i < GetFirstDigitalBusIn(); i++)
{
pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
}
pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_SPDIF;
pCapabilities->dwOutClockTypes = 0;
return Status;
} // ECHOSTATUS CMia::GetCapabilities
//===========================================================================
//
// QueryAudioSampleRate is used to find out if this card can handle a
// given sample rate.
//
//===========================================================================
ECHOSTATUS CMia::QueryAudioSampleRate
(
DWORD dwSampleRate
)
{
if ( dwSampleRate != 8000 &&
dwSampleRate != 11025 &&
dwSampleRate != 12000 &&
dwSampleRate != 16000 &&
dwSampleRate != 22050 &&
dwSampleRate != 24000 &&
dwSampleRate != 32000 &&
dwSampleRate != 44100 &&
dwSampleRate != 48000 &&
dwSampleRate != 88200 &&
dwSampleRate != 96000 )
{
ECHO_DEBUGPRINTF(
("CMia::QueryAudioSampleRate() Sample rate must be "
" 8,000 Hz, 11,025 Hz, 12,000 Hz, 16,000 Hz, 22,050 Hz, "
"24,000 Hz, 32,000 Hz, 44,100 Hz, 48,000 Hz, 88,200 Hz "
"or 96,000 Hz\n") );
return ECHOSTATUS_BAD_FORMAT;
}
ECHO_DEBUGPRINTF( ( "CMia::QueryAudioSampleRate()\n" ) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CMia::QueryAudioSampleRate
//===========================================================================
//
// GetInputClockDetect returns a bitmask consisting of all the input
// clocks currently connected to the hardware; this changes as the user
// connects and disconnects clock inputs.
//
// You should use this information to determine which clocks the user is
// allowed to select.
//
// Mia supports S/PDIF input clock.
//
//===========================================================================
ECHOSTATUS CMia::GetInputClockDetect(DWORD &dwClockDetectBits)
{
ECHO_DEBUGPRINTF(("CMia::GetInputClockDetect\n"));
if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
{
ECHO_DEBUGPRINTF( ("CMia::GetInputClockDetect: DSP Dead!\n") );
return ECHOSTATUS_DSP_DEAD;
}
//
// Map the DSP clock detect bits to the generic driver clock detect bits
//
DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SPDIF))
dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
return ECHOSTATUS_OK;
} // GetInputClockDetect
//===========================================================================
//
// Most of the cards don't have an actual output bus gain; they only
// have gain controls for output pipes; the output bus gain is implemented
// as a logical control. Mia (and any other card with a vmixer) works
// differently; it does have a physical output bus gain control, so
// just pass the gain down to the DSP comm object.
//
//===========================================================================
ECHOSTATUS CMia::AdjustPipesOutForBusOut(WORD wBusOut,int iBusOutGain)
{
GetDspCommObject()->SetBusOutGain(wBusOut,iBusOutGain);
return ECHOSTATUS_OK;
} // AdjustPipesOutForBusOut
// *** Mia.cpp ***

View File

@ -0,0 +1,122 @@
// ****************************************************************************
//
// CMia.H
//
// Include file for interfacing with the CMia generic driver class
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _MIAOBJECT_
#define _MIAOBJECT_
#include "CEchoGals.h"
#include "CMiaDspCommObject.h"
//
// Class used for interfacing with the Mia audio card.
//
class CMia : public CEchoGals
{
public:
//
// Construction/destruction
//
CMia( PCOsSupport pOsSupport );
virtual ~CMia();
//
// Setup & initialization methods
//
virtual ECHOSTATUS InitHw();
//
// Adapter information methods
//
//
// Return the capabilities of this card; card type, card name,
// # analog inputs, # analog outputs, # digital channels,
// # MIDI ports and supported clocks.
// See ECHOGALS_CAPS definition above.
//
virtual ECHOSTATUS GetCapabilities
(
PECHOGALS_CAPS pCapabilities
);
//
// Audio Interface methods
//
virtual ECHOSTATUS QueryAudioSampleRate
(
DWORD dwSampleRate
);
//
// Get a bitmask of all the clocks the hardware is currently detecting
//
virtual ECHOSTATUS GetInputClockDetect(DWORD &dwClockDetectBits);
//
// Adjust all the output pipe levels for a particular output bus
//
virtual ECHOSTATUS AdjustPipesOutForBusOut(WORD wBusOut,int iBusOutGain);
//
// Overload new & delete so memory for this object is allocated from
// non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
protected:
//
// Get access to the appropriate DSP comm object
//
PCMiaDspCommObject GetDspCommObject()
{ return( (PCMiaDspCommObject) m_pDspCommObject ); }
}; // class CMia
typedef CMia * PCMia;
#endif
// *** Mia.H ***

View File

@ -0,0 +1,466 @@
// ****************************************************************************
//
// CMiaDspCommObject.cpp
//
// Implementation file for EchoGals generic driver Darla 24 DSP
// interface class.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CMiaDspCommObject.h"
#include "MiaDSP.c"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CMiaDspCommObject::CMiaDspCommObject
(
PDWORD pdwRegBase, // Virtual ptr to DSP registers
PCOsSupport pOsSupport
) : CDspCommObject( pdwRegBase, pOsSupport )
{
strcpy( m_szCardName, "Mia" );
m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base
m_wNumPipesOut = 8;
m_wNumPipesIn = 4;
m_wNumBussesOut = 4;
m_wNumBussesIn = 4;
m_wFirstDigitalBusOut = 2;
m_wFirstDigitalBusIn = 2;
m_fHasVmixer = TRUE;
m_wNumMidiOut = 0; // # MIDI out channels
m_wNumMidiIn = 0; // # MIDI in channels
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 44100 );
m_bHasASIC = FALSE;
m_pwDspCodeToLoad = pwMiaDSP;
m_byDigitalMode = DIGITAL_MODE_NONE;
//
// Since this card has no ASIC, mark it as loaded so everything works OK
//
m_bASICLoaded = TRUE;
} // CMiaDspCommObject::CMiaDspCommObject( DWORD dwPhysRegBase )
//===========================================================================
//
// Destructor
//
//===========================================================================
CMiaDspCommObject::~CMiaDspCommObject()
{
} // CMiaDspCommObject::~CMiaDspCommObject()
/****************************************************************************
Hardware setup and config
****************************************************************************/
//===========================================================================
//
// Set the input clock
//
//===========================================================================
ECHOSTATUS CMiaDspCommObject::SetInputClock(WORD wClock)
{
DWORD dwSampleRate = GetSampleRate();
ECHO_DEBUGPRINTF( ("CMiaDspCommObject::SetInputClock:\n") );
switch ( wClock )
{
case ECHO_CLOCK_INTERNAL :
{
ECHO_DEBUGPRINTF( ( "\tSet Mia clock to INTERNAL\n" ) );
// If the sample rate is out of range for some reason, set it
// to a reasonable value. mattg
if ( ( dwSampleRate < 8000 ) ||
( dwSampleRate > 96000 ) )
{
dwSampleRate = 48000;
}
break;
} // CLK_CLOCKININTERNAL
case ECHO_CLOCK_SPDIF :
{
ECHO_DEBUGPRINTF( ( "\tSet Mia clock to SPDIF\n" ) );
break;
} // CLK_CLOCKINSPDIF
default :
ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for Mia\n",wClock));
ECHO_DEBUGBREAK();
return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
} // switch (wInputClock)
m_wInputClock = wClock;
SetSampleRate( dwSampleRate );
return ECHOSTATUS_OK;
} // ECHOSTATUS CMiaDspCommObject::SetInputClock
//===========================================================================
//
// SetSampleRate
//
// Set the audio sample rate for Mia
//
//===========================================================================
DWORD CMiaDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
{
//
// Set the sample rate
//
DWORD dwControlReg = MIA_48000;
switch ( dwNewSampleRate )
{
case 96000 :
dwControlReg = MIA_96000;
break;
case 88200 :
dwControlReg = MIA_88200;
break;
case 44100 :
dwControlReg = MIA_44100;
break;
case 32000 :
dwControlReg = MIA_32000;
break;
case 24000 :
dwControlReg = MIA_24000;
break;
case 22050 :
dwControlReg = MIA_22050;
break;
case 16000 :
dwControlReg = MIA_16000;
break;
case 12000 :
dwControlReg = MIA_12000;
break;
case 11025 :
dwControlReg = MIA_11025;
break;
case 8000 :
dwControlReg = MIA_8000;
break;
}
//
// Override the clock setting if this Mia is set to S/PDIF clock
//
if ( ECHO_CLOCK_SPDIF == GetInputClock() )
{
dwControlReg &= MIA_SRC_MASK;
dwControlReg |= MIA_SPDIF;
}
//
// Set the control register if it has changed
//
if (dwControlReg != GetControlRegister())
{
if ( !WaitForHandshake() )
return 0xffffffff;
//
// Set the values in the comm page; the dwSampleRate
// field isn't used by the DSP, but is read by the call
// to GetSampleRate below
//
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
SetControlRegister( dwControlReg );
//
// Poke the DSP
//
ClearHandshake();
SendVector( DSP_VC_UPDATE_CLOCKS );
}
return GetSampleRate();
} // DWORD CMiaDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
//===========================================================================
//
// GetAudioMeters
//
// Meters are written to the comm page by the DSP as follows:
//
// Output busses
// Input busses
// Output pipes (vmixer cards only)
//
// This function is overridden for vmixer cards
//
//===========================================================================
ECHOSTATUS CMiaDspCommObject::GetAudioMeters
(
PECHOGALS_METERS pMeters
)
{
WORD i;
pMeters->iNumPipesIn = 0;
//
// Output
//
DWORD dwCh = 0;
pMeters->iNumBussesOut = (int) m_wNumBussesOut;
for (i = 0; i < m_wNumBussesOut; i++)
{
pMeters->iBusOutVU[i] =
DSP_TO_GENERIC( ((int) (char) m_pDspCommPage->VULevel[ dwCh ]) );
pMeters->iBusOutPeak[i] =
DSP_TO_GENERIC( ((int) (char) m_pDspCommPage->PeakMeter[ dwCh ]) );
dwCh++;
}
pMeters->iNumBussesIn = (int) m_wNumBussesIn;
for (i = 0; i < m_wNumPipesIn; i++)
{
pMeters->iBusInVU[i] =
DSP_TO_GENERIC( ((int) (char) m_pDspCommPage->VULevel[ dwCh ]) );
pMeters->iBusInPeak[i] =
DSP_TO_GENERIC( ((int) (char) m_pDspCommPage->PeakMeter[ dwCh ]) );
dwCh++;
}
pMeters->iNumPipesOut = (int) m_wNumPipesOut;
for (i = 0; i < m_wNumPipesOut; i++)
{
pMeters->iPipeOutVU[i] =
DSP_TO_GENERIC( ((int) (char) m_pDspCommPage->VULevel[ dwCh ]) );
pMeters->iPipeOutPeak[i] =
DSP_TO_GENERIC( ((int) (char) m_pDspCommPage->PeakMeter[ dwCh ]) );
dwCh++;
}
return ECHOSTATUS_OK;
} // GetAudioMeters
//===========================================================================
//
// GetPipeOutGain and SetPipeOutGain
//
// On Mia, this doesn't set the line out volume; instead, it sets the
// vmixer volume.
//
//===========================================================================
ECHOSTATUS CMiaDspCommObject::SetPipeOutGain
(
WORD wPipeOut,
WORD wBusOut,
int iGain,
BOOL fImmediate
)
{
if (wPipeOut >= m_wNumPipesOut)
{
ECHO_DEBUGPRINTF( ("CDspCommObject::SetPipeOutGain: Invalid out pipe "
"%d\n",
wPipeOut) );
return ECHOSTATUS_INVALID_CHANNEL;
}
iGain = GENERIC_TO_DSP(iGain);
if ( wBusOut < m_wNumBussesOut )
{
if ( !WaitForHandshake() )
return ECHOSTATUS_DSP_DEAD;
DWORD dwIndex = wBusOut * m_wNumPipesOut + wPipeOut;
m_pDspCommPage->byVmixerLevel[ dwIndex ] = (BYTE) iGain;
ECHO_DEBUGPRINTF( ("CMiaDspCommObject::SetPipeOutGain: Out pipe %d, "
"out bus %d = %u\n",
wPipeOut,
wBusOut,
iGain) );
if (fImmediate)
{
return UpdateVmixerLevel();
}
return ECHOSTATUS_OK;
}
ECHO_DEBUGPRINTF( ("CMiaDspCommObject::SetPipeOutGain: Invalid out bus "
"%d\n",
wBusOut) );
return ECHOSTATUS_INVALID_CHANNEL;
} // SetPipeOutGain
ECHOSTATUS CMiaDspCommObject::GetPipeOutGain
(
WORD wPipeOut,
WORD wBusOut,
int &iGain
)
{
if (wPipeOut >= m_wNumPipesOut)
{
ECHO_DEBUGPRINTF( ("CMiaDspCommObject::GetPipeOutGain: Invalid out pipe "
"%d\n",
wPipeOut) );
return ECHOSTATUS_INVALID_CHANNEL;
}
if (wBusOut < m_wNumBussesOut)
{
iGain = m_pDspCommPage->byVmixerLevel[ wBusOut * m_wNumPipesOut + wPipeOut ];
iGain = DSP_TO_GENERIC(iGain);
return ECHOSTATUS_OK;
}
ECHO_DEBUGPRINTF( ("CMiaDspCommObject::GetPipeOutGain: Invalid out bus "
"%d\n",
wBusOut) );
return ECHOSTATUS_INVALID_CHANNEL;
} // GetPipeOutGain
//===========================================================================
//
// SetBusOutGain
//
//===========================================================================
ECHOSTATUS CMiaDspCommObject::SetBusOutGain(WORD wBusOut,int iGain)
{
if ( wBusOut < m_wNumBussesOut )
{
if ( !WaitForHandshake() )
return ECHOSTATUS_DSP_DEAD;
iGain = GENERIC_TO_DSP(iGain);
m_pDspCommPage->OutLineLevel[ wBusOut ] = (BYTE) iGain;
ECHO_DEBUGPRINTF( ("CMiaDspCommObject::SetBusOutGain: Out bus %d "
"= %u\n",
wBusOut,
iGain) );
return UpdateAudioOutLineLevel();
}
ECHO_DEBUGPRINTF( ("CMiaDspCommObject::SetBusOutGain: Invalid out bus "
"%d\n",
wBusOut) );
return ECHOSTATUS_INVALID_CHANNEL;
}
//===========================================================================
//
// Tell the DSP to read and update vmixer levels
// from the comm page.
//
//===========================================================================
ECHOSTATUS CMiaDspCommObject::UpdateVmixerLevel()
{
ECHO_DEBUGPRINTF( ( "CMiaDspCommObject::UpdateVmixerLevel:\n" ) );
ClearHandshake();
return( SendVector( DSP_VC_SET_VMIXER_GAIN ) );
}
// **** CMiaDspCommObject.cpp ****

View File

@ -0,0 +1,113 @@
// ****************************************************************************
//
// CMiaDspCommObject.H
//
// Include file for EchoGals generic driver Mia DSP interface class.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _MIADSPCOMMOBJECT_
#define _MIADSPCOMMOBJECT_
#include "CDspCommObject.h"
class CMiaDspCommObject : public CDspCommObject
{
public:
//
// Construction/destruction
//
CMiaDspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport );
virtual ~CMiaDspCommObject();
//
// Set the DSP sample rate.
// Return rate that was set, -1 if error
//
virtual DWORD SetSampleRate( DWORD dwNewSampleRate );
//
// Send current setting to DSP & return what it is
//
virtual DWORD SetSampleRate()
{ return( SetSampleRate( GetSampleRate() ) ); }
//
// Card information
//
virtual WORD GetCardType()
{ return( MIA ); }
//
// Set input clock
//
virtual ECHOSTATUS SetInputClock(WORD wClock);
virtual ECHOSTATUS GetAudioMeters
(
PECHOGALS_METERS pMeters
);
virtual ECHOSTATUS SetPipeOutGain
(
WORD wPipeOut,
WORD wBusOut,
int iGain,
BOOL fImmediate = TRUE
);
virtual ECHOSTATUS GetPipeOutGain
(
WORD wPipeOut,
WORD wBusOut,
int &iGain
);
virtual ECHOSTATUS UpdateVmixerLevel();
virtual ECHOSTATUS SetBusOutGain(WORD wBusOut,int iGain);
protected:
BOOL m_bProfessionalSpdif; // S/PDIF pro/consumer setting
}; // class CMiaDspCommObject
typedef CMiaDspCommObject * PCMiaDspCommObject;
#endif
// **** CMiaDspCommObject.h ****

View File

@ -0,0 +1,461 @@
// ****************************************************************************
//
// CMidiInQ.cpp
//
// Implementation file for the CMidiInQ class.
// Use a simple fixed size queue for managing MIDI data.
// Fill & drain pointers are maintained automatically whenever
// an Add or Get function succeeds.
//
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
/****************************************************************************
Construction and destruction, clean up and init
****************************************************************************/
//============================================================================
//
// Construction & destructor
//
//============================================================================
CMidiInQ::CMidiInQ()
{
Reset();
m_pBuffer = NULL;
m_ullLastActivityTime = 0;
m_wMtcState = MTC_STATE_NORMAL;
m_pEG = NULL;
m_fArmed = FALSE;
} // CMidiInQ::CMidiInQ()
CMidiInQ::~CMidiInQ()
{
Cleanup();
} // CMidiInQ::~CMidiInQ()
//============================================================================
//
// Init
//
//============================================================================
ECHOSTATUS CMidiInQ::Init( CEchoGals *pEG )
{
ECHOSTATUS Status;
ECHO_DEBUGPRINTF(("CMidiInQ::Init\n"));
m_pEG = pEG;
Status = OsAllocateNonPaged( sizeof(MIDI_DATA) * ECHO_MIDI_QUEUE_SZ,
(PPVOID) &m_pBuffer);
if (ECHOSTATUS_OK == Status)
Reset();
return Status;
} // Init
//============================================================================
//
// Cleanup
//
//============================================================================
void CMidiInQ::Cleanup()
{
//
// Free the MIDI input buffer
//
if (NULL != m_pBuffer)
{
if (ECHOSTATUS_OK != OsFreeNonPaged( m_pBuffer ))
{
ECHO_DEBUGPRINTF(("CMidiInQ::Cleanup - Failed to free MIDI input bufer\n"));
}
}
m_pBuffer = NULL;
}
/****************************************************************************
Queue management - add and remove MIDI data
****************************************************************************/
//============================================================================
//
// GetMidi - get oldest MIDI input byte from the Q
//
//============================================================================
ECHOSTATUS CMidiInQ::GetMidi
(
MIDI_DATA &Midi
)
{
if (NULL == m_pBuffer)
return ECHOSTATUS_CHANNEL_NOT_OPEN;
if ( m_pFill == m_pDrain )
return( ECHOSTATUS_NO_DATA );
Midi = *m_pDrain;
ECHO_DEBUGPRINTF( ("CMidiInQ::GetMidi 0x%x\n", Midi) );
m_pDrain = ComputeNext( m_pDrain );
return ECHOSTATUS_OK;
} // ECHOSTATUS CMidiInQ::GetMidi
//============================================================================
//
// AddMidi - add new MIDI input byte to the Q
//
//============================================================================
ECHOSTATUS CMidiInQ::AddMidi
(
MIDI_DATA Midi
)
{
if ( ComputeNext( m_pFill ) == m_pDrain )
{
ECHO_DEBUGPRINTF( ("CMidiInQ::AddMidi buffer overflow\n") );
ECHO_DEBUGBREAK();
return ECHOSTATUS_BUFFER_OVERFLOW;
}
ECHO_DEBUGPRINTF( ("CMidiInQ::AddMidi 0x%x\n", Midi) );
*m_pFill = Midi;
m_pFill = ComputeNext( m_pFill );
return ECHOSTATUS_OK;
} // ECHOSTATUS CMidiInQ::AddMidi
//============================================================================
//
// ComputeNext - protected routine used to wrap the read and write pointers
// around the circular buffer
//
//============================================================================
PMIDI_DATA CMidiInQ::ComputeNext( PMIDI_DATA pCur )
{
if ( ++pCur >= m_pEnd )
pCur = m_pBuffer;
return pCur;
} // PMIDI_DATA CMidiInQ::ComputeNext( PMIDI_DATA pCur )
//============================================================================
//
// Reset
//
//============================================================================
void CMidiInQ::Reset()
{
//
// Midi buffer pointer initialization
//
m_pEnd = m_pBuffer + ECHO_MIDI_QUEUE_SZ;
m_pFill = m_pBuffer;
m_pDrain = m_pBuffer;
} // void CMidiInQ::Reset()
/****************************************************************************
Arm and disarm
****************************************************************************/
//============================================================================
//
// Arm - resets the Q and enables the Q to start receiving MIDI input data
//
//============================================================================
ECHOSTATUS CMidiInQ::Arm()
{
//
// Return if the MIDI input buffer is not allocated
//
if ( (NULL == m_pBuffer) ||
(NULL == m_pEG)
)
return ECHOSTATUS_CANT_OPEN;
//
// Reset the buffer pointers
//
Reset();
//
// Tell the DSP to enable MIDI input
//
m_pEG->GetDspCommObject()->SetMidiOn( TRUE );
//
// Set the flag
//
m_fArmed = TRUE;
return ECHOSTATUS_OK;
} // Arm
//============================================================================
//
// Disarm - surprisingly, does the opposite of Arm
//
//============================================================================
void CMidiInQ::Disarm()
{
//
// Tell the DSP to disable MIDI input
//
if (m_pEG)
m_pEG->GetDspCommObject()->SetMidiOn( FALSE );
//
// Clear the flag
//
m_fArmed = FALSE;
} // Disarm
/****************************************************************************
Detect MIDI input activity - see if the driver has recently received
any MIDI input
****************************************************************************/
BOOL CMidiInQ::IsActive()
{
ULONGLONG ullCurTime,ullDelta;
//
// See if anything has happened recently
//
m_pEG->m_pOsSupport->OsGetSystemTime( &ullCurTime );
ullDelta = ullCurTime - m_ullLastActivityTime;
if (ullDelta > MIDI_ACTIVITY_TIMEOUT_USEC)
return FALSE;
return TRUE;
} // IsActive
/****************************************************************************
MIDI time code
****************************************************************************/
//===========================================================================
//
// Run the state machine for MIDI input data
//
// MIDI time code sync isn't supported by this code right now,
// but you still need this state machine to parse the incoming
// MIDI data stream. Every time the DSP sees a 0xF1 byte come in,
// it adds the DSP sample position to the MIDI data stream.
// The DSP sample position is represented as a 32 bit unsigned
// value, with the high 16 bits first, followed by the low 16 bits.
//
// Since these aren't real MIDI bytes, the following logic is
// needed to skip them.
//
//===========================================================================
DWORD CMidiInQ::MtcProcessData( DWORD dwMidiData )
{
switch ( m_wMtcState )
{
case MTC_STATE_NORMAL :
if ( dwMidiData == 0xF1L )
m_wMtcState = MTC_STATE_TS_HIGH;
break;
case MTC_STATE_TS_HIGH :
m_wMtcState = MTC_STATE_TS_LOW;
return MTC_SKIP_DATA;
break;
case MTC_STATE_TS_LOW :
m_wMtcState = MTC_STATE_F1_DATA;
return MTC_SKIP_DATA;
break;
case MTC_STATE_F1_DATA :
m_wMtcState = MTC_STATE_NORMAL;
break;
}
return 0;
} // DWORD CMidiInQ::MtcProcessData
/****************************************************************************
Interrupt service
****************************************************************************/
ECHOSTATUS CMidiInQ::ServiceIrq()
{
DWORD dwMidiCount;
WORD wIndex;
ECHOSTATUS Status;
CDspCommObject *pDCO;
//
// Store the time for the activity detector
//
m_pEG->m_pOsSupport->OsGetSystemTime( &m_ullLastActivityTime );
//
// Get the MIDI count
//
pDCO = m_pEG->GetDspCommObject();
pDCO->ReadMidi( 0, dwMidiCount ); // The count is at index 0
#ifdef ECHO_DEBUG
ECHO_DEBUGPRINTF( ("\tMIDI interrupt (%ld MIDI bytes)\n", dwMidiCount) );
if ( dwMidiCount == 0 )
{
ECHO_DEBUGBREAK();
}
#endif
//
// Get the MIDI data from the comm page
//
wIndex = 1; // First MIDI byte is at index 1
while ( dwMidiCount-- > 0 )
{
DWORD dwMidiByte;
//
// Get the MIDI byte
//
Status = pDCO->ReadMidi( wIndex++, dwMidiByte );
if ( ECHOSTATUS_OK != Status )
{
ECHO_DEBUGPRINTF(("Failed on ReadMidi\n"));
ECHO_DEBUGBREAK(); // should never happen...
break;
}
//
// Parse the incoming MIDI stream. The incoming MIDI data consists
// of MIDI bytes and timestamps for the MIDI time code 0xF1 bytes.
// MtcProcessData is a little state machine that parses the strem.
//
// If you get MTC_SKIP_DATA back, then this is a timestamp byte,
// not a MIDI byte, so don't store it in the MIDI input buffer.
//
if ( MTC_SKIP_DATA == MtcProcessData( dwMidiByte ) )
continue;
//
// Only store the MIDI data if MIDI input is armed
//
if (m_fArmed)
{
//
// Stash the MIDI and timestamp data and check for overflow
//
if ( ECHOSTATUS_BUFFER_OVERFLOW == AddMidi( (MIDI_DATA) dwMidiByte ) )
{
break;
}
}
} // while there is more MIDI data to read
return ECHOSTATUS_OK;
} // ServiceIrq
// *** CMidiInQ.cpp ***

View File

@ -0,0 +1,159 @@
// ****************************************************************************
//
// CMidiInQ.h
//
// This class manages MIDI input.
//
// Use a simple fixed size queue for storing MIDI data.
//
// Fill & drain pointers are maintained automatically whenever
// an Add or Get function succeeds.
//
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _MIDIQUEUEOBJECT_
#define _MIDIQUEUEOBJECT_
typedef BYTE MIDI_DATA;
typedef MIDI_DATA *PMIDI_DATA;
//
// Class used for simple MIDI byte queue
//
class CMidiInQ
{
public:
//
// Construction/destruction
//
CMidiInQ();
~CMidiInQ();
//
// Init
//
ECHOSTATUS Init(CEchoGals *pEG);
//
// Get the oldest byte from the circular buffer
//
ECHOSTATUS GetMidi
(
MIDI_DATA &Midi
);
//
// Enable and disable MIDI input
//
ECHOSTATUS Arm();
void Disarm();
//
// See if there has been any recent MIDI input activity
//
BOOL IsActive();
//
// Reset the in/out ptrs
//
void Reset();
//
// Service a MIDI input interrupt
//
ECHOSTATUS ServiceIrq();
protected:
//
// Find the next offset into the circular buffer
//
PMIDI_DATA ComputeNext( PMIDI_DATA pCur );
//
// Add a MIDI byte to the circular buffer
//
inline ECHOSTATUS AddMidi
(
MIDI_DATA Midi
);
//
// Parse MIDI time code data
//
DWORD MtcProcessData( DWORD dwMidiData );
//
// Cleanup
//
void Cleanup();
//
// Midi buffer management
//
PMIDI_DATA m_pBuffer;
PMIDI_DATA m_pEnd;
PMIDI_DATA m_pFill;
PMIDI_DATA m_pDrain;
BOOL m_fArmed;
//
// Most recent MIDI input time - used for activity detector
//
ULONGLONG m_ullLastActivityTime;
//
// MIDI time code
//
WORD m_wMtcState;
//
// Other objects
//
CEchoGals *m_pEG;
}; // class CMidiInQ
typedef CMidiInQ * PCMidiInQ;
#endif
// *** CMidiInQ.H ***

View File

@ -0,0 +1,162 @@
// ****************************************************************************
//
// CMidiQueue.cpp
//
// Implementation file for the CMidiQueue class.
// Use a simple fixed size queue for managing MIDI data.
// Fill & drain pointers are maintained automatically whenever
// an Add or Get function succeeds.
//
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CMidiQueue.h"
/****************************************************************************
Construction and destruction
****************************************************************************/
CMidiQueue::CMidiQueue()
{
Reset();
} // CMidiQueue::CMidiQueue()
CMidiQueue::~CMidiQueue()
{
} // CMidiQueue::~CMidiQueue()
/****************************************************************************
Add and retrieve data
****************************************************************************/
//===========================================================================
//
// Get the oldest byte out of the buffer
//
//===========================================================================
ECHOSTATUS CMidiQueue::GetMidi
(
MIDI_DATA &Midi
)
{
if ( m_pFill == m_pDrain )
return( ECHOSTATUS_NO_DATA );
Midi = *m_pDrain;
ECHO_DEBUGPRINTF( ("CMidiQueue::GetMidi 0x%x", Midi) );
m_pDrain = ComputeNext( m_pDrain );
return ECHOSTATUS_OK;
} // ECHOSTATUS CMidiQueue::GetMidi
//===========================================================================
//
// Put a new byte into the buffer
//
//===========================================================================
ECHOSTATUS CMidiQueue::AddMidi
(
MIDI_DATA Midi
)
{
if ( ComputeNext( m_pFill ) == m_pDrain )
{
ECHO_DEBUGPRINTF( ("CMidiQueue::AddMidi buffer overflow\n") );
ECHO_DEBUGBREAK();
return( ECHOSTATUS_BUFFER_OVERFLOW );
}
ECHO_DEBUGPRINTF( ("CMidiQueue::AddMidi 0x%x\n", Midi) );
*m_pFill = Midi;
m_pFill = ComputeNext( m_pFill );
return ECHOSTATUS_OK;
} // ECHOSTATUS CMidiQueue::AddMidi
//===========================================================================
//
// Move the head or tail pointer, wrapping at the end of the buffer
//
//===========================================================================
PMIDI_DATA CMidiQueue::ComputeNext( PMIDI_DATA pCur )
{
if ( ++pCur >= m_pEnd )
pCur = m_Buffer;
return pCur;
} // PMIDI_DATA CMidiQueue::ComputeNext( PMIDI_DATA pCur )
//===========================================================================
//
// Reset the MIDI input buffer
//
//===========================================================================
void CMidiQueue::Reset()
{
//
// Midi buffer pointer initialization
//
m_pEnd = m_Buffer + ECHO_MIDI_QUEUE_SZ;
m_pFill = m_Buffer;
m_pDrain = m_Buffer;
} // void CMidiQueue::Reset()
typedef CMidiQueue * PCMidiQueue;
// *** CMidiQueue.cpp ***

View File

@ -0,0 +1,103 @@
// ****************************************************************************
//
// CMidiQueue.h
//
// Include file for interfacing with the CMidiQueue class.
// Use a simple fixed size queue for managing a MIDI data.
// Fill & drain pointers are maintained automatically whenever
// an Add or Get function succeeds.
//
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _MIDIQUEUEOBJECT_
#define _MIDIQUEUEOBJECT_
typedef BYTE MIDI_DATA;
typedef MIDI_DATA *PMIDI_DATA;
//
// Class used for simple MIDI byte queue
//
class CMidiQueue
{
public:
//
// Construction/destruction
//
CMidiQueue();
~CMidiQueue();
//
// Add/Retrieve methods
//
ECHOSTATUS GetMidi
(
MIDI_DATA &Midi
);
ECHOSTATUS AddMidi
(
MIDI_DATA Midi
);
//
// Reset the in/out ptrs
//
void Reset();
protected:
PMIDI_DATA ComputeNext( PMIDI_DATA pCur );
//
// Midi buffer management
//
MIDI_DATA m_Buffer[ ECHO_MIDI_QUEUE_SZ ];
PMIDI_DATA m_pEnd;
PMIDI_DATA m_pFill;
PMIDI_DATA m_pDrain;
}; // class CMidiQueue
typedef CMidiQueue * PCMidiQueue;
#endif
// *** CMidiQueue.H ***

View File

@ -0,0 +1,307 @@
// ****************************************************************************
//
// CMona.cpp
//
// Implementation file for the CMona driver class.
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CMona.h"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
//===========================================================================
PVOID CMona::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("CMona::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID CMona::operator new( size_t Size )
VOID CMona::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("CMona::operator delete memory free failed\n"));
}
} // VOID CMona::operator delete( PVOID pVoid )
//===========================================================================
//
// Constructor and destructor
//
//===========================================================================
CMona::CMona( PCOsSupport pOsSupport )
: CEchoGals( pOsSupport )
{
ECHO_DEBUGPRINTF( ( "CMona::CMona() is born!\n" ) );
}
CMona::~CMona()
{
ECHO_DEBUGPRINTF( ( "CMona::~CMona() is toast!\n" ) );
}
/****************************************************************************
Setup and hardware initialization
****************************************************************************/
//===========================================================================
//
// Every card has an InitHw method
//
//===========================================================================
ECHOSTATUS CMona::InitHw()
{
ECHOSTATUS Status;
//
// Call the base method
//
if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
return Status;
//
// Create the DSP comm object
//
ASSERT( NULL == m_pDspCommObject );
m_pDspCommObject = new CMonaDspCommObject( (PDWORD) m_pvSharedMemory,
m_pOsSupport );
if (NULL == m_pDspCommObject)
{
ECHO_DEBUGPRINTF(("CMona::InitHw - could not create DSP comm object\n"));
return ECHOSTATUS_NO_MEM;
}
//
// Load the DSP, the PCI card ASIC, and the external box ASIC
//
GetDspCommObject()->LoadFirmware();
if ( GetDspCommObject()->IsBoardBad() )
return ECHOSTATUS_DSP_DEAD;
//
// Clear the "bad board" flag; set the flags to indicate that
// Mona can handle super-interleave and supports the digital
// input auto-mute.
//
m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK |
ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE;
//
// Must call this here after DSP is init to
// init gains and mutes
//
Status = InitLineLevels();
if ( ECHOSTATUS_OK != Status )
return Status;
//
// Set the digital mode to S/PDIF RCA
//
SetDigitalMode( DIGITAL_MODE_SPDIF_RCA );
//
// Set the S/PDIF output format to "professional"
//
SetProfessionalSpdif( TRUE );
//
// Get default sample rate from DSP
//
m_dwSampleRate = GetDspCommObject()->GetSampleRate();
ECHO_DEBUGPRINTF( ( "CMona::InitHw()\n" ) );
return Status;
} // ECHOSTATUS CMona::InitHw()
/****************************************************************************
Informational methods
****************************************************************************/
//===========================================================================
//
// Override GetCapabilities to enumerate unique capabilties for this card
//
//===========================================================================
ECHOSTATUS CMona::GetCapabilities
(
PECHOGALS_CAPS pCapabilities
)
{
ECHOSTATUS Status;
Status = GetBaseCapabilities(pCapabilities);
if ( ECHOSTATUS_OK != Status )
return Status;
pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_WORD |
ECHO_CLOCK_BIT_SPDIF |
ECHO_CLOCK_BIT_ADAT;
return Status;
} // ECHOSTATUS CMona::GetCapabilities
//===========================================================================
//
// QueryAudioSampleRate is used to find out if this card can handle a
// given sample rate.
//
//===========================================================================
ECHOSTATUS CMona::QueryAudioSampleRate
(
DWORD dwSampleRate
)
{
if ( dwSampleRate != 8000 &&
dwSampleRate != 11025 &&
dwSampleRate != 16000 &&
dwSampleRate != 22050 &&
dwSampleRate != 32000 &&
dwSampleRate != 44100 &&
dwSampleRate != 48000 &&
dwSampleRate != 88200 &&
dwSampleRate != 96000 )
{
ECHO_DEBUGPRINTF(
("CMona::QueryAudioSampleRate() Sample rate must be "
" 8,000 Hz, 11,025 Hz, 16,000 Hz, 22,050 Hz, 32,000 Hz, "
"44,100 Hz, 48,000 Hz, 88,200 Hz or 96,000 Hz\n") );
return ECHOSTATUS_BAD_FORMAT;
}
if ( dwSampleRate >= 88200 && DIGITAL_MODE_ADAT == GetDigitalMode() )
{
ECHO_DEBUGPRINTF(
("CMona::QueryAudioSampleRate() Sample rate cannot be "
"set to 88,200 Hz or 96,000 Hz in ADAT mode\n") );
return ECHOSTATUS_BAD_FORMAT;
}
ECHO_DEBUGPRINTF( ( "CMona::QueryAudioSampleRate()\n" ) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CMona::QueryAudioSampleRate
//===========================================================================
//
// GetInputClockDetect returns a bitmask consisting of all the input
// clocks currently connected to the hardware; this changes as the user
// connects and disconnects clock inputs.
//
// You should use this information to determine which clocks the user is
// allowed to select.
//
// Mona supports S/PDIF, word, and ADAT input clocks.
//
//===========================================================================
ECHOSTATUS CMona::GetInputClockDetect(DWORD &dwClockDetectBits)
{
//ECHO_DEBUGPRINTF(("CMona::GetInputClockDetect\n"));
if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
{
ECHO_DEBUGPRINTF( ("CMona::GetInputClockDetect: DSP Dead!\n") );
return ECHOSTATUS_DSP_DEAD;
}
//
// Map the DSP clock detect bits to the generic driver clock detect bits
//
DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF))
dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT))
dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT;
if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_WORD))
dwClockDetectBits |= ECHO_CLOCK_BIT_WORD;
return ECHOSTATUS_OK;
} // GetInputClockDetect
// *** CMona.cpp ***

View File

@ -0,0 +1,117 @@
// ****************************************************************************
//
// CMona.H
//
// Include file for interfacing with the CMona generic driver class
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _MONAOBJECT_
#define _MONAOBJECT_
#include "CEchoGals.h"
#include "CMonaDspCommObject.h"
//
// Class used for interfacing with the Darla audio card.
//
class CMona : public CEchoGals
{
public:
//
// Construction/destruction
//
CMona( PCOsSupport pOsSupport );
virtual ~CMona();
//
// Setup & initialization methods
//
virtual ECHOSTATUS InitHw();
//
// Adapter information methods
//
//
// Return the capabilities of this card; card type, card name,
// # analog inputs, # analog outputs, # digital channels,
// # MIDI ports and supported clocks.
// See ECHOGALS_CAPS definition above.
//
virtual ECHOSTATUS GetCapabilities
(
PECHOGALS_CAPS pCapabilities
);
//
// Audio Interface methods
//
virtual ECHOSTATUS QueryAudioSampleRate
(
DWORD dwSampleRate
);
//
// Get a bitmask of all the clocks the hardware is currently detecting
//
virtual ECHOSTATUS GetInputClockDetect(DWORD &dwClockDetectBits);
//
// Overload new & delete so memory for this object is allocated from
// non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
protected:
//
// Get access to the appropriate DSP comm object
//
PCMonaDspCommObject GetDspCommObject()
{ return( (PCMonaDspCommObject) m_pDspCommObject ); }
}; // class CMona
typedef CMona * PCMona;
#endif
// *** CMona.H ***

View File

@ -0,0 +1,626 @@
// ****************************************************************************
//
// CMonaDspCommObject.cpp
//
// Implementation file for EchoGals generic driver Darla 24 DSP
// interface class.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CMonaDspCommObject.h"
#include "MonaDSP.c"
#include "Mona361DSP.c"
#include "Mona1ASIC48.c"
#include "Mona1ASIC96.c"
#include "Mona1ASIC48_361.c"
#include "Mona1ASIC96_361.c"
#include "Mona2ASIC.c"
/****************************************************************************
Construction and destruction
****************************************************************************/
//===========================================================================
//
// Constructor
//
//===========================================================================
CMonaDspCommObject::CMonaDspCommObject
(
PDWORD pdwRegBase, // Virtual ptr to DSP registers
PCOsSupport pOsSupport
) : CGMLDspCommObject( pdwRegBase, pOsSupport )
{
strcpy( m_szCardName, "Mona" );
m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base
m_wNumPipesOut = 14;
m_wNumPipesIn = 12;
m_wNumBussesOut = 14;
m_wNumBussesIn = 12;
m_wFirstDigitalBusOut = 6;
m_wFirstDigitalBusIn = 4;
m_bProfessionalSpdif = FALSE;
m_fHasVmixer = FALSE;
m_wNumMidiOut = 0; // # MIDI out channels
m_wNumMidiIn = 0; // # MIDI in channels
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 44100 );
// Need this in cse we start with ESYNC
m_bHasASIC = TRUE;
if ( DEVICE_ID_56361 == pOsSupport->GetDeviceId() )
m_pwDspCodeToLoad = pwMona361DSP;
else
m_pwDspCodeToLoad = pwMonaDSP;
m_byDigitalMode = DIGITAL_MODE_SPDIF_RCA;
} // CMonaDspCommObject::CMonaDspCommObject( DWORD dwPhysRegBase )
//===========================================================================
//
// Destructor
//
//===========================================================================
CMonaDspCommObject::~CMonaDspCommObject()
{
} // CMonaDspCommObject::~CMonaDspCommObject()
/****************************************************************************
Hardware setup and config
****************************************************************************/
//===========================================================================
//
// Mona has an ASIC on the PCI card and another ASIC in the external box;
// both need to be loaded.
//
//===========================================================================
BOOL CMonaDspCommObject::LoadASIC()
{
DWORD dwControlReg;
PBYTE pbAsic1;
DWORD dwSize;
if ( m_bASICLoaded )
return TRUE;
m_pOsSupport->OsSnooze( 10000 );
if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() )
{
pbAsic1 = pbMona1ASIC48_361;
dwSize = sizeof( pbMona1ASIC48_361 );
}
else
{
pbAsic1 = pbMona1ASIC48;
dwSize = sizeof( pbMona1ASIC48 );
}
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
pbAsic1,
dwSize ) )
return FALSE;
m_pbyAsic = pbAsic1;
m_pOsSupport->OsSnooze( 10000 );
// Do the external one
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_MONA_EXTERNAL_ASIC,
pbMona2ASIC,
sizeof( pbMona2ASIC ) ) )
return FALSE;
m_pOsSupport->OsSnooze( 10000 );
CheckAsicStatus();
//
// Set up the control register if the load succeeded -
//
// 48 kHz, internal clock, S/PDIF RCA mode
//
if ( m_bASICLoaded )
{
dwControlReg = GML_CONVERTER_ENABLE | GML_48KHZ;
WriteControlReg( dwControlReg );
}
return m_bASICLoaded;
} // BOOL CMonaDspCommObject::LoadASIC()
//===========================================================================
//
// Depending on what digital mode you want, Mona needs different ASICs
// loaded. This function checks the ASIC needed for the new mode and sees
// if it matches the one already loaded.
//
//===========================================================================
BOOL CMonaDspCommObject::SwitchAsic( DWORD dwMask96 )
{
BYTE * pbyAsicNeeded;
DWORD dwAsicSize;
//
// Check the clock detect bits to see if this is
// a single-speed clock or a double-speed clock; load
// a new ASIC if necessary.
//
if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() )
{
pbyAsicNeeded = pbMona1ASIC48_361;
dwAsicSize = sizeof( pbMona1ASIC48_361 );
if ( 0 != ( dwMask96 & GetInputClockDetect() ) )
{
pbyAsicNeeded = pbMona1ASIC96_361;
dwAsicSize = sizeof( pbMona1ASIC96_361 );
}
}
else
{
pbyAsicNeeded = pbMona1ASIC48;
dwAsicSize = sizeof( pbMona1ASIC48 );
if ( 0 != ( dwMask96 & GetInputClockDetect() ) )
{
pbyAsicNeeded = pbMona1ASIC96;
dwAsicSize = sizeof( pbMona1ASIC96 );
}
}
if ( pbyAsicNeeded != m_pbyAsic )
{
//
// Load the desired ASIC
//
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
pbyAsicNeeded,
dwAsicSize ) )
return FALSE;
m_pbyAsic = pbyAsicNeeded;
}
return TRUE;
} // BOOL CMonaDspCommObject::SwitchAsic( DWORD dwMask96 )
//===========================================================================
//
// SetInputClock
//
//===========================================================================
ECHOSTATUS CMonaDspCommObject::SetInputClock(WORD wClock)
{
BOOL bSetRate;
BOOL bWriteControlReg;
DWORD dwControlReg, dwSampleRate;
ECHO_DEBUGPRINTF( ("CMonaDspCommObject::SetInputClock:\n") );
dwControlReg = GetControlRegister();
//
// Mask off the clock select bits
//
dwControlReg &= GML_CLOCK_CLEAR_MASK;
dwSampleRate = GetSampleRate();
bSetRate = FALSE;
bWriteControlReg = TRUE;
switch ( wClock )
{
case ECHO_CLOCK_INTERNAL :
{
ECHO_DEBUGPRINTF( ( "\tSet Mona clock to INTERNAL\n" ) );
// If the sample rate is out of range for some reason, set it
// to a reasonable value. mattg
if ( ( dwSampleRate < 8000 ) ||
( dwSampleRate > 96000 ) )
{
dwSampleRate = 48000;
}
bSetRate = TRUE;
bWriteControlReg = FALSE;
break;
} // CLK_CLOCKININTERNAL
case ECHO_CLOCK_SPDIF :
{
if ( DIGITAL_MODE_ADAT == GetDigitalMode() )
{
return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
}
if ( FALSE == SwitchAsic( GML_CLOCK_DETECT_BIT_SPDIF96 ) )
{
return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
}
ECHO_DEBUGPRINTF( ( "\tSet Mona clock to SPDIF\n" ) );
dwControlReg |= GML_SPDIF_CLOCK;
if ( GML_CLOCK_DETECT_BIT_SPDIF96 & GetInputClockDetect() )
{
dwControlReg |= GML_DOUBLE_SPEED_MODE;
}
else
{
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
}
break;
} // CLK_CLOCKINSPDIF
case ECHO_CLOCK_WORD :
{
ECHO_DEBUGPRINTF( ( "\tSet Mona clock to WORD\n" ) );
if ( FALSE == SwitchAsic( GML_CLOCK_DETECT_BIT_WORD96 ) )
{
return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
}
dwControlReg |= GML_WORD_CLOCK;
if ( GML_CLOCK_DETECT_BIT_WORD96 & GetInputClockDetect() )
{
dwControlReg |= GML_DOUBLE_SPEED_MODE;
}
else
{
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
}
break;
} // CLK_CLOCKINWORD
case ECHO_CLOCK_ADAT :
{
ECHO_DEBUGPRINTF( ( "\tSet Mona clock to ADAT\n" ) );
if ( DIGITAL_MODE_ADAT != GetDigitalMode() )
{
return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
}
dwControlReg |= GML_ADAT_CLOCK;
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
break;
} // CLK_CLOCKINADAT
default :
ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for Mona\n",wClock));
ECHO_DEBUGBREAK();
return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
} // switch (wClock)
//
// Winner! Save the new input clock.
//
m_wInputClock = wClock;
//
// Do things according to the flags
//
if ( bWriteControlReg )
{
WriteControlReg( dwControlReg );
}
// Set Mona sample rate to something sane if word or superword is
// being turned off
if ( bSetRate )
{
SetSampleRate( GetSampleRate() );
}
return ECHOSTATUS_OK;
} // ECHOSTATUS CMonaDspCommObject::SetInputClock
//===========================================================================
//
// SetSampleRate
//
// Set the audio sample rate for CMona
//
//===========================================================================
DWORD CMonaDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
{
BYTE *pbyAsicNeeded;
DWORD dwAsicSize, dwControlReg, dwNewClock;
//
// Only set the clock for internal mode. If the clock is not set to
// internal, try and re-set the input clock; this more transparently
// handles switching between single and double-speed mode
//
if ( GetInputClock() != ECHO_CLOCK_INTERNAL )
{
ECHO_DEBUGPRINTF( ( "CMonaDspCommObject::SetSampleRate: Cannot set sample rate - "
"clock not set to CLK_CLOCKININTERNAL\n" ) );
//
// Save the rate anyhow
//
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
//
// Set the input clock to the current value
//
SetInputClock( m_wInputClock );
return GetSampleRate();
}
//
// Now, check to see if the required ASIC is loaded
//
if ( dwNewSampleRate >= 88200 )
{
if ( DIGITAL_MODE_ADAT == GetDigitalMode() )
return( GetSampleRate() );
if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() )
{
pbyAsicNeeded = pbMona1ASIC96_361;
dwAsicSize = sizeof(pbMona1ASIC96_361);
}
else
{
pbyAsicNeeded = pbMona1ASIC96;
dwAsicSize = sizeof(pbMona1ASIC96);
}
}
else
{
if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() )
{
pbyAsicNeeded = pbMona1ASIC48_361;
dwAsicSize = sizeof(pbMona1ASIC48_361);
}
else
{
pbyAsicNeeded = pbMona1ASIC48;
dwAsicSize = sizeof(pbMona1ASIC48);
}
}
if ( pbyAsicNeeded != m_pbyAsic )
{
//
// Load the desired ASIC
//
if ( FALSE == CDspCommObject::LoadASIC
( DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
pbyAsicNeeded,
dwAsicSize ) )
return( GetSampleRate() );
m_pbyAsic = pbyAsicNeeded;
}
//
// Get the new control register value
//
dwNewClock = 0;
dwControlReg = GetControlRegister();
dwControlReg &= GML_CLOCK_CLEAR_MASK;
dwControlReg &= GML_SPDIF_RATE_CLEAR_MASK;
switch ( dwNewSampleRate )
{
case 96000 :
dwNewClock = GML_96KHZ;
break;
case 88200 :
dwNewClock = GML_88KHZ;
break;
case 48000 :
dwNewClock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
break;
case 44100 :
dwNewClock = GML_44KHZ;
//
// Professional mode
//
if ( dwControlReg & GML_SPDIF_PRO_MODE )
{
dwNewClock |= GML_SPDIF_SAMPLE_RATE0;
}
break;
case 32000 :
dwNewClock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | GML_SPDIF_SAMPLE_RATE1;
break;
case 22050 :
dwNewClock = GML_22KHZ;
break;
case 16000 :
dwNewClock = GML_16KHZ;
break;
case 11025 :
dwNewClock = GML_11KHZ;
break;
case 8000 :
dwNewClock = GML_8KHZ;
break;
}
dwControlReg |= dwNewClock;
//
// Send the new value to the card
//
if ( ECHOSTATUS_OK == WriteControlReg( dwControlReg ) )
{
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
ECHO_DEBUGPRINTF( ("CMonaDspCommObject::SetSampleRate: %ld "
"clock %ld\n", dwNewSampleRate, dwNewClock) );
}
return GetSampleRate();
} // DWORD CMonaDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
//===========================================================================
//
// Set digital mode
//
//===========================================================================
ECHOSTATUS CMonaDspCommObject::SetDigitalMode
(
BYTE byNewMode
)
{
DWORD dwControlReg;
dwControlReg = GetControlRegister();
//
// Clear the current digital mode
//
dwControlReg &= GML_DIGITAL_MODE_CLEAR_MASK;
//
// Tweak the control reg
//
switch ( byNewMode )
{
default :
return ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED;
case DIGITAL_MODE_SPDIF_OPTICAL :
dwControlReg |= GML_SPDIF_OPTICAL_MODE;
// fall through
case DIGITAL_MODE_SPDIF_RCA :
//
// If the input clock is set to ADAT, set the
// input clock to internal and the sample rate to 48 KHz
//
if ( ECHO_CLOCK_ADAT == GetInputClock() )
{
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 );
SetInputClock( ECHO_CLOCK_INTERNAL );
}
break;
case DIGITAL_MODE_ADAT :
//
// If the input clock is set to S/PDIF, set the
// input clock to internal and the sample rate to 48 KHz
//
if ( ECHO_CLOCK_SPDIF == GetInputClock() )
{
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 );
SetInputClock( ECHO_CLOCK_INTERNAL );
}
//
// If the current ASIC is the 96KHz ASIC, switch
// the ASIC and set to 48 KHz
//
if ( ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() &&
pbMona1ASIC96_361 == m_pbyAsic ) ||
( DEVICE_ID_56301 == m_pOsSupport->GetDeviceId() &&
pbMona1ASIC96 == m_pbyAsic ) )
{
SetSampleRate( 48000 );
}
dwControlReg |= GML_ADAT_MODE;
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
break;
}
//
// Write the control reg
//
WriteControlReg( dwControlReg );
m_byDigitalMode = byNewMode;
ECHO_DEBUGPRINTF( ("CMonaDspCommObject::SetDigitalMode to %ld\n",
(DWORD) m_byDigitalMode) );
return ECHOSTATUS_OK;
} // ECHOSTATUS CMonaDspCommObject::SetDigitalMode
// **** CMonaDspCommObject.cpp ****

View File

@ -0,0 +1,106 @@
// ****************************************************************************
//
// CMonaDspCommObject.H
//
// Include file for EchoGals generic driver Mona DSP interface class.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _MONADSPCOMMOBJECT_
#define _MONADSPCOMMOBJECT_
#include "CGMLDspCommObject.h"
class CMonaDspCommObject : public CGMLDspCommObject
{
public:
//
// Construction/destruction
//
CMonaDspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport );
virtual ~CMonaDspCommObject();
//
// Set the DSP sample rate.
// Return rate that was set, -1 if error
//
virtual DWORD SetSampleRate( DWORD dwNewSampleRate );
//
// Send current setting to DSP & return what it is
//
virtual DWORD SetSampleRate()
{ return( SetSampleRate( GetSampleRate() ) ); }
//
// Set digital mode
//
virtual ECHOSTATUS SetDigitalMode
(
BYTE byNewMode
);
//
// Get mask of all supported digital modes
// (See ECHOCAPS_HAS_DIGITAL_MODE_??? defines in EchoGalsXface.h)
//
virtual DWORD GetDigitalModes()
{ return( ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
ECHOCAPS_HAS_DIGITAL_MODE_ADAT ); }
//
// Card information
//
virtual WORD GetCardType()
{ return( MONA ); }
protected:
virtual BOOL LoadASIC();
BOOL SwitchAsic( DWORD dwMask96 );
//
// Set input clock
//
virtual ECHOSTATUS SetInputClock(WORD wClock);
BYTE * m_pbyAsic; // Current ASIC code
}; // class CMonaDspCommObject
typedef CMonaDspCommObject * PCMonaDspCommObject;
#endif
// **** MonaDspCommObject.h ****

View File

@ -0,0 +1,448 @@
// ****************************************************************************
//
// CMonitorCtrl.cpp
//
// Class to control monitors
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CMonitorCtrl.h"
//*****************************************************************************
//
// Init
//
//*****************************************************************************
ECHOSTATUS CMonitorCtrl::Init(CEchoGals *pEG)
{
DWORD dwBytes;
DWORD dwArraySize;
m_Gains = NULL;
m_Mutes = NULL;
m_Pans = NULL;
m_PanDbs = NULL;
//
// Cache stuff
//
m_pEG = pEG;
m_wNumBussesIn = pEG->GetNumBussesIn();
m_wNumBussesOut = pEG->GetNumBussesOut();
//
// Indigo has no inputs; attempting to allocate 0 bytes
// causes a BSOD on Windows ME.
//
if ((0 == m_wNumBussesIn) || (0 == m_wNumBussesOut))
{
ECHO_DEBUGPRINTF(("CMonitorCtrl::Init - this card has no inputs!\n"));
return ECHOSTATUS_OK;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Allocate the arrays
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dwArraySize = m_wNumBussesIn * (m_wNumBussesOut >> 1);
dwBytes = sizeof(INT8) * dwArraySize;
OsAllocateNonPaged(dwBytes,(void **) &m_Gains);
if (NULL == m_Gains)
{
Cleanup();
return ECHOSTATUS_NO_MEM;
}
dwBytes = sizeof(WORD) * dwArraySize;
OsAllocateNonPaged(dwBytes,(void **) &m_Pans);
if (NULL == m_Pans)
{
Cleanup();
return ECHOSTATUS_NO_MEM;
}
dwBytes = sizeof(BYTE) * dwArraySize;
OsAllocateNonPaged(dwBytes,(void **) &m_Mutes);
if (NULL == m_Mutes)
{
Cleanup();
return ECHOSTATUS_NO_MEM;
}
dwBytes = sizeof(PAN_DB) * dwArraySize;
OsAllocateNonPaged(dwBytes,(void **) &m_PanDbs );
if (NULL == m_PanDbs)
{
Cleanup();
return ECHOSTATUS_NO_MEM;
}
//==============================================================
//
// Init the arrays
//
//==============================================================
WORD wBusIn,wBusOut,wIndex;
for (wBusIn = 0; wBusIn < m_wNumBussesIn; wBusIn++)
for (wBusOut = 0; wBusOut < m_wNumBussesOut; wBusOut += 2)
{
wIndex = GetIndex(wBusIn,wBusOut);
//
// Pan hard left for even inputs, hard right for odd
//
if (0 == (wBusIn & 1))
{
m_Pans[wIndex] = 0;
m_PanDbs[wIndex].iLeft = 0;
m_PanDbs[wIndex].iRight = GENERIC_TO_DSP( ECHOGAIN_MUTED );
}
else
{
m_Pans[wIndex] = MAX_MIXER_PAN;
m_PanDbs[wIndex].iLeft = GENERIC_TO_DSP( ECHOGAIN_MUTED );
m_PanDbs[wIndex].iRight = 0;
}
//
// Mute unless this is not a digital input
// and the input is going to the same-numbered output
//
if ( (wBusIn < m_pEG->GetFirstDigitalBusIn()) &&
( (wBusIn & 0xfffe) == wBusOut ) )
{
m_Mutes[wIndex] = FALSE;
}
else
{
m_Mutes[wIndex] = TRUE;
}
//
// Put stuff in the comm page
//
SetGain(wBusIn,wBusOut,ECHOGAIN_UPDATE,FALSE);
}
//
// Now actually update the DSP
//
m_pEG->GetDspCommObject()->UpdateAudioOutLineLevel();
return ECHOSTATUS_OK;
} // Init
//*****************************************************************************
//
// Cleanup - free allocated memory
//
//*****************************************************************************
void CMonitorCtrl::Cleanup()
{
if (m_Gains)
OsFreeNonPaged(m_Gains);
if (m_Mutes)
OsFreeNonPaged(m_Mutes);
if (m_Pans)
OsFreeNonPaged(m_Pans);
if (m_PanDbs)
OsFreeNonPaged(m_PanDbs);
} // Cleanup
//*****************************************************************************
//
// Set and get gain
//
//*****************************************************************************
ECHOSTATUS CMonitorCtrl::SetGain
(
WORD wBusIn,
WORD wBusOut,
INT32 iGain,
BOOL fImmediate
)
{
ECHOSTATUS Status;
if (NULL == m_pEG)
return ECHOSTATUS_DSP_DEAD;
if ( (NULL == m_Gains) ||
(NULL == m_PanDbs) )
return ECHOSTATUS_NO_MEM;
WORD wIndex = GetIndex(wBusIn,wBusOut);
if (ECHOGAIN_UPDATE == iGain)
{
iGain = DSP_TO_GENERIC( m_Gains[ wIndex ] );
}
else
{
if (iGain > ECHOGAIN_MAXOUT)
iGain = ECHOGAIN_MAXOUT;
else if (iGain < ECHOGAIN_MUTED)
iGain = ECHOGAIN_MUTED;
m_Gains[ wIndex ] = GENERIC_TO_DSP( iGain );
//
// Gain has changed; store the notify
//
m_pEG->MixerControlChanged(ECHO_MONITOR,MXN_LEVEL,wBusIn,wBusOut);
}
//
// Use the gain that was passed in, the pan setting,
// and the mute to calculate the left and right gains
//
INT32 iLeft = iGain + DSP_TO_GENERIC( m_PanDbs[wIndex].iLeft );
INT32 iRight = iGain + DSP_TO_GENERIC( m_PanDbs[wIndex].iRight );
//
// Adjust left and right by the output bus gain
//
iLeft += m_pEG->m_BusOutLineLevels[wBusOut].GetGain();
iRight += m_pEG->m_BusOutLineLevels[wBusOut + 1].GetGain();
//
// Either mute or clamp
//
if (TRUE == m_Mutes[wIndex])
{
iLeft = ECHOGAIN_MUTED;
iRight = ECHOGAIN_MUTED;
}
else
{
if ( m_pEG->m_BusOutLineLevels[wBusOut].IsMuteOn() )
{
iLeft = ECHOGAIN_MUTED;
}
else
{
//
// Clamp left
//
if (iLeft > ECHOGAIN_MAXOUT)
iLeft = ECHOGAIN_MAXOUT;
else if (iLeft < ECHOGAIN_MUTED)
iLeft = ECHOGAIN_MUTED;
}
if ( m_pEG->m_BusOutLineLevels[wBusOut + 1].IsMuteOn() )
{
iRight = ECHOGAIN_MUTED;
}
else
{
//
// Clamp right
//
if (iRight > ECHOGAIN_MAXOUT)
iRight = ECHOGAIN_MAXOUT;
else if (iRight < ECHOGAIN_MUTED)
iRight = ECHOGAIN_MUTED;
}
}
//
// Set the left channel
//
if ( (NULL == m_pEG) ||
(NULL == m_pEG->GetDspCommObject() ) )
return ECHOSTATUS_DSP_DEAD;
Status = m_pEG->
GetDspCommObject()->
SetAudioMonitor( wBusOut,
wBusIn,
iLeft,
FALSE);
//
// Set the right channel
//
if (ECHOSTATUS_OK == Status)
{
Status = m_pEG->
GetDspCommObject()->
SetAudioMonitor( wBusOut + 1,
wBusIn,
iRight,
fImmediate);
}
return Status;
}
ECHOSTATUS CMonitorCtrl::GetGain(WORD wBusIn, WORD wBusOut, INT32 &iGain)
{
WORD wIndex = GetIndex(wBusIn,wBusOut);
if (NULL == m_Gains)
return ECHOSTATUS_NO_MEM;
iGain = DSP_TO_GENERIC( m_Gains[wIndex] );
return ECHOSTATUS_OK;
}
//*****************************************************************************
//
// Set and get mute
//
//*****************************************************************************
ECHOSTATUS CMonitorCtrl::SetMute
(
WORD wBusIn,
WORD wBusOut,
BOOL bMute,
BOOL fImmediate
)
{
if (NULL == m_Mutes)
return ECHOSTATUS_NO_MEM;
WORD wIndex = GetIndex(wBusIn,wBusOut);
//
// Store the mute
//
m_Mutes[ wIndex ] = (BYTE) bMute;
//
// Store the notify
//
m_pEG->MixerControlChanged(ECHO_MONITOR,MXN_MUTE,wBusIn,wBusOut);
//
// Call the SetGain function to do all the heavy lifting
// Use the ECHOGAIN_UPDATE value to tell the function to
// recalculate the gain setting using the currently stored value.
//
return SetGain(wBusIn,wBusOut,ECHOGAIN_UPDATE,fImmediate);
}
ECHOSTATUS CMonitorCtrl::GetMute(WORD wBusIn, WORD wBusOut, BOOL &bMute)
{
WORD wIndex = GetIndex(wBusIn,wBusOut);
if (NULL == m_Mutes)
return ECHOSTATUS_NO_MEM;
bMute = (BOOL) m_Mutes[ wIndex ];
return ECHOSTATUS_OK;
}
//*****************************************************************************
//
// Set and get pan
//
//*****************************************************************************
ECHOSTATUS CMonitorCtrl::SetPan(WORD wBusIn, WORD wBusOut, INT32 iPan)
{
WORD wIndex = GetIndex(wBusIn,wBusOut);
if (NULL == m_Pans)
return ECHOSTATUS_NO_MEM;
//
// Clamp it and stash it
//
if (iPan < 0)
iPan = 0;
else if (iPan > MAX_MIXER_PAN)
iPan = MAX_MIXER_PAN;
m_Pans[wIndex] = (WORD) iPan;
//
// Convert this pan setting INTo left and right dB values
//
m_PanDbs[wIndex].iLeft = GENERIC_TO_DSP( PanToDb(MAX_MIXER_PAN - iPan) );
m_PanDbs[wIndex].iRight = GENERIC_TO_DSP( PanToDb(iPan) );
//
// Store the notify
//
m_pEG->MixerControlChanged(ECHO_MONITOR,MXN_PAN,wBusIn,wBusOut);
//
// Once again SetGain does all the hard work
//
return SetGain(wBusIn,wBusOut,ECHOGAIN_UPDATE);
}
ECHOSTATUS CMonitorCtrl::GetPan(WORD wBusIn, WORD wBusOut, INT32 &iPan)
{
WORD wIndex = GetIndex(wBusIn,wBusOut);
if (NULL == m_Pans)
return ECHOSTATUS_NO_MEM;
iPan = m_Pans[ wIndex ];
return ECHOSTATUS_OK;
}

View File

@ -0,0 +1,105 @@
// ****************************************************************************
//
// CMonitorCtrl.h
//
// Class to control input monitors on cards with or without vmixers.
// Input monitors are used to route audio data from input busses to
// output busses through the DSP with very low latency.
//
// Any input bus may be routed to any output bus.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _CMonitorCtrl_H_
#define _CMonitorCtrl_H_
class CEchoGals;
class CMonitorCtrl
{
protected:
typedef struct
{
INT8 iLeft;
INT8 iRight;
} PAN_DB;
CEchoGals *m_pEG;
WORD m_wNumBussesIn;
WORD m_wNumBussesOut;
INT8 *m_Gains;
BYTE *m_Mutes;
WORD *m_Pans;
PAN_DB *m_PanDbs;
WORD GetIndex(WORD wBusIn,WORD wBusOut)
{
return (wBusOut >> 1) * m_wNumBussesIn + wBusIn;
}
public:
ECHOSTATUS Init(CEchoGals *m_pEG);
void Cleanup();
ECHOSTATUS SetGain
(
WORD wBusIn,
WORD wBusOut,
INT32 iGain,
BOOL fImmediate = TRUE
);
ECHOSTATUS GetGain(WORD wBusIn, WORD wBusOut, INT32 &iGain);
ECHOSTATUS SetMute
(
WORD wBusIn,
WORD wBusOut,
BOOL bMute,
BOOL fImmediate = TRUE
);
ECHOSTATUS GetMute(WORD wBusIn, WORD wBusOut, BOOL &bMute);
ECHOSTATUS SetPan(WORD wBusIn, WORD wBusOut, INT32 iPan);
ECHOSTATUS GetPan(WORD wBusIn, WORD wBusOut, INT32 &iPan);
};
#endif // _CMonitorCtrl_H_

View File

@ -0,0 +1,507 @@
// ****************************************************************************
//
// CPipeOutCtrl.cpp
//
// Class to control output pipes on cards with or without vmixers.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include "CPipeOutCtrl.h"
extern INT32 PanToDb( INT32 iPan );
//*****************************************************************************
//
// Init
//
//*****************************************************************************
ECHOSTATUS CPipeOutCtrl::Init(CEchoGals *pEG)
{
DWORD dwBytes;
WORD wPipe,wStereoBus;
m_Gains = NULL;
m_Mutes = NULL;
m_Pans = NULL;
m_PanDbs = NULL;
//
// Cache stuff
//
m_pEG = pEG;
m_wNumPipesOut = pEG->GetNumPipesOut();
m_wNumBussesOut = pEG->GetNumBussesOut();
m_fHasVmixer = pEG->HasVmixer();
//
// Allocate the arrays
//
if (m_fHasVmixer)
{
WORD wNumStereoBusses = m_wNumBussesOut >> 1;
//
// Allocate arrays for vmixer support
//
dwBytes = sizeof(INT8) * m_wNumPipesOut * wNumStereoBusses;
OsAllocateNonPaged(dwBytes,(void **) &m_Gains);
if (NULL == m_Gains)
{
return ECHOSTATUS_NO_MEM;
}
dwBytes = sizeof(BYTE) * m_wNumPipesOut * wNumStereoBusses;
OsAllocateNonPaged(dwBytes,(void **) &m_Mutes);
if (NULL == m_Mutes)
{
Cleanup();
return ECHOSTATUS_NO_MEM;
}
dwBytes = sizeof(WORD) * m_wNumPipesOut * wNumStereoBusses;
OsAllocateNonPaged(dwBytes,(void **) &m_Pans);
if (NULL == m_Pans)
{
Cleanup();
return ECHOSTATUS_NO_MEM;
}
dwBytes = sizeof(PAN_DB) * m_wNumPipesOut * wNumStereoBusses;
OsAllocateNonPaged(dwBytes,(void **) &m_PanDbs);
if (NULL == m_PanDbs)
{
Cleanup();
return ECHOSTATUS_NO_MEM;
}
//
// Initialize pans and mutes
//
for (wPipe = 0; wPipe < m_wNumPipesOut; wPipe++)
for (wStereoBus = 0; wStereoBus < wNumStereoBusses; wStereoBus++)
{
WORD wIndex;
wIndex = GetIndex(wPipe,wStereoBus << 1);
//
// Pans
//
if (0 == (wPipe & 1))
{
//
// Even channel - pan hard left
//
m_Pans[wIndex] = 0;
m_PanDbs[wIndex].iLeft = 0;
m_PanDbs[wIndex].iRight = GENERIC_TO_DSP( ECHOGAIN_MUTED );
}
else
{
//
// Odd channel - pan hard right
//
m_Pans[wIndex] = MAX_MIXER_PAN;
m_PanDbs[wIndex].iLeft = GENERIC_TO_DSP( ECHOGAIN_MUTED );
m_PanDbs[wIndex].iRight = 0;
}
//
// Mutes
//
if ((wPipe >> 1) == wStereoBus)
{
m_Mutes[wIndex] = FALSE;
}
else
{
m_Mutes[wIndex] = TRUE;
}
//
// Set the gain to the DSP; use fImmedate = FALSE here
// to make this faster
//
SetGain(wPipe,wStereoBus << 1,ECHOGAIN_UPDATE,FALSE);
}
//
// Set the gain one more time with the immediate flag set to
// make sure the DSP gets the message
//
SetGain(0,0,ECHOGAIN_UPDATE,TRUE);
}
else
{
//
// Allocate arrays for no vmixer support - don't need pans
//
dwBytes = sizeof(INT8) * m_wNumPipesOut;
OsAllocateNonPaged(dwBytes,(void **) &m_Gains);
if (NULL == m_Gains)
{
return ECHOSTATUS_NO_MEM;
}
dwBytes = sizeof(BYTE) * m_wNumPipesOut;
OsAllocateNonPaged(dwBytes,(void **) &m_Mutes);
if (NULL == m_Mutes)
{
OsFreeNonPaged(m_Gains);
return ECHOSTATUS_NO_MEM;
}
}
return ECHOSTATUS_OK;
} // Init
//*****************************************************************************
//
// Cleanup - free allocated memory
//
//*****************************************************************************
void CPipeOutCtrl::Cleanup()
{
if (m_Gains)
OsFreeNonPaged(m_Gains);
if (m_Mutes)
OsFreeNonPaged(m_Mutes);
if (m_Pans)
OsFreeNonPaged(m_Pans);
if (m_PanDbs)
OsFreeNonPaged(m_PanDbs);
} // Cleanup
//*****************************************************************************
//
// Set and get gain
//
// For cards without vmixers, output bus gain is not handled by the DSP.
// Instead, the driver adjusts the output pipe volumes by the output bus gain
// and sends that value to the DSP.
//
// For cards with vmixers, the output bus gain is handled by the DSP, so
// the gain setting does not need to take into account the output bus gain
// stored by the driver.
//
//*****************************************************************************
ECHOSTATUS CPipeOutCtrl::SetGain
(
WORD wPipeOut,
WORD wBusOut,
INT32 iGain,
BOOL fImmediate
)
{
ECHOSTATUS Status;
if ( NULL == m_pEG)
return ECHOSTATUS_DSP_DEAD;
if (!m_fHasVmixer && (wPipeOut != wBusOut))
return ECHOSTATUS_OK;
if ((NULL == m_Gains) || (NULL == m_Mutes))
return ECHOSTATUS_NO_MEM;
WORD wIndex = GetIndex(wPipeOut,wBusOut);
/*
ECHO_DEBUGPRINTF(("CPipeOutCtrl::SetGain pipe %d bus %d gain 0x%lx index %d\n",
wPipeOut,wBusOut,iGain,wIndex));
*/
if (ECHOGAIN_UPDATE == iGain)
{
iGain = DSP_TO_GENERIC( m_Gains[ wIndex ] );
}
else
{
if (iGain > ECHOGAIN_MAXOUT)
iGain = ECHOGAIN_MAXOUT;
else if (iGain < ECHOGAIN_MUTED)
iGain = ECHOGAIN_MUTED;
m_Gains[ wIndex ] = GENERIC_TO_DSP( iGain );
//
// Store the notify
//
m_pEG->MixerControlChanged(ECHO_PIPE_OUT,MXN_LEVEL,wPipeOut,wBusOut);
}
if (m_fHasVmixer)
{
wBusOut &= 0xfffe;
if (NULL == m_Pans)
return ECHOSTATUS_NO_MEM;
//
// For vmixer cards, the DSP handles the output bus gain,
// so no need to account for it here. Vmixer output pipes
// do have to handle panning.
//
int iLeft = iGain + DSP_TO_GENERIC( m_PanDbs[wIndex].iLeft );
int iRight = iGain + DSP_TO_GENERIC( m_PanDbs[wIndex].iRight );
if (m_Mutes[wIndex])
{
iLeft = ECHOGAIN_MUTED;
iRight = ECHOGAIN_MUTED;
}
else
{
if (iLeft < ECHOGAIN_MUTED)
iLeft = ECHOGAIN_MUTED;
else if (iLeft > ECHOGAIN_MAXOUT)
iLeft = ECHOGAIN_MAXOUT;
if (iRight < ECHOGAIN_MUTED)
iRight = ECHOGAIN_MUTED;
else if (iRight > ECHOGAIN_MAXOUT)
iRight = ECHOGAIN_MAXOUT;
}
//
// Set the left channel gain
//
Status = m_pEG->GetDspCommObject()->SetPipeOutGain(wPipeOut,
wBusOut,
iLeft,
FALSE);
if (ECHOSTATUS_OK == Status)
{
Status = m_pEG->GetDspCommObject()->SetPipeOutGain(wPipeOut,
wBusOut + 1,
iRight,
fImmediate);
}
}
else
{
int iBusOutGain;
//
// Add this output pipe gain to the output bus gain
// Since these gains are in decibels, it's OK to just add them
//
iBusOutGain = m_pEG->m_BusOutLineLevels[wBusOut].GetGain();
iGain += iBusOutGain;
//
// Mute this output pipe if this output bus is muted
//
if (m_Mutes[ wIndex ] ||
(m_pEG->m_BusOutLineLevels[wBusOut].IsMuteOn()) )
{
iGain = ECHOGAIN_MUTED;
}
else
{
//
// Clamp the output pipe gain if necessary
//
if (iGain < ECHOGAIN_MUTED)
iGain = ECHOGAIN_MUTED;
else if (iGain > ECHOGAIN_MAXOUT)
iGain = ECHOGAIN_MAXOUT;
}
//
// Set the gain
//
Status = m_pEG->GetDspCommObject()->SetPipeOutGain(wPipeOut,
wBusOut,
iGain,
fImmediate);
}
return Status;
}
ECHOSTATUS CPipeOutCtrl::GetGain(WORD wPipeOut, WORD wBusOut, INT32 &iGain)
{
WORD wIndex = GetIndex(wPipeOut,wBusOut);
if (NULL == m_Gains)
return ECHOSTATUS_NO_MEM;
iGain = DSP_TO_GENERIC( m_Gains[wIndex] );
/*
ECHO_DEBUGPRINTF(("CPipeOutCtrl::GetGain pipe %d bus %d gain 0x%lx index %d\n",
wPipeOut,wBusOut,iGain,wIndex));
*/
return ECHOSTATUS_OK;
}
//*****************************************************************************
//
// Set and get mute
//
//*****************************************************************************
ECHOSTATUS CPipeOutCtrl::SetMute
(
WORD wPipeOut,
WORD wBusOut,
BOOL bMute,
BOOL fImmediate
)
{
if (!m_fHasVmixer && (wPipeOut != wBusOut))
return ECHOSTATUS_OK;
if (NULL == m_Mutes)
return ECHOSTATUS_NO_MEM;
WORD wIndex = GetIndex(wPipeOut,wBusOut);
/*
ECHO_DEBUGPRINTF(("CPipeOutCtrl::SetMute wPipeOut %d wBusOut %d bMute %ld\n",
wPipeOut,wBusOut,bMute));
*/
//
// Store the mute
//
m_Mutes[ wIndex ] = (BYTE) bMute;
//
// Store the notify
//
m_pEG->MixerControlChanged(ECHO_PIPE_OUT,MXN_MUTE,wPipeOut,wBusOut);
//
// Call the SetGain function to do all the heavy lifting
// Use the ECHOGAIN_UPDATE value to tell the function to
// recalculate the gain setting using the currently stored value.
//
return SetGain(wPipeOut,wBusOut,ECHOGAIN_UPDATE,fImmediate);
}
ECHOSTATUS CPipeOutCtrl::GetMute(WORD wPipeOut, WORD wBusOut, BOOL &bMute)
{
WORD wIndex = GetIndex(wPipeOut,wBusOut);
if (NULL == m_Mutes)
return ECHOSTATUS_NO_MEM;
bMute = (BOOL) m_Mutes[ wIndex ];
/*
ECHO_DEBUGPRINTF(("CPipeOutCtrl::GetMute wPipeOut %d wBusOut %d bMute %ld\n",
wPipeOut,wBusOut,bMute));
*/
return ECHOSTATUS_OK;
}
//*****************************************************************************
//
// Set and get pan (vmixer only)
//
//*****************************************************************************
ECHOSTATUS CPipeOutCtrl::SetPan(WORD wPipeOut, WORD wBusOut, INT32 iPan)
{
if (!m_fHasVmixer)
return ECHOSTATUS_OK;
if (NULL == m_Pans)
return ECHOSTATUS_NO_MEM;
WORD wIndex = GetIndex(wPipeOut,wBusOut);
//
// Clamp it and stash it
//
if (iPan < 0)
iPan = 0;
else if (iPan > MAX_MIXER_PAN)
iPan = MAX_MIXER_PAN;
m_Pans[wIndex] = (WORD) iPan;
//
// Store the notify
//
m_pEG->MixerControlChanged(ECHO_PIPE_OUT,MXN_PAN,wPipeOut,wBusOut);
//
// Convert this pan setting into left and right dB values
//
m_PanDbs[wIndex].iLeft = GENERIC_TO_DSP( PanToDb(MAX_MIXER_PAN - iPan) );
m_PanDbs[wIndex].iRight = GENERIC_TO_DSP( PanToDb(iPan) );
//
// Again, SetGain does all the hard work
//
return SetGain(wPipeOut,wBusOut,ECHOGAIN_UPDATE);
}
ECHOSTATUS CPipeOutCtrl::GetPan(WORD wPipeOut, WORD wBusOut, INT32 &iPan)
{
WORD wIndex = GetIndex(wPipeOut,wBusOut);
if (NULL == m_Pans)
return ECHOSTATUS_NO_MEM;
iPan = m_Pans[ wIndex ];
return ECHOSTATUS_OK;
}

View File

@ -0,0 +1,105 @@
// ****************************************************************************
//
// CPipeOutCtrl.h
//
// Class to control output pipes on cards with or without vmixers.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifndef _CPIPEOUTCTRL_H_
#define _CPIPEOUTCTRL_H_
class CEchoGals;
class CPipeOutCtrl
{
protected:
typedef struct
{
INT8 iLeft;
INT8 iRight;
} PAN_DB;
CEchoGals *m_pEG;
WORD m_wNumPipesOut;
WORD m_wNumBussesOut;
BOOL m_fHasVmixer;
INT8 *m_Gains;
BYTE *m_Mutes;
WORD *m_Pans;
PAN_DB *m_PanDbs;
WORD GetIndex(WORD wPipe,WORD wBus)
{
if (!m_fHasVmixer)
return wPipe;
return (wBus >> 1) * m_wNumPipesOut + wPipe;
}
public:
ECHOSTATUS Init(CEchoGals *m_pEG);
void Cleanup();
ECHOSTATUS SetGain
(
WORD wPipeOut,
WORD wBusOut,
INT32 iGain,
BOOL fImmediate = TRUE
);
ECHOSTATUS GetGain(WORD wPipeOut, WORD wBusOut, INT32 &iGain);
ECHOSTATUS SetMute
(
WORD wPipeOut,
WORD wBusOut,
BOOL bMute,
BOOL fImmediate = TRUE
);
ECHOSTATUS GetMute(WORD wPipeOut, WORD wBusOut, BOOL &bMute);
ECHOSTATUS SetPan(WORD wPipeOut, WORD wBusOut, INT32 iPan);
ECHOSTATUS GetPan(WORD wPipeOut, WORD wBusOut, INT32 &iPan);
};
#endif // _CPIPEOUTCTRL_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,908 @@
// darla24 DSP Code File (Converted by LRS2VxD)
// Copyright (c) Echo Digital Audio, 2002. All Rights Reserved.
WORD pwDarla24DSP[] =
{
0x0082, 0x0001, 0x0000, 0x0100, 0x0200, 0x614c, 0x6c79, 0x2061,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x5344, 0x3550, 0x3336, 0x3030,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2e36, 0x2e30,
0x2e30, 0x2030, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x000f, 0x0002, 0x0001, 0x0002, 0x0000, 0x0007,
0x0000, 0x0000, 0x0000, 0x0000, 0x000f, 0x0002, 0x0002, 0x0002,
0x0000, 0x0007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0021, 0x0002,
0x0001, 0x000b, 0x0000, 0x001d, 0x0000, 0x0400, 0x0000, 0x0400,
0x0000, 0x0400, 0x0000, 0x0400, 0x0000, 0x0400, 0x0000, 0x0400,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0316, 0x001b, 0x0002, 0x0002, 0x0008, 0x0000, 0x0015,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0013, 0x0002, 0x0002, 0x0004, 0x0000, 0x0021, 0x0000, 0x0000,
0x007f, 0xc4e1, 0x00d4, 0xd5e6, 0x00ab, 0x2f94, 0x0019, 0x0002,
0x0001, 0x0007, 0x0000, 0x003c, 0x0000, 0x0003, 0x0000, 0x0000,
0x0000, 0x0000, 0x00fe, 0x0000, 0x00a6, 0x5bc0, 0x0078, 0x0000,
0x0008, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0047,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0048,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0049,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x004a,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x004b,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x004c,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x004d,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x004e,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x004f,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0050,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0051,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0052,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0053,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0054,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0055,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0056,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0057,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0058,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0059,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x005a,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x002c,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x002d,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x002e,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x002f,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0030,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0031,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0032,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0033,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0034,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0035,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0036,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0037,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0038,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x0039,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x003a,
0x0000, 0x0000, 0x000d, 0x0002, 0x0001, 0x0001, 0x0000, 0x003b,
0x0000, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x002e,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x002f,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0030,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0031,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0032,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0033,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0034,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0035,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0036,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0037,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0038,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0039,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x003a,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x003b,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x003c,
0x00c0, 0x0000, 0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x003d,
0x00c0, 0x0000, 0x001d, 0x0002, 0x0000, 0x0009, 0x0000, 0x0100,
0x0008, 0x4e3d, 0x0001, 0x40c5, 0x000d, 0x0005, 0x000e, 0xa108,
0x0008, 0xf4bd, 0x000d, 0x0006, 0x000a, 0x7025, 0x0000, 0x0025,
0x000d, 0x0866, 0x0055, 0x0002, 0x0000, 0x0025, 0x0000, 0x0186,
0x000c, 0x1e00, 0x0001, 0x40c0, 0x0000, 0x01a5, 0x0000, 0x0000,
0x0021, 0x9300, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x000a, 0xe380, 0x000c, 0x09d7, 0x000c, 0x0201, 0x000c, 0x0994,
0x000c, 0x09d7, 0x000c, 0x0a7d, 0x000c, 0x0a04, 0x000c, 0x0a82,
0x000c, 0x0805, 0x000c, 0x0a87, 0x000c, 0x0790, 0x000c, 0x0925,
0x000c, 0x08de, 0x000c, 0x0876, 0x000c, 0x07f3, 0x000c, 0x0800,
0x000c, 0x01a0, 0x000c, 0x01ca, 0x0046, 0xf400, 0x0000, 0xffff,
0x0020, 0xc700, 0x0044, 0xf400, 0x0000, 0x0010, 0x000d, 0x0826,
0x000a, 0x23a0, 0x0000, 0x01aa, 0x000a, 0x700f, 0x0000, 0x0024,
0x0000, 0x000c, 0x0011, 0x0002, 0x0000, 0x0003, 0x0000, 0x01ab,
0x0042, 0x0300, 0x0040, 0x0100, 0x0052, 0x1000, 0x0015, 0x0002,
0x0000, 0x0005, 0x0000, 0x01ae, 0x0008, 0x4e0b, 0x000d, 0x0846,
0x0001, 0x4285, 0x000a, 0xf0aa, 0x0000, 0x01b7, 0x0011, 0x0002,
0x0000, 0x0003, 0x0000, 0x01b3, 0x0052, 0x9000, 0x0040, 0x8100,
0x0042, 0x8300, 0x0033, 0x0002, 0x0000, 0x0014, 0x0000, 0x01b6,
0x0000, 0x0004, 0x006b, 0x1000, 0x000d, 0x0846, 0x004c, 0x7000,
0x0000, 0x0000, 0x000d, 0x0846, 0x0044, 0x7000, 0x0000, 0x0000,
0x0063, 0xf400, 0x0000, 0x07fb, 0x0006, 0x0590, 0x0000, 0x0004,
0x0054, 0xdb00, 0x000d, 0x0859, 0x0000, 0x0000, 0x006b, 0x9000,
0x000c, 0x01b3, 0x000a, 0x7030, 0x0000, 0x0024, 0x0000, 0x0004,
0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x01ca, 0x0000, 0x03f8,
0x0017, 0x0002, 0x0000, 0x0006, 0x0000, 0x01cb, 0x0006, 0x0590,
0x0000, 0x0002, 0x0000, 0x0000, 0x000d, 0x0204, 0x0000, 0x0086,
0x000c, 0x01cf, 0x00c7, 0x0002, 0x0000, 0x005e, 0x0000, 0x0233,
0x004c, 0x1a00, 0x004c, 0x1b00, 0x0045, 0xf400, 0x0000, 0x0238,
0x004d, 0x1800, 0x005e, 0x9b00, 0x0025, 0x0c00, 0x0001, 0x6085,
0x000e, 0x7246, 0x004c, 0x9b51, 0x0001, 0x5f86, 0x0020, 0x0040,
0x0001, 0x6085, 0x000e, 0x7246, 0x0025, 0x0e00, 0x005e, 0x9b00,
0x0001, 0x4485, 0x000e, 0x7246, 0x0025, 0x0600, 0x000a, 0xac17,
0x0043, 0x0800, 0x0069, 0x1600, 0x005e, 0x9b00, 0x000c, 0x1e9c,
0x0001, 0x40c4, 0x0001, 0x0000, 0x0020, 0x0072, 0x0008, 0xcc07,
0x005e, 0x9b00, 0x0020, 0x0023, 0x0001, 0x4184, 0x0008, 0xf4af,
0x00ff, 0xffcb, 0x0008, 0xcc2d, 0x0008, 0xd12e, 0x0008, 0xf4ac,
0x00af, 0xeac0, 0x0020, 0xce00, 0x0020, 0x0062, 0x0008, 0xcc08,
0x000a, 0x7028, 0x0000, 0x0025, 0x000a, 0x7000, 0x0000, 0x0023,
0x000a, 0x8624, 0x0000, 0x000c, 0x004c, 0x1a00, 0x004c, 0x1b00,
0x0045, 0xf400, 0x0000, 0x0266, 0x004d, 0x1800, 0x004c, 0x9b00,
0x0025, 0x0f00, 0x0020, 0x0051, 0x0001, 0x5f86, 0x0020, 0x0042,
0x0001, 0x6085, 0x000e, 0xa26e, 0x0025, 0x0700, 0x0020, 0x0041,
0x000a, 0xa817, 0x000a, 0xac17, 0x0043, 0x0800, 0x0069, 0x1600,
0x000a, 0x862e, 0x0020, 0x0023, 0x0001, 0x4184, 0x0008, 0xd12b,
0x0008, 0xcc29, 0x0008, 0xf4aa, 0x00ff, 0xffcc, 0x000a, 0x86ae,
0x0000, 0x027a, 0x0008, 0xf4a8, 0x00af, 0xfa50, 0x005e, 0x9b00,
0x000c, 0x1e9c, 0x0001, 0x40c4, 0x0001, 0x0000, 0x0020, 0x0072,
0x0008, 0xcc07, 0x0020, 0xce00, 0x0020, 0x0062, 0x000a, 0x7028,
0x0000, 0x0025, 0x0008, 0xcc08, 0x000a, 0x7000, 0x0000, 0x0023,
0x000a, 0x8624, 0x0000, 0x000c, 0x0067, 0x1600, 0x0077, 0x1700,
0x0005, 0x1827, 0x006f, 0x9900, 0x0011, 0x0002, 0x0000, 0x0003,
0x0000, 0x0291, 0x0042, 0x0300, 0x0040, 0x0100, 0x0052, 0x1000,
0x0037, 0x0002, 0x0000, 0x0016, 0x0000, 0x0294, 0x006b, 0x1000,
0x0005, 0x1163, 0x000b, 0x77d3, 0x0000, 0x0004, 0x0043, 0x0600,
0x0061, 0x1300, 0x0005, 0x1521, 0x0005, 0xf421, 0x00ff, 0xffff,
0x000b, 0xe380, 0x0044, 0xf400, 0x0000, 0x02ae, 0x0007, 0x7084,
0x0000, 0x0071, 0x0005, 0x9521, 0x0067, 0x9600, 0x0077, 0x9700,
0x0005, 0x9827, 0x0043, 0x8600, 0x006b, 0x9000, 0x0005, 0x9163,
0x0061, 0x9300, 0x0011, 0x0002, 0x0000, 0x0003, 0x0000, 0x02aa,
0x0052, 0x9000, 0x0040, 0x8100, 0x0042, 0x8300, 0x000d, 0x0002,
0x0000, 0x0001, 0x0000, 0x02ad, 0x0000, 0x0004, 0x0011, 0x0002,
0x0000, 0x0003, 0x0000, 0x02ae, 0x0042, 0x0300, 0x0040, 0x0100,
0x0052, 0x1000, 0x008d, 0x0002, 0x0000, 0x0041, 0x0000, 0x02b1,
0x006b, 0x1000, 0x0005, 0x1163, 0x0043, 0x0600, 0x0061, 0x1300,
0x000a, 0x8604, 0x0005, 0xf423, 0x00ff, 0xffff, 0x006b, 0x9600,
0x000a, 0x8a82, 0x0000, 0x02c0, 0x0008, 0x5b8b, 0x0000, 0x0000,
0x0000, 0x0000, 0x000a, 0x8aa2, 0x0000, 0x02bb, 0x0008, 0x450a,
0x004d, 0x7000, 0x0000, 0x0021, 0x0008, 0xf48a, 0x0000, 0x0fe0,
0x000a, 0x7008, 0x0000, 0x0025, 0x000a, 0x8aae, 0x0000, 0x02e2,
0x000a, 0xc52a, 0x0000, 0x02d8, 0x000a, 0xc529, 0x0000, 0x02de,
0x000a, 0xc52b, 0x0000, 0x02de, 0x000a, 0x7020, 0x0000, 0x0023,
0x000d, 0x02fa, 0x005e, 0x9a00, 0x004c, 0x9b00, 0x0020, 0x0044,
0x000a, 0xac17, 0x005c, 0x1c00, 0x000c, 0x02e5, 0x006b, 0x9800,
0x0043, 0x8800, 0x0069, 0x9600, 0x004c, 0x9b00, 0x000b, 0xe380,
0x000c, 0x02f2, 0x006b, 0x9800, 0x000d, 0x02fa, 0x000b, 0xe380,
0x000c, 0x02f2, 0x004c, 0x9a00, 0x004c, 0x1c00, 0x000a, 0xac17,
0x0063, 0xa700, 0x0005, 0x1521, 0x0005, 0xf421, 0x00ff, 0xffff,
0x0067, 0x1600, 0x0077, 0x1700, 0x0005, 0x1827, 0x006f, 0x9900,
0x000b, 0xe380, 0x0005, 0x9521, 0x0067, 0x9600, 0x0077, 0x9700,
0x0005, 0x9827, 0x0011, 0x0002, 0x0000, 0x0003, 0x0000, 0x02f2,
0x0052, 0x9000, 0x0040, 0x8100, 0x0042, 0x8300, 0x0029, 0x0002,
0x0000, 0x000f, 0x0000, 0x02f5, 0x0043, 0x8600, 0x006b, 0x9000,
0x0005, 0x9163, 0x0061, 0x9300, 0x0000, 0x0004, 0x0008, 0x4e0a,
0x0001, 0x40c0, 0x0001, 0x8000, 0x000c, 0x1ee0, 0x000c, 0x1e84,
0x004d, 0x9b00, 0x0021, 0x8464, 0x004c, 0x1b36, 0x0000, 0x0000,
0x0021, 0x8500, 0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x0304,
0x0000, 0x03f8, 0x001d, 0x0002, 0x0000, 0x0009, 0x0000, 0x0305,
0x004f, 0x9661, 0x0020, 0x0023, 0x0020, 0x0070, 0x0000, 0x0000,
0x0021, 0x9100, 0x0020, 0xae00, 0x000c, 0x1e90, 0x0027, 0x0000,
0x0021, 0x8600, 0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x030e,
0x000a, 0xf971, 0x0013, 0x0002, 0x0000, 0x0004, 0x0000, 0x030f,
0x0048, 0x8800, 0x0020, 0x0030, 0x0000, 0x0000, 0x0048, 0x0800,
0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x0313, 0x000a, 0xf951,
0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x0314, 0x0000, 0xfdb8,
0x000f, 0x0002, 0x0000, 0x0002, 0x0000, 0x0315, 0x0043, 0x8800,
0x0000, 0x000c, 0x0053, 0x0002, 0x0000, 0x0024, 0x0000, 0x0000,
0x000c, 0x0100, 0x0000, 0x0000, 0x0000, 0x0086, 0x0000, 0x0000,
0x0000, 0x0086, 0x0000, 0x0000, 0x000c, 0x0006, 0x0000, 0x0000,
0x000c, 0x0008, 0x0000, 0x0000, 0x000c, 0x000a, 0x0000, 0x0000,
0x000c, 0x000c, 0x0000, 0x0000, 0x000c, 0x000e, 0x0000, 0x0000,
0x000c, 0x0010, 0x0000, 0x0000, 0x000c, 0x0012, 0x0000, 0x0000,
0x000c, 0x0014, 0x0000, 0x0000, 0x000c, 0x0016, 0x0000, 0x0000,
0x000c, 0x0018, 0x0000, 0x0000, 0x000c, 0x001a, 0x0000, 0x0000,
0x000c, 0x001c, 0x0000, 0x0000, 0x000c, 0x001e, 0x0000, 0x0000,
0x000c, 0x0020, 0x0000, 0x0000, 0x000c, 0x0022, 0x0000, 0x0000,
0x002b, 0x0002, 0x0000, 0x0010, 0x0000, 0x0072, 0x000d, 0x0844,
0x0000, 0x0000, 0x000d, 0x0873, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x000d, 0x0785, 0x0000, 0x0000, 0x000d, 0x0788,
0x0000, 0x0000, 0x000d, 0x0a01, 0x0000, 0x0000, 0x000d, 0x0a7a,
0x0000, 0x0000, 0x000d, 0x0922, 0x0000, 0x0000, 0x000f, 0x0002,
0x0000, 0x0002, 0x0000, 0x00ec, 0x0000, 0x0000, 0x0000, 0x0000,
0x001b, 0x0002, 0x0000, 0x0008, 0x0000, 0x00f6, 0x000d, 0x08db,
0x0000, 0x0000, 0x000d, 0x01c7, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x000d, 0x078d, 0x0000, 0x0000, 0x000d, 0x0002,
0x0000, 0x0001, 0x0000, 0x00fe, 0x0000, 0x03f8, 0x000d, 0x0002,
0x0000, 0x0001, 0x0000, 0x00ff, 0x000c, 0x0fa4, 0x00db, 0x0002,
0x0000, 0x0068, 0x0000, 0x080b, 0x005e, 0x8000, 0x0020, 0x0060,
0x0047, 0x8000, 0x0021, 0x8600, 0x000d, 0x0233, 0x000c, 0x0832,
0x005e, 0x8000, 0x0020, 0x0060, 0x0047, 0x8000, 0x0021, 0x8600,
0x000d, 0x0261, 0x000c, 0x0832, 0x005e, 0x8000, 0x0020, 0x0040,
0x0047, 0x8000, 0x0021, 0x8600, 0x0044, 0xf400, 0x0000, 0x0004,
0x0061, 0xf400, 0x0000, 0x0600, 0x000d, 0x0233, 0x000d, 0x0832,
0x0044, 0xf000, 0x0000, 0x0600, 0x0045, 0xf000, 0x0000, 0x0601,
0x0000, 0x000c, 0x005e, 0x8000, 0x0046, 0x7040, 0x0000, 0x0600,
0x0047, 0x7000, 0x0000, 0x0601, 0x0061, 0xf400, 0x0000, 0x0600,
0x0047, 0x8000, 0x0021, 0x8600, 0x0044, 0xf400, 0x0000, 0x0004,
0x000d, 0x0261, 0x000a, 0x25a8, 0x0000, 0x0832, 0x0000, 0x000c,
0x0061, 0xf400, 0x0000, 0x0600, 0x0044, 0xf400, 0x0000, 0x0008,
0x000d, 0x0233, 0x000d, 0x0832, 0x0044, 0xf000, 0x0000, 0x0600,
0x0045, 0xf000, 0x0000, 0x0601, 0x0050, 0xf000, 0x0000, 0x0602,
0x0054, 0xf000, 0x0000, 0x0603, 0x0000, 0x000c, 0x000a, 0x8506,
0x0000, 0x0004, 0x000c, 0xc902, 0x0000, 0x0000, 0x0008, 0x440b,
0x0000, 0x000c, 0x000a, 0x8981, 0x0000, 0x084a, 0x0008, 0xc40d,
0x0000, 0x000c, 0x000c, 0xc902, 0x0000, 0x0000, 0x0008, 0x440b,
0x0000, 0x0000, 0x0000, 0x0000, 0x000c, 0xc902, 0x0000, 0x0000,
0x0008, 0x4e0b, 0x000c, 0x1ea0, 0x0020, 0x0042, 0x0000, 0x000c,
0x000c, 0xc901, 0x0000, 0x0000, 0x0008, 0xcc0d, 0x000c, 0x1ee0,
0x0000, 0x0000, 0x000c, 0xc901, 0x0000, 0x0000, 0x0008, 0xcc0d,
0x0000, 0x000c, 0x000a, 0x8a81, 0x0000, 0x0862, 0x0008, 0xcc0c,
0x0000, 0x000c, 0x0008, 0xf485, 0x0000, 0x0000, 0x000a, 0x89b7,
0x0000, 0x0868, 0x0008, 0xf487, 0x0000, 0x0000, 0x000a, 0x8632,
0x0008, 0xf485, 0x0010, 0x0005, 0x000a, 0xfa68, 0x000a, 0xbe20,
0x000a, 0xbe01, 0x0000, 0x000c, 0x047b, 0x0002, 0x0000, 0x0238,
0x0000, 0x0317, 0x0044, 0xf400, 0x0000, 0x0080, 0x0045, 0xf400,
0x0000, 0x8000, 0x004e, 0xdc00, 0x0006, 0x2090, 0x0000, 0x0007,
0x004e, 0xdcd0, 0x004e, 0xdce2, 0x004e, 0xdcd8, 0x004e, 0xdcea,
0x0050, 0x5900, 0x0051, 0x4900, 0x0020, 0x5413, 0x0000, 0x000c,
0x0044, 0xf400, 0x0000, 0x0080, 0x0045, 0xf400, 0x0000, 0x8000,
0x004e, 0xdc00, 0x0006, 0x1090, 0x0000, 0x0009, 0x004e, 0xdcd0,
0x004e, 0xdce2, 0x004e, 0xdcd8, 0x004e, 0xdcea, 0x0050, 0x5900,
0x0050, 0x4900, 0x0051, 0x5900, 0x0051, 0x4900, 0x0020, 0x5413,
0x0000, 0x000c, 0x0024, 0x8000, 0x0006, 0x2090, 0x0000, 0x0009,
0x005c, 0xdc00, 0x000c, 0x1ea0, 0x0020, 0x0043, 0x005d, 0xdc00,
0x000c, 0x1ea1, 0x0020, 0x004b, 0x0054, 0x5900, 0x0055, 0x4900,
0x0020, 0x0013, 0x0000, 0x000c, 0x0024, 0x8000, 0x0025, 0xff00,
0x0006, 0x1090, 0x0000, 0x000b, 0x005c, 0xdc00, 0x000c, 0x1ea0,
0x0020, 0x0043, 0x005d, 0xdc00, 0x000c, 0x1ea1, 0x0020, 0x004b,
0x0054, 0x5900, 0x0054, 0x4900, 0x0055, 0x5900, 0x0055, 0x4900,
0x0020, 0x0013, 0x0000, 0x000c, 0x0044, 0xf400, 0x0000, 0x0080,
0x0045, 0xf400, 0x0000, 0x8000, 0x004e, 0xdc13, 0x0027, 0x001b,
0x0006, 0x2090, 0x0000, 0x0009, 0x004e, 0xdc30, 0x004e, 0xdcd2,
0x004e, 0xdce2, 0x004e, 0xdc38, 0x004e, 0xdcda, 0x004e, 0xdcea,
0x0050, 0x5913, 0x0051, 0x491b, 0x0020, 0x5400, 0x0000, 0x000c,
0x0044, 0xf400, 0x0000, 0x0080, 0x0045, 0xf400, 0x0000, 0x8000,
0x004e, 0xdc13, 0x0027, 0x001b, 0x0006, 0x1090, 0x0000, 0x000b,
0x004e, 0xdc30, 0x004e, 0xdcd2, 0x004e, 0xdce2, 0x004e, 0xdc38,
0x004e, 0xdcda, 0x004e, 0xdcea, 0x0050, 0x5900, 0x0050, 0x4913,
0x0051, 0x5900, 0x0051, 0x491b, 0x0020, 0x5400, 0x0000, 0x000c,
0x0074, 0x2a00, 0x0020, 0x5c13, 0x0027, 0x001b, 0x003c, 0x0200,
0x0044, 0xf400, 0x0000, 0x0080, 0x0045, 0xf400, 0x0000, 0x8000,
0x004e, 0xdc00, 0x0006, 0x2090, 0x0000, 0x0009, 0x004e, 0xdc30,
0x004e, 0xccd2, 0x004e, 0xdce2, 0x004e, 0xdc38, 0x004e, 0xccda,
0x004e, 0xdcea, 0x0050, 0x5913, 0x0051, 0x491b, 0x0020, 0x5400,
0x0020, 0x5400, 0x0074, 0xaa00, 0x0000, 0x000c, 0x0074, 0x2a00,
0x0020, 0x5c13, 0x0027, 0x001b, 0x003c, 0x0200, 0x0044, 0xf400,
0x0000, 0x0080, 0x0045, 0xf400, 0x0000, 0x8000, 0x004e, 0xdc00,
0x0006, 0x1090, 0x0000, 0x000b, 0x004e, 0xdc30, 0x004e, 0xccd2,
0x004e, 0xdce2, 0x004e, 0xdc38, 0x004e, 0xccda, 0x004e, 0xdcea,
0x0050, 0x5900, 0x0050, 0x4913, 0x0051, 0x5900, 0x0051, 0x491b,
0x0020, 0x5400, 0x0020, 0x5400, 0x0074, 0xaa00, 0x0000, 0x000c,
0x0074, 0x2a00, 0x0020, 0x5c13, 0x0027, 0x001b, 0x003c, 0x0200,
0x0044, 0xf400, 0x0000, 0x0080, 0x0045, 0xf400, 0x0000, 0x8000,
0x0039, 0x0800, 0x004e, 0xdc00, 0x0006, 0x1090, 0x0000, 0x0009,
0x004e, 0xdc30, 0x004e, 0xccd2, 0x004e, 0xdce2, 0x004e, 0xdc38,
0x004e, 0xccda, 0x004e, 0xdcea, 0x0050, 0x4913, 0x0051, 0x491b,
0x0020, 0x5400, 0x0020, 0x5400, 0x0074, 0xaa00, 0x0000, 0x000c,
0x0074, 0x2a00, 0x004e, 0xdc13, 0x0027, 0x001b, 0x003c, 0x0200,
0x0044, 0xf400, 0x0000, 0x0080, 0x0045, 0xf400, 0x0000, 0x8000,
0x0039, 0x0800, 0x0006, 0x1090, 0x0000, 0x0009, 0x004e, 0xdce0,
0x004e, 0xccd2, 0x004e, 0xdc30, 0x004e, 0xdce8, 0x004e, 0xccda,
0x004e, 0xdc38, 0x0050, 0x4913, 0x0051, 0x491b, 0x0020, 0x5400,
0x0074, 0xaa00, 0x0000, 0x000c, 0x0074, 0x2a00, 0x004e, 0xdc13,
0x0027, 0x001b, 0x003c, 0x0200, 0x0044, 0xf400, 0x0000, 0x0080,
0x0045, 0xf400, 0x0000, 0x8000, 0x0006, 0x2090, 0x0000, 0x0009,
0x004e, 0xdce0, 0x004e, 0xccd2, 0x004e, 0xdc30, 0x004e, 0xdce8,
0x004e, 0xccda, 0x004e, 0xdc38, 0x0050, 0x5913, 0x0051, 0x491b,
0x0020, 0x5400, 0x0074, 0xaa00, 0x0000, 0x000c, 0x0002, 0x1fd4,
0x0044, 0x2900, 0x0069, 0x2000, 0x0044, 0xf400, 0x0000, 0x03f3,
0x0002, 0x07a4, 0x000b, 0x77d3, 0x0000, 0x0008, 0x000b, 0x77e3,
0x0000, 0x0009, 0x0069, 0xa000, 0x000a, 0x77d9, 0x0000, 0x0009,
0x0074, 0x2a00, 0x003c, 0x0200, 0x0044, 0xf400, 0x0000, 0x0080,
0x0045, 0xf400, 0x0000, 0x8000, 0x0020, 0x5c13, 0x0027, 0x001b,
0x004e, 0xdc00, 0x0006, 0xd310, 0x0000, 0x000c, 0x0006, 0xe310,
0x0000, 0x0009, 0x004e, 0xdc30, 0x004e, 0xccd2, 0x004e, 0xdce2,
0x004e, 0xdc38, 0x004e, 0xccda, 0x004e, 0xdcea, 0x0050, 0x5913,
0x0051, 0x591b, 0x0020, 0x4900, 0x0002, 0x1ff4, 0x0044, 0x2800,
0x0044, 0xf400, 0x0000, 0x0480, 0x004c, 0x1f00, 0x0056, 0xa900,
0x0001, 0x4184, 0x0069, 0x2000, 0x0054, 0x2900, 0x000e, 0x241d,
0x0044, 0xf400, 0x0000, 0x03ed, 0x0002, 0x07a4, 0x0020, 0x5400,
0x0020, 0x5400, 0x0005, 0xf423, 0x00ff, 0xffff, 0x0074, 0xaa00,
0x0000, 0x000c, 0x0024, 0x0000, 0x0063, 0xf400, 0x0000, 0x0600,
0x0006, 0x8090, 0x0000, 0x0002, 0x0044, 0x5b00, 0x000c, 0x042d,
0x0045, 0xf400, 0x0000, 0x0040, 0x000d, 0x050f, 0x0063, 0xf400,
0x0000, 0x0600, 0x0044, 0xf400, 0x0000, 0x8020, 0x0045, 0xf400,
0x0000, 0x8028, 0x0006, 0x2090, 0x0000, 0x0014, 0x0046, 0xdb00,
0x0056, 0xdb00, 0x004e, 0xd950, 0x000c, 0x1c20, 0x0046, 0xdb50,
0x0057, 0xdb00, 0x004e, 0xc958, 0x000c, 0x1ca1, 0x0021, 0xc658,
0x0020, 0x0051, 0x0021, 0xe700, 0x000c, 0x1a89, 0x000c, 0x1a8c,
0x0059, 0x5c00, 0x0058, 0x5c71, 0x000c, 0x1a89, 0x000c, 0x1a8c,
0x0059, 0x5c00, 0x0058, 0x5c00, 0x0000, 0x000c, 0x0024, 0x0000,
0x0063, 0xf400, 0x0000, 0x0600, 0x0006, 0x4090, 0x0000, 0x0002,
0x0044, 0x5b00, 0x000c, 0x0453, 0x0045, 0xf400, 0x0000, 0x0020,
0x000d, 0x050f, 0x0063, 0xf400, 0x0000, 0x0600, 0x0044, 0xf400,
0x0000, 0x8020, 0x0045, 0xf400, 0x0000, 0x8028, 0x0006, 0x2090,
0x0000, 0x000c, 0x0046, 0xdb00, 0x0056, 0xdb00, 0x004e, 0xd950,
0x000c, 0x1c20, 0x0046, 0xdb50, 0x0020, 0x4900, 0x0021, 0xcc00,
0x000c, 0x1a89, 0x000c, 0x1a8c, 0x0059, 0x5c00, 0x0058, 0x5c00,
0x0000, 0x000c, 0x0045, 0xf400, 0x0000, 0x0040, 0x000d, 0x050f,
0x0063, 0xf400, 0x0000, 0x0600, 0x0044, 0xf400, 0x0000, 0x0080,
0x0006, 0x2090, 0x0000, 0x0012, 0x0046, 0xdb00, 0x0056, 0xdb00,
0x004e, 0xd950, 0x000c, 0x1c10, 0x0046, 0xdb50, 0x0057, 0xdb00,
0x004e, 0xc958, 0x000c, 0x1c91, 0x0020, 0x0058, 0x0021, 0xcc00,
0x0021, 0xed00, 0x000c, 0x1ee0, 0x0020, 0x0043, 0x000c, 0x1ee1,
0x0020, 0x004b, 0x005c, 0x5c00, 0x005d, 0x5c00, 0x0000, 0x000c,
0x0045, 0xf400, 0x0000, 0x0020, 0x000d, 0x050f, 0x0063, 0xf400,
0x0000, 0x0600, 0x0044, 0xf400, 0x0000, 0x0080, 0x0006, 0x2090,
0x0000, 0x000d, 0x0046, 0xdb00, 0x0056, 0xdb00, 0x004e, 0xd950,
0x000c, 0x1c10, 0x0020, 0x0050, 0x0020, 0x4900, 0x0021, 0xcc00,
0x0000, 0x0000, 0x000c, 0x1ee0, 0x0020, 0x0043, 0x0000, 0x0000,
0x005c, 0x5c00, 0x0000, 0x000c, 0x0044, 0xf400, 0x0000, 0x0080,
0x0045, 0xf400, 0x0000, 0x8000, 0x0047, 0xf400, 0x0000, 0x00ff,
0x004e, 0xd900, 0x0020, 0x0051, 0x0020, 0x0076, 0x0020, 0x00e8,
0x005c, 0x5c7e, 0x0001, 0x27cd, 0x004e, 0xc900, 0x005d, 0x5c59,
0x005c, 0x5c7e, 0x0020, 0x00e0, 0x005d, 0x5c76, 0x0001, 0x27ed,
0x004e, 0xd900, 0x0006, 0x1f90, 0x0000, 0x000d, 0x005c, 0x5c51,
0x005d, 0x5c76, 0x0020, 0x00e8, 0x005c, 0x5c7e, 0x0001, 0x27cd,
0x004e, 0xc900, 0x005d, 0x5c59, 0x005c, 0x5c7e, 0x0020, 0x00e0,
0x005d, 0x5c76, 0x0001, 0x27ed, 0x004e, 0xd900, 0x005c, 0x5c00,
0x005d, 0x5c00, 0x0000, 0x000c, 0x0044, 0xf400, 0x0000, 0x0080,
0x0045, 0xf400, 0x0000, 0x8000, 0x0047, 0xf400, 0x0000, 0x00ff,
0x0006, 0x2090, 0x0000, 0x000a, 0x004e, 0xd900, 0x0020, 0x0051,
0x0020, 0x0076, 0x0020, 0x00e8, 0x005c, 0x5c7e, 0x0001, 0x27cd,
0x0020, 0x4900, 0x005d, 0x5c00, 0x005c, 0x5c00, 0x0000, 0x000c,
0x0024, 0x0000, 0x0006, 0x2090, 0x0000, 0x000f, 0x005e, 0xd900,
0x004c, 0x5c09, 0x005c, 0x5c00, 0x000c, 0x1ed0, 0x000c, 0x1ee1,
0x005c, 0x5c00, 0x005d, 0x5c00, 0x005e, 0xc900, 0x004c, 0x5c09,
0x005c, 0x5c00, 0x000c, 0x1ed0, 0x000c, 0x1ee1, 0x005c, 0x5c00,
0x005d, 0x5c00, 0x0000, 0x000c, 0x0024, 0x0000, 0x0039, 0x0200,
0x0006, 0x2090, 0x0000, 0x0008, 0x005e, 0xc900, 0x004c, 0x5c09,
0x005c, 0x5c00, 0x000c, 0x1ed0, 0x000c, 0x1ee1, 0x005c, 0x5c00,
0x005d, 0x5c00, 0x0000, 0x000c, 0x0033, 0x0000, 0x0006, 0x2090,
0x0000, 0x000a, 0x005e, 0xd900, 0x000c, 0x1d10, 0x0020, 0x4909,
0x005a, 0x5c00, 0x000c, 0x1d10, 0x000c, 0x1da1, 0x005a, 0x5c00,
0x005b, 0x5c00, 0x006b, 0x5c00, 0x0000, 0x000c, 0x0033, 0x0000,
0x0006, 0x2090, 0x0000, 0x0013, 0x005e, 0xd900, 0x000c, 0x1d10,
0x0020, 0x0009, 0x005a, 0x5c00, 0x000c, 0x1d10, 0x000c, 0x1da1,
0x005a, 0x5c00, 0x005b, 0x5c00, 0x006b, 0x5c00, 0x005e, 0xc900,
0x000c, 0x1d10, 0x0020, 0x0009, 0x005a, 0x5c00, 0x000c, 0x1d10,
0x000c, 0x1da1, 0x005a, 0x5c00, 0x005b, 0x5c00, 0x006b, 0x5c00,
0x0000, 0x000c, 0x0063, 0xf400, 0x0000, 0x0600, 0x0056, 0xf000,
0x0000, 0x003f, 0x0057, 0xf000, 0x0000, 0x0040, 0x0044, 0xf400,
0x0000, 0x0001, 0x0006, 0xc510, 0x0000, 0x000b, 0x0020, 0x0003,
0x0020, 0x2c40, 0x0020, 0x0032, 0x0020, 0x000b, 0x0020, 0x2c48,
0x0020, 0x003a, 0x0054, 0x5b00, 0x0021, 0x8e00, 0x0055, 0x5b00,
0x0021, 0xaf00, 0x0054, 0x7000, 0x0000, 0x003f, 0x0055, 0x7000,
0x0000, 0x0040, 0x0000, 0x000c, 0x0002, 0x1fd4, 0x0044, 0x2900,
0x0069, 0x2000, 0x0044, 0xf400, 0x0000, 0x052f, 0x0002, 0x07a4,
0x000a, 0x6724, 0x000a, 0x77d9, 0x0000, 0x0009, 0x0069, 0xa000,
0x000b, 0x77d3, 0x0000, 0x0008, 0x000a, 0x77e3, 0x0000, 0x0008,
0x0024, 0x0000, 0x0006, 0xd310, 0x0000, 0x000b, 0x0006, 0xe310,
0x0000, 0x0008, 0x005e, 0xd900, 0x004c, 0x5c09, 0x005c, 0x5c00,
0x000c, 0x1ed0, 0x000c, 0x1ee1, 0x005c, 0x5c00, 0x005d, 0x5c00,
0x0020, 0x4900, 0x0005, 0xf423, 0x00ff, 0xffff, 0x0056, 0xa900,
0x0001, 0x4184, 0x0069, 0x2000, 0x0054, 0x2900, 0x000e, 0x254e,
0x0044, 0xf400, 0x0000, 0x0528, 0x0002, 0x07a4, 0x000a, 0x6704,
0x0000, 0x000c, 0x0095, 0x0002, 0x0000, 0x0045, 0x0000, 0x054f,
0x0054, 0x2800, 0x0002, 0x07de, 0x0020, 0x0003, 0x000e, 0xa613,
0x0002, 0x1f9e, 0x0020, 0x0003, 0x000e, 0xa564, 0x0005, 0xf423,
0x00ff, 0xffff, 0x006b, 0x9f00, 0x000b, 0x77d1, 0x0000, 0x0006,
0x0006, 0xcc10, 0x0000, 0x0003, 0x0044, 0xd900, 0x004c, 0x5b00,
0x0044, 0xa800, 0x0025, 0x0044, 0x006b, 0x1f36, 0x0002, 0x1f85,
0x0054, 0x2800, 0x0044, 0xf400, 0x0000, 0x057d, 0x0044, 0x2700,
0x0061, 0xf400, 0x0000, 0x0600, 0x0056, 0xa800, 0x0001, 0x4380,
0x0001, 0x40c6, 0x00ff, 0xfffc, 0x0002, 0x0fb6, 0x0002, 0x0f97,
0x0021, 0x8400, 0x0020, 0xce00, 0x0001, 0x4386, 0x000e, 0x2676,
0x0002, 0x07de, 0x0020, 0x0045, 0x000e, 0x1233, 0x0001, 0x4485,
0x000e, 0x9676, 0x0001, 0x40c6, 0x00ff, 0xfffc, 0x0000, 0x0000,
0x0021, 0x8400, 0x000c, 0x0233, 0x0041, 0x0200, 0x0053, 0x1200,
0x004c, 0x9c00, 0x0061, 0xf441, 0x0000, 0x0600, 0x006f, 0x9f23,
0x0005, 0xf427, 0x00ff, 0xffff, 0x0010, 0xf400, 0x0000, 0x8000,
0x0047, 0xf400, 0x0000, 0x00ff, 0x0057, 0xe100, 0x0045, 0xd97e,
0x0020, 0x00e0, 0x0006, 0xc410, 0x0000, 0x0004, 0x00bf, 0xe100,
0x00b6, 0xf97e, 0x0020, 0x00e0, 0x006f, 0x1f00, 0x006f, 0x9900,
0x004c, 0x9c00, 0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x0594,
0x0000, 0x03f8, 0x0019, 0x0002, 0x0000, 0x0007, 0x0000, 0x0595,
0x0001, 0x41c0, 0x0000, 0x0080, 0x0002, 0x07df, 0x0020, 0x004c,
0x0005, 0xf423, 0x00ff, 0xffff, 0x0002, 0x07cd, 0x000d, 0x0002,
0x0000, 0x0001, 0x0000, 0x059c, 0x000a, 0xf971, 0x0023, 0x0002,
0x0000, 0x000c, 0x0000, 0x059d, 0x0002, 0x0fb9, 0x0002, 0x0f9d,
0x0020, 0x0018, 0x0000, 0x0000, 0x0002, 0x0fa9, 0x0002, 0x0f8d,
0x0002, 0x17f9, 0x0002, 0x17dd, 0x0020, 0x0018, 0x0000, 0x0000,
0x0002, 0x17e9, 0x0002, 0x17cd, 0x000d, 0x0002, 0x0000, 0x0001,
0x0000, 0x05a9, 0x000a, 0xf951, 0x000d, 0x0002, 0x0000, 0x0001,
0x0000, 0x05aa, 0x0000, 0xfdb8, 0x020d, 0x0002, 0x0000, 0x0101,
0x0000, 0x05ab, 0x0041, 0x8200, 0x0053, 0x9200, 0x0056, 0xa800,
0x0020, 0x0044, 0x000e, 0x754f, 0x0020, 0x0036, 0x0053, 0x1200,
0x0041, 0x0200, 0x0064, 0x1b00, 0x0005, 0x1c24, 0x0071, 0x1400,
0x0002, 0x1f8c, 0x0056, 0x9d00, 0x0002, 0x1794, 0x0020, 0x0040,
0x000b, 0x77d3, 0x0000, 0x0000, 0x0064, 0xf400, 0x0000, 0x0480,
0x0005, 0xf424, 0x00ff, 0xffff, 0x0021, 0x9100, 0x0039, 0x0700,
0x0005, 0xf421, 0x0000, 0x01ff, 0x000b, 0xe380, 0x0005, 0xf421,
0x00ff, 0xffff, 0x000b, 0x77d1, 0x0000, 0x0006, 0x0002, 0x1f94,
0x0006, 0xc410, 0x0000, 0x0003, 0x004c, 0xdc00, 0x0044, 0x5900,
0x0071, 0x9400, 0x0064, 0x9b00, 0x0005, 0x9c24, 0x0053, 0x9200,
0x0041, 0x8200, 0x0020, 0x0003, 0x000e, 0x2550, 0x006f, 0x9900,
0x003f, 0x0a00, 0x0044, 0xf400, 0x0000, 0x0480, 0x004c, 0x1f00,
0x000a, 0x4f23, 0x006f, 0x1900, 0x0002, 0x1ff4, 0x0044, 0x2800,
0x000b, 0x77d3, 0x0000, 0x0004, 0x0022, 0xee00, 0x0001, 0x40c5,
0x0000, 0x00e4, 0x000a, 0xe3a2, 0x0056, 0x9d00, 0x0001, 0x40c3,
0x0000, 0x0100, 0x0044, 0xf400, 0x0000, 0x0080, 0x004c, 0x1900,
0x0054, 0x1d00, 0x0056, 0xa100, 0x0001, 0x40c3, 0x0000, 0x0040,
0x0000, 0x0000, 0x0054, 0x2100, 0x0056, 0xab00, 0x0020, 0x0003,
0x000e, 0xa60c, 0x0044, 0xf400, 0x0000, 0x060a, 0x0044, 0x2700,
0x003f, 0x0a00, 0x0067, 0xf400, 0x0000, 0x0085, 0x0063, 0xf400,
0x0000, 0x0600, 0x0006, 0x0a90, 0x0000, 0x0004, 0x0042, 0xcf00,
0x0044, 0x5b00, 0x0045, 0x5b00, 0x005e, 0x8000, 0x0001, 0x40c0,
0x0000, 0x0160, 0x0047, 0x8000, 0x0021, 0x8600, 0x0044, 0xf400,
0x0000, 0x0040, 0x0061, 0xf400, 0x0000, 0x0600, 0x000c, 0x0261,
0x000a, 0x23a0, 0x0000, 0x0600, 0x0044, 0xf400, 0x0000, 0x0316,
0x0044, 0x2700, 0x000a, 0x8604, 0x000a, 0x7008, 0x0000, 0x0025,
0x0000, 0x000c, 0x0002, 0x07fe, 0x0020, 0x0003, 0x000e, 0x2627,
0x0044, 0xf400, 0x0000, 0x0613, 0x0002, 0x17a4, 0x000a, 0x67a2,
0x0000, 0x05d5, 0x0056, 0xe700, 0x0001, 0x40c6, 0x0000, 0x0080,
0x006b, 0x9f00, 0x0005, 0xf423, 0x00ff, 0xffff, 0x0044, 0xa800,
0x0006, 0xc410, 0x0000, 0x0002, 0x005c, 0x5b00, 0x006b, 0x1f00,
0x000c, 0x05ad, 0x0044, 0xf400, 0x0000, 0x0631, 0x0044, 0x2700,
0x0002, 0x0ff6, 0x0002, 0x0fd7, 0x0044, 0xf400, 0x0000, 0x0008,
0x0061, 0xf400, 0x0000, 0x0700, 0x000c, 0x0233, 0x0056, 0xf400,
0x0000, 0x0550, 0x0044, 0xf400, 0x0000, 0x06da, 0x000b, 0x6722,
0x0002, 0x8040, 0x000a, 0x23a0, 0x0000, 0x0613, 0x0021, 0x9300,
0x0002, 0x0ffe, 0x0001, 0x4880, 0x0044, 0xf000, 0x0000, 0x0700,
0x0045, 0xf000, 0x0000, 0x0701, 0x0002, 0x0fec, 0x0050, 0xf000,
0x0000, 0x0702, 0x0054, 0xf000, 0x0000, 0x0703, 0x000c, 0x1d10,
0x000c, 0x1ed0, 0x000c, 0x1c10, 0x0002, 0x0fa4, 0x0002, 0x0f85,
0x0002, 0x07c8, 0x000b, 0x7793, 0x0000, 0x0004, 0x0020, 0x0003,
0x000a, 0xe3a2, 0x0020, 0x8800, 0x0020, 0xac00, 0x0020, 0x0003,
0x000e, 0x265c, 0x0002, 0x07fe, 0x0044, 0xf403, 0x0000, 0x0001,
0x0020, 0x2744, 0x0026, 0x0000, 0x0002, 0x07ee, 0x000a, 0x7027,
0x0000, 0x0024, 0x000c, 0x0613, 0x0002, 0x0fe4, 0x0002, 0x0fc5,
0x000c, 0x0613, 0x000a, 0x67a2, 0x0000, 0x05d5, 0x0056, 0x9d00,
0x0002, 0x1794, 0x0020, 0x0040, 0x0071, 0x1400, 0x0021, 0x9100,
0x002c, 0x0800, 0x0002, 0x2794, 0x0025, 0x0044, 0x0005, 0xf421,
0x0000, 0x01ff, 0x0021, 0x9900, 0x0006, 0x2090, 0x0000, 0x0005,
0x0006, 0xc410, 0x0000, 0x0002, 0x0045, 0x5900, 0x0020, 0x4900,
0x0005, 0xf421, 0x00ff, 0xffff, 0x0071, 0x9400, 0x000c, 0x05d5,
0x0044, 0xf400, 0x0000, 0x0683, 0x0044, 0x2700, 0x0020, 0xce00,
0x0001, 0x40c6, 0x00ff, 0xfffc, 0x0061, 0xf400, 0x0000, 0x0600,
0x0044, 0xf400, 0x0000, 0x0004, 0x0021, 0x8600, 0x0002, 0x0f97,
0x000c, 0x0233, 0x0002, 0x0fb6, 0x000a, 0x23a0, 0x0000, 0x0676,
0x0041, 0x0200, 0x0053, 0x1200, 0x0063, 0xf400, 0x0000, 0x0603,
0x0061, 0xf400, 0x0000, 0x0601, 0x0006, 0x0290, 0x0000, 0x000a,
0x0056, 0xe100, 0x000c, 0x1ed0, 0x0000, 0x0000, 0x0056, 0x5300,
0x0056, 0xd100, 0x0001, 0x40c6, 0x0000, 0x00ff, 0x0000, 0x0000,
0x0054, 0x5300, 0x0020, 0xce00, 0x0001, 0x4386, 0x0001, 0x40c0,
0x0000, 0x0600, 0x0069, 0x9f00, 0x0021, 0x9300, 0x0020, 0xce00,
0x0001, 0x4386, 0x0001, 0x4484, 0x0020, 0x0036, 0x0002, 0x07d4,
0x0020, 0x0045, 0x0002, 0x7040, 0x0000, 0x0000, 0x0006, 0xcc10,
0x0000, 0x0003, 0x0045, 0xdb00, 0x004d, 0x5900, 0x0069, 0x1f00,
0x0021, 0x8400, 0x000c, 0x0594, 0x00e9, 0x0002, 0x0000, 0x006f,
0x0000, 0x06ac, 0x0044, 0xf400, 0x0000, 0x0480, 0x004c, 0x1f00,
0x0002, 0x1ff4, 0x0044, 0x2800, 0x0053, 0x1200, 0x0041, 0x0200,
0x0064, 0x1b00, 0x0005, 0x1c24, 0x0071, 0x1400, 0x0064, 0xf400,
0x0000, 0x0480, 0x0002, 0x1f9e, 0x0020, 0x0003, 0x000e, 0xa6c7,
0x0005, 0xf424, 0x00ff, 0xffff, 0x000b, 0x77d1, 0x0000, 0x0006,
0x0006, 0xcc10, 0x0000, 0x0003, 0x004c, 0xd900, 0x004c, 0x5c00,
0x0044, 0xa800, 0x0025, 0x0040, 0x0002, 0x1f85, 0x0054, 0x2800,
0x0056, 0xa100, 0x0002, 0x1794, 0x0020, 0x0040, 0x000b, 0x77d3,
0x0000, 0x0000, 0x0021, 0x9100, 0x0039, 0x0100, 0x0005, 0x7fa1,
0x000b, 0xe380, 0x0005, 0xf421, 0x00ff, 0xffff, 0x0071, 0x9400,
0x0064, 0x9b00, 0x0005, 0x9c24, 0x0053, 0x9200, 0x0041, 0x8200,
0x0044, 0xf400, 0x0000, 0x06da, 0x0002, 0x17a4, 0x0002, 0x07de,
0x0020, 0x0003, 0x000e, 0xa613, 0x0002, 0x0fb6, 0x0044, 0xa851,
0x0001, 0x5f86, 0x000e, 0xa6ec, 0x0020, 0xce00, 0x0001, 0x4386,
0x000e, 0x274a, 0x0020, 0xce00, 0x0001, 0x5f86, 0x0001, 0x6084,
0x0020, 0x0036, 0x0020, 0x0045, 0x0002, 0x7040, 0x0000, 0x0000,
0x0021, 0x8400, 0x0020, 0x8e00, 0x0001, 0x40c6, 0x00ff, 0xffe0,
0x0002, 0xa040, 0x0002, 0x07d5, 0x0020, 0x0065, 0x0002, 0x7060,
0x0001, 0x40c6, 0x00ff, 0xfffc, 0x000e, 0xa74a, 0x0021, 0x8400,
0x0053, 0x1200, 0x0041, 0x0200, 0x0069, 0x9f00, 0x0067, 0xf449,
0x0000, 0x0600, 0x000c, 0x1ec5, 0x0047, 0xf400, 0x0000, 0x8020,
0x005e, 0xd900, 0x001c, 0xd900, 0x000c, 0x1b5e, 0x005f, 0xd900,
0x004e, 0xd900, 0x000c, 0x1b5f, 0x0006, 0xc510, 0x0000, 0x0007,
0x00fa, 0x3f00, 0x004e, 0xd900, 0x000c, 0x1b5e, 0x00ff, 0x3f00,
0x004e, 0xd900, 0x000c, 0x1b5f, 0x006f, 0x9900, 0x0053, 0x9200,
0x0041, 0x8200, 0x0046, 0xf400, 0x0000, 0x0718, 0x0046, 0x2700,
0x0002, 0x0fb6, 0x0002, 0x0f97, 0x0061, 0xf400, 0x0000, 0x0600,
0x000c, 0x0261, 0x004c, 0x9c00, 0x0041, 0x0200, 0x0053, 0x1200,
0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x071b, 0x0000, 0x03f8,
0x0019, 0x0002, 0x0000, 0x0007, 0x0000, 0x071c, 0x005e, 0x9f00,
0x0020, 0x0040, 0x0005, 0xf423, 0x00ff, 0xffff, 0x005c, 0x1f00,
0x0001, 0x41c0, 0x0000, 0x0080, 0x000d, 0x0002, 0x0000, 0x0001,
0x0000, 0x0723, 0x000a, 0xf971, 0x0023, 0x0002, 0x0000, 0x000c,
0x0000, 0x0724, 0x0002, 0x0fb9, 0x0002, 0x0f9d, 0x0020, 0x0018,
0x0000, 0x0000, 0x0002, 0x0fa9, 0x0002, 0x0f8d, 0x0002, 0x17f9,
0x0002, 0x17dd, 0x0020, 0x0018, 0x0000, 0x0000, 0x0002, 0x17e9,
0x0002, 0x17cd, 0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x0730,
0x000a, 0xf951, 0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x0731,
0x0000, 0xfdb8, 0x00b1, 0x0002, 0x0000, 0x0053, 0x0000, 0x0732,
0x0002, 0x07de, 0x0020, 0x0044, 0x0041, 0x8200, 0x0002, 0x07ce,
0x0056, 0xa800, 0x0020, 0x0044, 0x0053, 0x9200, 0x0054, 0x2800,
0x0001, 0x6085, 0x000e, 0x16da, 0x0002, 0x1f8c, 0x006b, 0x9f00,
0x000b, 0x77d1, 0x0000, 0x0006, 0x0006, 0xcc10, 0x0000, 0x0003,
0x004c, 0xdb00, 0x004c, 0x5900, 0x0044, 0xf400, 0x0000, 0x06b1,
0x0002, 0x17a4, 0x000a, 0x67a4, 0x0000, 0x06ac, 0x000c, 0x05d5,
0x0041, 0x0200, 0x0053, 0x1200, 0x0020, 0xce00, 0x0001, 0x4386,
0x0001, 0x4484, 0x0020, 0x0036, 0x0002, 0x07d4, 0x0020, 0x0045,
0x0002, 0x7040, 0x0000, 0x0000, 0x0021, 0x8400, 0x005c, 0x1e00,
0x0069, 0x9f00, 0x0006, 0xcc10, 0x0000, 0x0003, 0x005b, 0xd900,
0x000c, 0x1c91, 0x0001, 0x4384, 0x0020, 0x0036, 0x000c, 0x1e86,
0x0000, 0x0000, 0x000c, 0x1e35, 0x0020, 0xce00, 0x0001, 0x4386,
0x000c, 0x1e86, 0x0069, 0x1f00, 0x000c, 0x1e55, 0x000c, 0x1ec6,
0x0055, 0x7000, 0x0000, 0x0600, 0x000c, 0x1ca1, 0x0000, 0x0000,
0x0055, 0x7000, 0x0000, 0x0601, 0x002d, 0x0100, 0x000c, 0x1e19,
0x0001, 0x418c, 0x000c, 0x1e15, 0x0001, 0x4f8b, 0x000c, 0x1ea9,
0x0020, 0x005a, 0x0001, 0x40ce, 0x00ff, 0xfffc, 0x0044, 0xf400,
0x0000, 0x0781, 0x0044, 0x2700, 0x0044, 0xf400, 0x0000, 0x0004,
0x0061, 0xf400, 0x0000, 0x0600, 0x0021, 0xa600, 0x0002, 0x0f97,
0x0041, 0x8200, 0x0053, 0x9200, 0x000c, 0x0261, 0x000a, 0x23a0,
0x0000, 0x0780, 0x004c, 0x9e00, 0x000c, 0x0719, 0x0017, 0x0002,
0x0000, 0x0006, 0x0000, 0x0805, 0x000a, 0x85a6, 0x0000, 0x080a,
0x000a, 0x7007, 0x0000, 0x0024, 0x000a, 0x8526, 0x0000, 0x000c,
0x001f, 0x0002, 0x0001, 0x000a, 0x0000, 0x0080, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
0x0000, 0x0000, 0x001f, 0x0002, 0x0002, 0x000a, 0x0000, 0x0080,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x065f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x001f, 0x0002, 0x0001, 0x000a,
0x0000, 0x008a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x001f, 0x0002,
0x0002, 0x000a, 0x0000, 0x008a, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x065f, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x001f, 0x0002, 0x0001, 0x000a, 0x0000, 0x0094, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
0x0000, 0x0000, 0x001f, 0x0002, 0x0002, 0x000a, 0x0000, 0x0094,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x065f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x001f, 0x0002, 0x0001, 0x000a,
0x0000, 0x009e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x001f, 0x0002,
0x0002, 0x000a, 0x0000, 0x009e, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x065f, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x001f, 0x0002, 0x0001, 0x000a, 0x0000, 0x00a8, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
0x0000, 0x0000, 0x001f, 0x0002, 0x0002, 0x000a, 0x0000, 0x00a8,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x065f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x001f, 0x0002, 0x0001, 0x000a,
0x0000, 0x00b2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x001f, 0x0002,
0x0002, 0x000a, 0x0000, 0x00b2, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x065f, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x001f, 0x0002, 0x0001, 0x000a, 0x0000, 0x00bc, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
0x0000, 0x0000, 0x001f, 0x0002, 0x0002, 0x000a, 0x0000, 0x00bc,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x065f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x001f, 0x0002, 0x0001, 0x000a,
0x0000, 0x00c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x001f, 0x0002,
0x0002, 0x000a, 0x0000, 0x00c6, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x065f, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x001f, 0x0002, 0x0001, 0x000a, 0x0000, 0x00d0, 0x0000, 0x0004,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
0x0000, 0x0000, 0x001f, 0x0002, 0x0002, 0x000a, 0x0000, 0x00d0,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x065f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x001f, 0x0002, 0x0001, 0x000a,
0x0000, 0x00da, 0x0000, 0x0004, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x001f, 0x0002,
0x0002, 0x000a, 0x0000, 0x00da, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x065f, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0013, 0x0002, 0x0001, 0x0004, 0x0000, 0x00e4, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0013, 0x0002,
0x0002, 0x0004, 0x0000, 0x00e4, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0013, 0x0002, 0x0001, 0x0004,
0x0000, 0x0028, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0011, 0x0002, 0x0002, 0x0003, 0x0000, 0x001e,
0x0000, 0x0000, 0x0000, 0x0480, 0x0000, 0x0000, 0x0081, 0x0002,
0x0002, 0x003b, 0x0000, 0x05a0, 0x0000, 0x0344, 0x0000, 0x0482,
0x0000, 0x0002, 0x0000, 0x0020, 0x0000, 0x0326, 0x0000, 0x0450,
0x0000, 0x0002, 0x0000, 0x0040, 0x0000, 0x0366, 0x0000, 0x04bc,
0x0000, 0x0002, 0x0000, 0x0060, 0x0000, 0x0391, 0x0000, 0x04e0,
0x0000, 0x0002, 0x0000, 0x0080, 0x0000, 0x0337, 0x0000, 0x0467,
0x0000, 0x0002, 0x0000, 0x0040, 0x0000, 0x0317, 0x0000, 0x042a,
0x0000, 0x0002, 0x0000, 0x0080, 0x0000, 0x0354, 0x0000, 0x0498,
0x0000, 0x0002, 0x0000, 0x00c0, 0x0000, 0x037a, 0x0000, 0x04ce,
0x0000, 0x0002, 0x0000, 0x0100, 0x0000, 0x03aa, 0x0000, 0x04e0,
0x0000, 0x0001, 0x0000, 0x0080, 0x0000, 0x03c2, 0x0000, 0x04ec,
0x0000, 0x0001, 0x0000, 0x0080, 0x0000, 0x0326, 0x0000, 0x0449,
0x0000, 0x0002, 0x0000, 0x0040, 0x0000, 0x0317, 0x0000, 0x0423,
0x0000, 0x0002, 0x0000, 0x0080, 0x0000, 0x03d8, 0x0000, 0x04f9,
0x0000, 0x0002, 0x0000, 0x0100, 0x0000, 0x0001, 0x0000, 0x0002,
0x0000, 0x0002, 0x0000, 0x0003, 0x0000, 0x0003, 0x0000, 0x0003,
0x0000, 0x0003, 0x017b, 0x0002, 0x0000, 0x00b8, 0x0000, 0x0873,
0x000a, 0x702c, 0x0000, 0x0024, 0x0000, 0x0004, 0x0044, 0xf400,
0x0000, 0x0014, 0x000d, 0x0817, 0x000a, 0x23a0, 0x0000, 0x08da,
0x000d, 0x0940, 0x0040, 0x7000, 0x0000, 0x00e4, 0x0044, 0xf400,
0x0000, 0x0b7c, 0x000d, 0x0817, 0x000a, 0x23a0, 0x0000, 0x08da,
0x000d, 0x0940, 0x0040, 0x7000, 0x0000, 0x00e7, 0x0045, 0xf400,
0x0000, 0x0020, 0x0044, 0xf400, 0x0000, 0x0014, 0x0061, 0xf400,
0x0000, 0x0600, 0x000d, 0x080b, 0x000a, 0x23a0, 0x0000, 0x08da,
0x0049, 0xf000, 0x0000, 0x00e4, 0x0067, 0xf400, 0x0000, 0x0080,
0x003f, 0x0a00, 0x0023, 0xf800, 0x0061, 0xf400, 0x0000, 0x0600,
0x0006, 0x0a90, 0x0000, 0x002f, 0x000a, 0xc900, 0x0000, 0x08c5,
0x0056, 0xab00, 0x0001, 0x4180, 0x000a, 0x67a0, 0x0000, 0x08c5,
0x0054, 0x2b00, 0x0056, 0xe100, 0x000d, 0x0945, 0x0056, 0xf400,
0x0000, 0x0550, 0x0044, 0xf400, 0x0000, 0x06b1, 0x000b, 0x6722,
0x0002, 0x8040, 0x000a, 0x6720, 0x0002, 0x17ac, 0x0022, 0xf000,
0x0002, 0x279e, 0x0001, 0x4184, 0x000a, 0x67a2, 0x0000, 0x08b6,
0x0044, 0xf400, 0x0000, 0x05d5, 0x0020, 0x4800, 0x0006, 0xcc10,
0x0000, 0x0003, 0x0002, 0x10a4, 0x0020, 0x4800, 0x000a, 0x67a1,
0x0000, 0x08c5, 0x0004, 0x44bf, 0x002c, 0x0a00, 0x0020, 0x0044,
0x000c, 0x1e86, 0x0001, 0x40c0, 0x0000, 0x0060, 0x000c, 0x1c30,
0x0042, 0x8000, 0x0024, 0x0020, 0x000a, 0x6721, 0x0002, 0x0fe8,
0x0002, 0x0fcc, 0x0002, 0x07c4, 0x0020, 0x592a, 0x0020, 0x4f00,
0x0049, 0xf000, 0x0000, 0x00e7, 0x0067, 0xf400, 0x0000, 0x0080,
0x003f, 0x0a00, 0x0024, 0x8000, 0x0006, 0x0a90, 0x0000, 0x0007,
0x000a, 0xc900, 0x0000, 0x08d4, 0x000a, 0x6780, 0x0000, 0x08d4,
0x0002, 0x07e4, 0x0020, 0x4f2a, 0x000a, 0x700c, 0x0000, 0x0024,
0x000a, 0x702f, 0x0000, 0x0024, 0x000c, 0x01a0, 0x0000, 0x000c,
0x000a, 0x702b, 0x0000, 0x0024, 0x0000, 0x0004, 0x0044, 0xf400,
0x0000, 0x0018, 0x000d, 0x0817, 0x000a, 0x23a0, 0x0000, 0x0921,
0x000d, 0x0940, 0x0040, 0x7000, 0x0000, 0x00e5, 0x0044, 0xf400,
0x0000, 0x001c, 0x000d, 0x0817, 0x000a, 0x23a0, 0x0000, 0x0921,
0x000d, 0x0940, 0x0040, 0x7000, 0x0000, 0x00e6, 0x0049, 0xf000,
0x0000, 0x00e5, 0x0067, 0xf400, 0x0000, 0x0080, 0x003f, 0x0a00,
0x0023, 0xf800, 0x0006, 0x0a90, 0x0000, 0x0014, 0x000a, 0xc900,
0x0000, 0x0908, 0x000a, 0x6780, 0x0000, 0x0908, 0x0056, 0xab00,
0x0001, 0x4184, 0x000a, 0x6700, 0x0054, 0x2b00, 0x0044, 0xf400,
0x0000, 0x065f, 0x0022, 0xf000, 0x0002, 0x2795, 0x002c, 0x0100,
0x0006, 0xc510, 0x0000, 0x0004, 0x0002, 0x10a4, 0x0002, 0x208c,
0x0020, 0x4800, 0x0020, 0x4f2a, 0x0049, 0xf000, 0x0000, 0x00e6,
0x0067, 0xf400, 0x0000, 0x0080, 0x003f, 0x0a00, 0x0006, 0x0a90,
0x0000, 0x000d, 0x000a, 0xc900, 0x0000, 0x091b, 0x000a, 0x6700,
0x000a, 0x6701, 0x0024, 0x0000, 0x0002, 0x07e4, 0x0002, 0x17e4,
0x0002, 0x17c4, 0x0002, 0x1f84, 0x000d, 0x0989, 0x0002, 0x1fac,
0x0020, 0x4f2a, 0x000a, 0x700b, 0x0000, 0x0024, 0x000a, 0x702f,
0x0000, 0x0024, 0x000c, 0x01a0, 0x0000, 0x000c, 0x000a, 0x702a,
0x0000, 0x0024, 0x0000, 0x0004, 0x0044, 0xf400, 0x0000, 0x0b74,
0x000d, 0x0817, 0x000a, 0x23a0, 0x0000, 0x093f, 0x000d, 0x0940,
0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x092b, 0x0000, 0x03f8,
0x002d, 0x0002, 0x0000, 0x0011, 0x0000, 0x092c, 0x000c, 0x1e00,
0x0001, 0x6e80, 0x0067, 0xf400, 0x0000, 0x0081, 0x0021, 0xc400,
0x0001, 0x41c0, 0x0000, 0x000a, 0x0020, 0x0022, 0x0021, 0x1f00,
0x0000, 0x0000, 0x000a, 0x702f, 0x0000, 0x0024, 0x005e, 0xef00,
0x0001, 0x4180, 0x000a, 0x700a, 0x0000, 0x0024, 0x005e, 0x6f00,
0x000d, 0x0002, 0x0000, 0x0001, 0x0000, 0x093d, 0x0000, 0xfcb8,
0x00b7, 0x0002, 0x0000, 0x0056, 0x0000, 0x093e, 0x000c, 0x01a0,
0x0000, 0x000c, 0x0020, 0x0041, 0x000c, 0x1c20, 0x0020, 0xac00,
0x000c, 0x1c10, 0x0000, 0x000c, 0x000a, 0xcc07, 0x0000, 0x0974,
0x0001, 0x7f86, 0x0021, 0xc500, 0x0001, 0x4484, 0x0020, 0x0023,
0x0001, 0x40c0, 0x0000, 0x05d4, 0x0002, 0x2785, 0x0021, 0x9200,
0x0020, 0x0061, 0x0020, 0x0023, 0x0000, 0x0000, 0x004c, 0xe200,
0x0002, 0x27ec, 0x002c, 0x0700, 0x0020, 0x0044, 0x0000, 0x0000,
0x0021, 0x8661, 0x000c, 0x1e1a, 0x0000, 0x0000, 0x0002, 0x1fec,
0x002c, 0x0100, 0x000c, 0x1e18, 0x0000, 0x0000, 0x0002, 0x1fcc,
0x002c, 0x2000, 0x000c, 0x1e38, 0x0000, 0x0000, 0x0002, 0x27ac,
0x002c, 0x0800, 0x0046, 0xf400, 0x0000, 0x0002, 0x000b, 0x6722,
0x0002, 0x8050, 0x0020, 0x0064, 0x0000, 0x0000, 0x0002, 0x27cc,
0x0054, 0xf400, 0x0000, 0x03ed, 0x0046, 0xf400, 0x0000, 0x0528,
0x000b, 0x6722, 0x0002, 0x8050, 0x0000, 0x0000, 0x0002, 0x07ac,
0x0000, 0x000c, 0x0021, 0xc600, 0x000c, 0x1e84, 0x0062, 0xf400,
0x0000, 0x05a0, 0x0021, 0x9a00, 0x0056, 0xf400, 0x0000, 0xfffb,
0x0020, 0x0056, 0x000e, 0x297e, 0x000a, 0x6727, 0x0020, 0x4a00,
0x005e, 0xda00, 0x004d, 0xda00, 0x000b, 0x6722, 0x0002, 0x8060,
0x004c, 0xda00, 0x0002, 0x2784, 0x004c, 0xda00, 0x0002, 0x1fe4,
0x0002, 0x07ac, 0x0000, 0x000c, 0x0002, 0x179e, 0x000a, 0x67a2,
0x0000, 0x0990, 0x000c, 0x1e86, 0x0001, 0x40c0, 0x0000, 0x0100,
0x0000, 0x000c, 0x000c, 0x1e8a, 0x0001, 0x40c0, 0x0000, 0x0100,
0x0000, 0x000c, 0x0037, 0x0002, 0x0000, 0x0016, 0x0000, 0x0109,
0x0067, 0xf400, 0x0000, 0x0080, 0x003f, 0x0a13, 0x0057, 0xf400,
0x0000, 0x0100, 0x0006, 0x0890, 0x0000, 0x0006, 0x0002, 0x178c,
0x0002, 0x1fad, 0x0001, 0x4180, 0x0001, 0x4888, 0x0020, 0x4f00,
0x0020, 0x0013, 0x0057, 0xf400, 0x0000, 0x0100, 0x0006, 0x0290,
0x0000, 0x0006, 0x0002, 0x178c, 0x0002, 0x1fad, 0x0001, 0x4180,
0x0001, 0x6088, 0x0020, 0x4f00, 0x0033, 0x0002, 0x0000, 0x0014,
0x0000, 0x0128, 0x000a, 0x25a8, 0x0000, 0x012e, 0x0056, 0xf000,
0x0000, 0x0024, 0x0020, 0x0003, 0x000f, 0x2186, 0x0044, 0x9d00,
0x0056, 0x9e00, 0x0045, 0xf444, 0x0000, 0x0200, 0x0020, 0x2960,
0x0001, 0x40c5, 0x0000, 0x0100, 0x000e, 0x9128, 0x000a, 0x25a8,
0x0000, 0x0128, 0x0044, 0x9d00, 0x0044, 0x1f00, 0x0044, 0xa100,
0x0044, 0x2200, 0x002b, 0x0002, 0x0000, 0x0010, 0x0000, 0x013c,
0x0061, 0xa200, 0x0005, 0x7fa1, 0x0044, 0xf000, 0x0000, 0x0044,
0x0045, 0xf000, 0x0000, 0x0045, 0x0006, 0x2090, 0x0000, 0x0007,
0x005e, 0xd900, 0x000c, 0x1e48, 0x005f, 0xd100, 0x000c, 0x1e5d,
0x005e, 0x5900, 0x005f, 0x5900, 0x0005, 0xf421, 0x00ff, 0xffff,
0x007f, 0x0002, 0x0000, 0x003a, 0x0000, 0x014c, 0x006b, 0x9d00,
0x0044, 0xf400, 0x0000, 0x028d, 0x0007, 0x7084, 0x0000, 0x0071,
0x004c, 0xf000, 0x0000, 0x0087, 0x0044, 0x2800, 0x0044, 0xf400,
0x0000, 0x0480, 0x004c, 0x1f00, 0x000a, 0x7028, 0x0000, 0x0025,
0x000a, 0x7024, 0x00ff, 0xffc6, 0x000a, 0xe380, 0x0004, 0x62a0,
0x000a, 0x2582, 0x0000, 0x0128, 0x002f, 0x0800, 0x0025, 0x0100,
0x0060, 0xf400, 0x0000, 0x002e, 0x0064, 0xf400, 0x0000, 0x0036,
0x0006, 0x0880, 0x0000, 0x016a, 0x005e, 0xdc00, 0x004c, 0xe000,
0x000d, 0x0170, 0x005e, 0x5800, 0x0020, 0x000b, 0x000e, 0x2128,
0x000a, 0x7002, 0x0000, 0x0025, 0x000c, 0x0128, 0x0021, 0xc645,
0x000e, 0x717c, 0x0020, 0x0044, 0x0020, 0x0026, 0x0001, 0x40c5,
0x0000, 0x8000, 0x000e, 0x9184, 0x0056, 0xf400, 0x0000, 0x8000,
0x0020, 0x0044, 0x0020, 0x0036, 0x0000, 0x000c, 0x0020, 0x0044,
0x0001, 0x40c5, 0x0000, 0x8000, 0x000e, 0x9184, 0x0056, 0xf400,
0x0000, 0x8000, 0x0020, 0x0040, 0x0000, 0x000c, 0x0020, 0xce6c,
0x0000, 0x000c, 0x00c1, 0x0002, 0x0000, 0x005b, 0x0000, 0x0994,
0x000a, 0x2596, 0x0000, 0x09cb, 0x0001, 0x0f00, 0x0004, 0x4e8c,
0x0020, 0x001b, 0x0044, 0xf403, 0x0000, 0x0010, 0x0002, 0x2048,
0x0056, 0xf000, 0x0000, 0x0043, 0x0020, 0x000d, 0x000e, 0xa9aa,
0x0021, 0xb700, 0x0044, 0xf400, 0x0000, 0x0b6c, 0x0027, 0x0000,
0x0021, 0xa600, 0x000d, 0x0826, 0x000a, 0x23a0, 0x0000, 0x09d7,
0x0067, 0x7000, 0x0000, 0x0043, 0x0001, 0x0f20, 0x0036, 0x0000,
0x0060, 0xf400, 0x0000, 0x0047, 0x0064, 0xf400, 0x0000, 0x0600,
0x002c, 0x0500, 0x000d, 0x07e1, 0x0044, 0xf400, 0x0000, 0x000c,
0x0045, 0xf400, 0x0000, 0x0200, 0x0061, 0xf400, 0x0000, 0x0600,
0x000d, 0x0811, 0x000a, 0x23a0, 0x0000, 0x09d7, 0x0036, 0x0000,
0x0060, 0xf400, 0x0000, 0x0048, 0x0064, 0xf400, 0x0000, 0x0600,
0x002c, 0x0500, 0x000d, 0x07e1, 0x0044, 0xf400, 0x0000, 0x000c,
0x0045, 0xf400, 0x0000, 0x01e0, 0x0061, 0xf400, 0x0000, 0x0600,
0x000d, 0x0811, 0x000a, 0x23a0, 0x0000, 0x09d7, 0x000a, 0x7015,
0x0000, 0x0025, 0x000e, 0x09d5, 0x0060, 0xf400, 0x0000, 0x0047,
0x0038, 0x0200, 0x0024, 0x0000, 0x0006, 0x0a90, 0x0000, 0x0002,
0x0044, 0x4800, 0x000a, 0x7002, 0x0000, 0x0024, 0x0000, 0x000c,
0x0007, 0xf403, 0x0000, 0x0003, 0x0044, 0xf400, 0x0004, 0x4e70,
0x0056, 0xf400, 0x0005, 0x1614, 0x000b, 0x7025, 0x0000, 0x0025,
0x0002, 0x0040, 0x0004, 0xcc89, 0x0007, 0xf40a, 0x0000, 0x0000,
0x000a, 0xbe28, 0x000a, 0xbe09, 0x0001, 0x0b2f, 0x0001, 0x0b29,
0x0001, 0x0b22, 0x0001, 0x0b20, 0x0007, 0xf40e, 0x0000, 0x0000,
0x0007, 0xf40f, 0x0000, 0x0031, 0x0000, 0x000c, 0x0011, 0x0002,
0x0000, 0x0003, 0x0000, 0x09ef, 0x0042, 0x0300, 0x0040, 0x0100,
0x0052, 0x1000, 0x0021, 0x0002, 0x0000, 0x000b, 0x0000, 0x09f2,
0x000a, 0x7022, 0x0000, 0x0024, 0x0056, 0xf000, 0x0000, 0x003c,
0x0001, 0x4184, 0x000e, 0x79fb, 0x002c, 0x0300, 0x000a, 0x7035,
0x0000, 0x0025, 0x0054, 0x7000, 0x0000, 0x003c, 0x0011, 0x0002,
0x0000, 0x0003, 0x0000, 0x09fd, 0x0052, 0x9000, 0x0040, 0x8100,
0x0042, 0x8300, 0x0123, 0x0002, 0x0000, 0x008c, 0x0000, 0x0a00,
0x0000, 0x0004, 0x000a, 0x7025, 0x0000, 0x0024, 0x0000, 0x0004,
0x0044, 0xf400, 0x0000, 0x0b64, 0x000d, 0x0817, 0x000a, 0x23a0,
0x0000, 0x0a79, 0x002c, 0x0200, 0x000b, 0xc468, 0x0020, 0x2013,
0x002d, 0x0200, 0x000b, 0xc469, 0x0020, 0x201b, 0x0054, 0x7000,
0x0000, 0x0044, 0x0055, 0x7000, 0x0000, 0x0045, 0x0020, 0x0041,
0x0001, 0x40c6, 0x0000, 0x00ff, 0x0000, 0x0000, 0x0054, 0x7000,
0x0000, 0x0046, 0x0045, 0xf400, 0x0000, 0x0220, 0x0044, 0xf400,
0x0000, 0x0008, 0x0061, 0xf400, 0x0000, 0x0600, 0x000d, 0x080b,
0x000a, 0x23a0, 0x0000, 0x0a79, 0x0060, 0xf400, 0x0000, 0x0600,
0x0061, 0xf400, 0x0000, 0x0036, 0x0006, 0x0490, 0x0000, 0x000d,
0x0020, 0x0013, 0x0052, 0xe000, 0x000c, 0x1c30, 0x000d, 0x07a2,
0x005e, 0x5900, 0x0056, 0xd800, 0x0001, 0x40c6, 0x0000, 0xff00,
0x000c, 0x1d20, 0x000c, 0x1c30, 0x000d, 0x07a2, 0x005e, 0x5900,
0x0045, 0xf400, 0x0000, 0x0240, 0x0044, 0xf400, 0x0000, 0x0010,
0x0061, 0xf400, 0x0000, 0x0600, 0x000d, 0x080b, 0x000a, 0x23a0,
0x0000, 0x0a79, 0x0060, 0xf400, 0x0000, 0x0600, 0x0061, 0xf400,
0x0000, 0x002c, 0x0006, 0x0890, 0x0000, 0x000d, 0x0020, 0x0013,
0x0052, 0xe000, 0x000c, 0x1c30, 0x000d, 0x07a2, 0x0056, 0x5900,
0x0056, 0xd800, 0x0001, 0x40c6, 0x0000, 0xff00, 0x000c, 0x1d20,
0x000c, 0x1c30, 0x000d, 0x07a2, 0x0056, 0x5900, 0x0060, 0xf400,
0x0000, 0x0036, 0x0056, 0xf000, 0x0000, 0x0046, 0x0006, 0x0890,
0x0000, 0x000b, 0x0024, 0x0000, 0x000a, 0xcc00, 0x0000, 0x0a5a,
0x0044, 0xf400, 0x0000, 0x0002, 0x005f, 0xe000, 0x000c, 0x1e79,
0x0020, 0x003e, 0x0020, 0x0023, 0x005f, 0x5800, 0x0060, 0xf400,
0x0000, 0x002c, 0x0056, 0xf000, 0x0000, 0x0046, 0x0006, 0x0890,
0x0000, 0x000e, 0x0024, 0x0000, 0x000a, 0xcc00, 0x0000, 0x0a6a,
0x0044, 0xf400, 0x0000, 0x0002, 0x0006, 0x0290, 0x0000, 0x0006,
0x0057, 0xe000, 0x000c, 0x1e79, 0x0020, 0x003e, 0x0000, 0x0000,
0x0057, 0x5800, 0x0020, 0x0023, 0x000a, 0x7005, 0x0000, 0x0024,
0x000a, 0x7022, 0x0000, 0x0025, 0x000a, 0x702f, 0x0000, 0x0024,
0x000c, 0x01a0, 0x0000, 0x000c, 0x000a, 0x7024, 0x0000, 0x0024,
0x0000, 0x0004, 0x000a, 0x7004, 0x0000, 0x0024, 0x000a, 0x702f,
0x0000, 0x0024, 0x000c, 0x01a0, 0x000a, 0x7006, 0x0000, 0x0024,
0x000a, 0x702f, 0x0000, 0x0024, 0x000c, 0x01a0, 0x000a, 0x7008,
0x0000, 0x0024, 0x000a, 0x702f, 0x0000, 0x0024, 0x0000, 0x000c,
0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x001d, 0x0000, 0x0a8c,
0x000d, 0x0002, 0x0002, 0x0001, 0x0000, 0x0025, 0x0000, 0x0000,
0x0013, 0x0002, 0x0001, 0x0004, 0x0000, 0x0043, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001b, 0x0002,
0x0002, 0x0008, 0x0000, 0x0026, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0035, 0x0002, 0x0000, 0x0015,
0x0000, 0x07f0, 0x000a, 0x702d, 0x0000, 0x0024, 0x0000, 0x0004,
0x0044, 0xf400, 0x0000, 0x0b60, 0x000d, 0x0817, 0x000a, 0x23a0,
0x0000, 0x07ff, 0x0044, 0x7000, 0x00fd, 0xf000, 0x000a, 0x700d,
0x0000, 0x0024, 0x000a, 0x702f, 0x0000, 0x0024, 0x000c, 0x01a0,
0x0000, 0x000c, 0x000a, 0x700e, 0x0000, 0x0024, 0x0000, 0x000c,
0x0000, 0x000c, 0x0000, 0x000c, 0x00e1, 0x0002, 0x0000, 0x006b,
0x0000, 0x0785, 0x000a, 0x7036, 0x0000, 0x0025, 0x0000, 0x0004,
0x000a, 0x7016, 0x0000, 0x0025, 0x000a, 0x7002, 0x0000, 0x0024,
0x0000, 0x0004, 0x000a, 0x7029, 0x0000, 0x0024, 0x0000, 0x0004,
0x0044, 0xf400, 0x0000, 0x0004, 0x000d, 0x0817, 0x000a, 0x25a0,
0x0000, 0x07a1, 0x005e, 0x9500, 0x0020, 0x0043, 0x004c, 0x1500,
0x000a, 0xcc03, 0x0000, 0x079c, 0x000a, 0x7021, 0x0000, 0x0024,
0x000a, 0x7009, 0x0000, 0x0024, 0x000a, 0x702f, 0x0000, 0x0024,
0x000c, 0x01a0, 0x0000, 0x000c, 0x0021, 0x8400, 0x0001, 0x40c5,
0x00ff, 0xff80, 0x000e, 0x77a8, 0x0020, 0x0013, 0x0000, 0x000c,
0x0001, 0x41c4, 0x0015, 0x5555, 0x0000, 0x0000, 0x0021, 0x8600,
0x0001, 0x41d8, 0x0000, 0x0006, 0x000c, 0x1daf, 0x0020, 0x0048,
0x0020, 0x003e, 0x0001, 0x40c8, 0x0000, 0x07bb, 0x0000, 0x0000,
0x0021, 0xb700, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0007, 0xe78e, 0x000c, 0x1e2a, 0x0000, 0x000c, 0x0040, 0x0000,
0x0039, 0x0a41, 0x0032, 0xd646, 0x002d, 0x4efc, 0x0028, 0x619b,
0x0023, 0xfd66, 0x0020, 0x1374, 0x0020, 0x0003, 0x000e, 0x27c7,
0x0056, 0xf400, 0x00ff, 0xff80, 0x0000, 0x000c, 0x0067, 0xf400,
0x0000, 0x0022, 0x000c, 0x1e01, 0x000c, 0x1e26, 0x0021, 0xa700,
0x0021, 0xc400, 0x004e, 0xdf81, 0x0000, 0x0000, 0x0014, 0xdfd0,
0x004e, 0xdfe2, 0x0020, 0x0050, 0x000c, 0x1d04, 0x000c, 0x1c10,
0x0046, 0xf400, 0x0006, 0x051f, 0x0021, 0x8400, 0x0020, 0x00b8,
0x0020, 0x00d0, 0x000c, 0x1d9f, 0x0044, 0xf410, 0x00ff, 0xff80,
0x000c, 0x1c10, 0x0020, 0x0011, 0x0020, 0x0045, 0x0002, 0x9040,
0x0000, 0x000c, 0x0038, 0x0200, 0x0006, 0xcc10, 0x0000, 0x000c,
0x0056, 0xc800, 0x000d, 0x07c2, 0x0054, 0x6400, 0x0056, 0xc800,
0x000d, 0x07c2, 0x000c, 0x1e90, 0x0044, 0xe400, 0x000c, 0x1940,
0x0000, 0x8018, 0x0000, 0x0000, 0x0054, 0x5c00, 0x0000, 0x000c,
0x00cf, 0x0002, 0x0000, 0x0062, 0x0000, 0x01d1, 0x0004, 0x4edf,
0x0001, 0x40c5, 0x0000, 0x001f, 0x000e, 0xa1f2, 0x0007, 0xf43f,
0x0000, 0x0000, 0x0007, 0xf42f, 0x0000, 0x0000, 0x0008, 0xf4b6,
0x00fd, 0xfc11, 0x0044, 0xf400, 0x0000, 0x0010, 0x0044, 0x7000,
0x00fd, 0xf000, 0x0006, 0x0f90, 0x0000, 0x0002, 0x0000, 0x0000,
0x0044, 0xf400, 0x0000, 0x0001, 0x0044, 0x7000, 0x00fd, 0xf000,
0x0007, 0xf435, 0x0020, 0x0000, 0x0007, 0xf425, 0x0020, 0x0000,
0x0007, 0xf436, 0x0002, 0xd900, 0x0007, 0xf426, 0x0003, 0xd900,
0x0007, 0xf43f, 0x0000, 0x0000, 0x0007, 0xf43e, 0x0000, 0x0000,
0x0000, 0x000c, 0x0004, 0xbd05, 0x0000, 0x0000, 0x0004, 0xbd25,
0x0000, 0x0000, 0x0007, 0xf43f, 0x0000, 0x001f, 0x0007, 0xf42f,
0x0000, 0x003f, 0x0000, 0x000c, 0x000a, 0xbe24, 0x000a, 0xbe25,
0x0001, 0x2632, 0x0004, 0x44c7, 0x0000, 0x000c, 0x000a, 0x7001,
0x0000, 0x0024, 0x0000, 0x000c, 0x0000, 0x000c, 0x0042, 0x0a00,
0x006b, 0x1200, 0x0005, 0x1363, 0x007b, 0x1400, 0x0063, 0xa000,
0x0005, 0x7fa3, 0x003b, 0x0200, 0x0004, 0x44c8, 0x0001, 0xbda5,
0x0000, 0x0223, 0x0020, 0x5b00, 0x004c, 0x5b00, 0x0063, 0x2000,
0x0063, 0x9e00, 0x0005, 0xf423, 0x0000, 0x01ff, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x5b00, 0x0007, 0xcb2c,
0x0007, 0xcb2b, 0x0007, 0xcb2a, 0x0007, 0xdb3b, 0x0063, 0x1e00,
0x006b, 0x9200, 0x0005, 0x9363, 0x007b, 0x9400, 0x0042, 0x8a00,
0x0000, 0x0004, 0x004c, 0x4b00, 0x0063, 0x9e00, 0x0005, 0xf423,
0x0000, 0x01ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0007, 0xcb2c, 0x0007, 0xcb2b, 0x0007, 0xcb2a, 0x0007, 0xcb3b,
0x006b, 0x9200, 0x0005, 0x9363, 0x007b, 0x9400, 0x0042, 0x8a00,
0x0000, 0x0004, 0x0017, 0x0002, 0x0000, 0x0006, 0x0000, 0x011f,
0x000d, 0x0803, 0x000d, 0x0804, 0x000d, 0x01d1, 0x000d, 0x09d8,
0x000d, 0x01fc, 0x000d, 0x01f3, 0x000d, 0x0002, 0x0000, 0x0001,
0x0000, 0x0125, 0x0000, 0x03f8, 0x000d, 0x0002, 0x0000, 0x0001,
0x0000, 0x0126, 0x0000, 0xfcb8, 0x000d, 0x0002, 0x0000, 0x0001,
0x0000, 0x0127, 0x000a, 0x8524, 0x0023, 0x0002, 0x0000, 0x000c,
0x0000, 0x0024, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200,
0x0000, 0x0000, 0x000d, 0x09ef, 0x0000, 0x0000, 0x0000, 0x0200,
0x0000, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200,
0x0000, 0x0000, 0x0043, 0x0002, 0x0000, 0x001c, 0x0000, 0x0030,
0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000,
0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000,
0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000,
0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000,
0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000,
0x0000, 0x0200, 0x0000, 0x0000, 0x000d, 0x0205, 0x0000, 0x0000,
0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000,
0x000f, 0x0002, 0x0000, 0x0002, 0x0000, 0x00f0, 0x000d, 0x07f0,
0x0000, 0x0000, 0x00e5, 0x0002, 0x0000, 0x006d, 0x0000, 0x0a8c,
0x0063, 0xa200, 0x003b, 0x0200, 0x0064, 0xa200, 0x0062, 0xf400,
0x0000, 0x0057, 0x003a, 0x0200, 0x0006, 0x0290, 0x0000, 0x000b,
0x0057, 0xe200, 0x005e, 0xcb00, 0x0006, 0x2090, 0x0000, 0x0002,
0x005e, 0xcb15, 0x0020, 0x002e, 0x0020, 0x5c00, 0x0022, 0x9300,
0x0000, 0x0000, 0x0057, 0x4a00, 0x0063, 0xa200, 0x003b, 0x0200,
0x0064, 0xa200, 0x0062, 0xf400, 0x0000, 0x0058, 0x003a, 0x0200,
0x0026, 0x7800, 0x0006, 0x0290, 0x0000, 0x000d, 0x005e, 0xcb1b,
0x0006, 0x2090, 0x0000, 0x0003, 0x0020, 0x0026, 0x005e, 0xcb18,
0x000c, 0x1c93, 0x0044, 0xe200, 0x0020, 0x5cd0, 0x0022, 0x9300,
0x0020, 0x0018, 0x0000, 0x0000, 0x0057, 0x4a00, 0x0067, 0xf400,
0x0000, 0x0080, 0x003f, 0x0a00, 0x0038, 0x0800, 0x0005, 0xf420,
0x0000, 0x01ff, 0x0061, 0xf400, 0x0000, 0x0047, 0x0039, 0x0200,
0x0062, 0x9f00, 0x0004, 0x62a0, 0x0063, 0xf400, 0x0000, 0x002c,
0x0073, 0xf400, 0x00ff, 0xffff, 0x0064, 0xf400, 0x0000, 0x0026,
0x0065, 0xf400, 0x0000, 0x002e, 0x0005, 0x7fa6, 0x003e, 0x0000,
0x0006, 0x0880, 0x0000, 0x0ade, 0x00fd, 0xa100, 0x0022, 0x5000,
0x0066, 0xa200, 0x000a, 0x6783, 0x0000, 0x0acd, 0x0006, 0x2080,
0x0000, 0x0ad8, 0x0045, 0xe000, 0x00f0, 0xdbf0, 0x00f0, 0xcbd2,
0x0020, 0x00d2, 0x004e, 0xe432, 0x0020, 0x0050, 0x0020, 0x4e15,
0x0056, 0x4800, 0x0020, 0x432e, 0x000a, 0x4f03, 0x0057, 0x4900,
0x0020, 0x5a00, 0x0020, 0x5c00, 0x0020, 0x5b00, 0x0005, 0xf420,
0x00ff, 0xffff, 0x0004, 0x66a0, 0x0004, 0x62a0, 0x0063, 0x9f00,
0x003b, 0x0800, 0x0064, 0x9f00, 0x0062, 0xf400, 0x0000, 0x0048,
0x003a, 0x0200, 0x0026, 0x7800, 0x0006, 0x0890, 0x0000, 0x000d,
0x0056, 0xcb1b, 0x0006, 0x2090, 0x0000, 0x0003, 0x0020, 0x0026,
0x0056, 0xcb18, 0x000c, 0x1c93, 0x0044, 0xe200, 0x0020, 0x5cd0,
0x0022, 0x9300, 0x0020, 0x0018, 0x0000, 0x0000, 0x0057, 0x4a00,
0x000c, 0x015c, 0x0013, 0x0002, 0x0000, 0x0004, 0x0000, 0x004c,
0x000c, 0x004c, 0x0000, 0x0000, 0x000c, 0x004e, 0x0000, 0x0000,
0x000f, 0x0002, 0x0000, 0x0002, 0x0000, 0x006a, 0x000d, 0x01ab,
0x0000, 0x0000, 0x000f, 0x0002, 0x0000, 0x0002, 0x0000, 0x0070,
0x000b, 0xf080, 0x0000, 0x02ae, 0x0000, 0x0004, 0x0000
} ;
// **** End of file ****

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
// Loader DSP Code File (Converted by LRS2VxD)
// Copyright (c) Echo Digital Audio, 1999. All Rights Reserved.
WORD pwLoaderDSP[] =
{
0x0082, 0x0001, 0x0000, 0x0100, 0x0200, 0x614c, 0x6c79, 0x2061,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x5344, 0x3550, 0x3336, 0x3030,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2e36, 0x2e30,
0x2e30, 0x2030, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
0x2020, 0x2020, 0x00bd, 0x0002, 0x0000, 0x0059, 0x0000, 0x1a80,
0x0000, 0x03f8, 0x0000, 0x0084, 0x0005, 0x00b0, 0x0001, 0x0503,
0x0001, 0x0504, 0x0005, 0x00b1, 0x0005, 0x00bb, 0x000a, 0xfa54,
0x0005, 0xf439, 0x00c0, 0x0300, 0x0005, 0xf43a, 0x0000, 0x0300,
0x0007, 0xf405, 0x0000, 0x0000, 0x0004, 0x8937, 0x0000, 0x0000,
0x0007, 0xf407, 0x0040, 0x0000, 0x0007, 0xf405, 0x0010, 0x0000,
0x0001, 0x0523, 0x0001, 0x0525, 0x0024, 0x0000, 0x0008, 0xc42c,
0x0008, 0xc428, 0x0008, 0xc424, 0x0008, 0xc420, 0x0008, 0xc41c,
0x0008, 0xc418, 0x0007, 0xf084, 0x0000, 0x1ad3, 0x0007, 0x7084,
0x0000, 0x00fe, 0x0007, 0xf084, 0x0000, 0x1ad4, 0x0007, 0x7084,
0x0000, 0x00ff, 0x0005, 0xf420, 0x00ff, 0xffff, 0x0004, 0x61a0,
0x0004, 0x62a0, 0x0004, 0x63a0, 0x0004, 0x64a0, 0x0004, 0x65a0,
0x0004, 0x66a0, 0x0004, 0x67a0, 0x0005, 0x0847, 0x0020, 0x0013,
0x0020, 0x8800, 0x0020, 0x0003, 0x0005, 0xa41e, 0x0005, 0x0842,
0x0020, 0x9000, 0x0005, 0x0840, 0x0020, 0x8f00, 0x0020, 0x000b,
0x0005, 0xa406, 0x0001, 0x418d, 0x0005, 0xa40a, 0x0001, 0x428d,
0x0005, 0xa40e, 0x0005, 0x0fd1, 0x0004, 0x8902, 0x0000, 0x0000,
0x0000, 0x980b, 0x0000, 0x000a, 0x0005, 0x77dc, 0x0005, 0x0fcb,
0x0004, 0x8902, 0x0000, 0x0000, 0x0007, 0x580b, 0x0000, 0x000a,
0x0005, 0x77dc, 0x0005, 0x0fc5, 0x0004, 0x8902, 0x0000, 0x0000,
0x0007, 0x584b, 0x0000, 0x000a, 0x0005, 0x77dc, 0x0005, 0x0f9f,
0x0001, 0x0503, 0x0000, 0x00b9, 0x000c, 0x0000, 0x000a, 0xf080,
0x0000, 0x1a80, 0x0004, 0x8902, 0x0000, 0x0000, 0x0004, 0x448b,
0x0000, 0x000c, 0x0000, 0x0004, 0x0000
} ;
// **** End of file ****

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,663 @@
// ****************************************************************************
//
// EchoGalsXface.H
//
// Include file for interfacing with the CEchoGals generic driver class.
//
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
/*
Here's a block diagram of how most of the cards work:
+-----------+
record | |<-------------------- Inputs
<-------| | |
PCI | Transport | |
bus | engine | \|/
------->| | +-------+
play | |--->|monitor|-------> Outputs
+-----------+ | mixer |
+-------+
The lines going to and from the PCI bus represent "pipes". A pipe performs
audio transport - moving audio data to and from buffers on the host via
bus mastering.
The inputs and outputs on the right represent input and output "busses."
A bus is a physical, real connection to the outside world. An example
of a bus would be the 1/4" analog connectors on the back of Layla or
an RCA S/PDIF connector.
For most cards, there is a one-to-one correspondence between outputs
and busses; that is, each individual pipe is hard-wired to a single bus.
Cards that work this way are Darla20, Gina20, Layla20, Darla24, Gina24,
Layla24, Mona, and Indigo.
Mia has a feature called "virtual outputs."
+-----------+
record | |<----------------------------- Inputs
<-------| | |
PCI | Transport | |
bus | engine | \|/
------->| | +------+ +-------+
play | |-->|vmixer|-->|monitor|-------> Outputs
+-----------+ +------+ | mixer |
+-------+
Obviously, the difference here is the box labeled "vmixer." Vmixer is
short for "virtual output mixer." For Mia, pipes are *not* hard-wired
to a single bus; the vmixer lets you mix any pipe to any bus in any
combination.
Note, however, that the left-hand side of the diagram is unchanged.
Transport works exactly the same way - the difference is in the mixer stage.
Pipes and busses are numbered starting at zero.
Pipe index
==========
A number of calls in CEchoGals refer to a "pipe index". A pipe index is
a unique number for a pipe that unambiguously refers to a playback or record
pipe. Pipe indices are numbered starting with analog outputs, followed by
digital outputs, then analog inputs, then digital inputs.
Take Gina24 as an example:
Pipe index
0-7 Analog outputs
8-15 Digital outputs
16-17 Analog inputs
18-25 Digital inputs
You get the pipe index by calling CEchoGals::OpenAudio; the other transport
functions take the pipe index as a parameter. If you need a pipe index for
some other reason, use the handy MakePipeIndex method.
Some calls take a CChannelMask parameter; CChannelMask is a handy way to group
pipe indices.
Digital mode switch
===================
Some cards (right now, Gina24, Layla24, and Mona) have a Digital Mode Switch
or DMS. Cards with a DMS can be set to one of three mutually exclusive
digital modes: S/PDIF RCA, S/PDIF optical, or ADAT optical.
This may create some confusion since ADAT optical is 8 channels wide and
S/PDIF is only two channels wide. Gina24, Layla24, and Mona handle this
by acting as if they always have 8 digital outs and ins. If you are in
either S/PDIF mode, the last 6 channels don't do anything - data sent
out these channels is thrown away and you will always record zeros.
Note that with Gina24, Layla24, and Mona, sample rates above 50 kHz are
only available if you have the card configured for S/PDIF optical or S/PDIF RCA.
Double speed mode
=================
Some of the cards support 88.2 kHz and 96 kHz sampling (Darla24, Gina24, Layla24,
Mona, Mia, and Indigo). For these cards, the driver sometimes has to worry about
"double speed mode"; double speed mode applies whenever the sampling rate is above
50 kHz.
For instance, Mona and Layla24 support word clock sync. However, they actually
support two different word clock modes - single speed (below 50 kHz) and double
speed (above 50 kHz). The hardware detects if a single or double speed word clock
signal is present; the generic code uses that information to determine which mode
to use.
The generic code takes care of all this for you.
*/
// Prevent problems with multiple includes
#ifndef _ECHOGALSXFACE_
#define _ECHOGALSXFACE_
//***********************************************************************
//
// PCI configuration space
//
//***********************************************************************
//
// PCI vendor ID and device IDs for the hardware
//
#define VENDOR_ID 0x1057
#define DEVICE_ID_56301 0x1801
#define DEVICE_ID_56361 0x3410
#define SUBVENDOR_ID ((ULONG)0xECC0)
//
// Valid Echo PCI subsystem card IDs
//
#define DARLA 0x0010
#define GINA 0x0020
#define LAYLA 0x0030
#define DARLA24 0x0040
#define GINA24 0x0050
#define LAYLA24 0x0060
#define MONA 0x0070
#define MIA 0x0080
#define INDIGO 0x0090
//***********************************************************************
//
// Array sizes and so forth
//
//***********************************************************************
//
// Sizes
//
#define ECHO_MAXNAMELEN 128 // Max card name length
// (includes 0 terminator)
#define ECHO_MAXAUDIOINPUTS 32 // Max audio input channels
#define ECHO_MAXAUDIOOUTPUTS 32 // Max audio output channels
#define ECHO_MAXAUDIOPIPES 32 // Max number of input and output pipes
// channels
#define ECHO_MAXMIDIJACKS 1 // Max MIDI ports
#define ECHO_MIDI_QUEUE_SZ 512 // Max MIDI input queue entries
#define ECHO_MTC_QUEUE_SZ 32 // Max MIDI time code input queue entries
//
// MIDI activity indicator timeout
//
#define MIDI_ACTIVITY_TIMEOUT_USEC 200000
//*****************************************************************************
//
// Clocks
//
//*****************************************************************************
//
// Clock numbers
//
#define ECHO_CLOCK_INTERNAL 0
#define ECHO_CLOCK_WORD 1
#define ECHO_CLOCK_SUPER 2
#define ECHO_CLOCK_SPDIF 3
#define ECHO_CLOCK_ADAT 4
#define ECHO_CLOCK_ESYNC 5
#define ECHO_CLOCK_ESYNC96 6
#define ECHO_CLOCK_NONE 0xffff
//
// Clock bit numbers - used to report capabilities and whatever clocks
// are being detected dynamically.
//
#define ECHO_CLOCK_BIT_INTERNAL (1<<ECHO_CLOCK_INTERNAL)
#define ECHO_CLOCK_BIT_WORD (1<<ECHO_CLOCK_WORD)
#define ECHO_CLOCK_BIT_SUPER (1<<ECHO_CLOCK_SUPER)
#define ECHO_CLOCK_BIT_SPDIF (1<<ECHO_CLOCK_SPDIF)
#define ECHO_CLOCK_BIT_ADAT (1<<ECHO_CLOCK_ADAT)
#define ECHO_CLOCK_BIT_ESYNC (1<<ECHO_CLOCK_ESYNC)
#define ECHO_CLOCK_BIT_ESYNC96 (1<<ECHO_CLOCK_ESYNC96)
//*****************************************************************************
//
// Digital modes
//
//*****************************************************************************
//
// Digital modes for Mona, Layla24, and Gina24
//
#define DIGITAL_MODE_NONE 0xFF
#define DIGITAL_MODE_SPDIF_RCA 0
#define DIGITAL_MODE_SPDIF_OPTICAL 1
#define DIGITAL_MODE_ADAT 2
#define DIGITAL_MODE_SPDIF_CDROM 3
//
// Digital mode capability masks
//
#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA (1<<DIGITAL_MODE_SPDIF_RCA)
#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL (1<<DIGITAL_MODE_SPDIF_OPTICAL)
#define ECHOCAPS_HAS_DIGITAL_MODE_ADAT (1<<DIGITAL_MODE_ADAT)
#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM (1<<DIGITAL_MODE_SPDIF_CDROM)
//*****************************************************************************
//
// Driver flags
//
//*****************************************************************************
//
// Note that some flags are read-only (look for ROFLAG as part of the name).
// The read-only flags are used to tell you what the card can do; you can't
// set or clear them.
//
// Some cards can only handle mono & stereo interleaved data in host audio buffers; that
// is, you may only specify 1 or 2 in the wPipeWidth field when you open a pipe for
// playing or recording.
//
// If the card has the super interleave flag set, that means that you can interleave
// by more than 2. For super interleave-capable cards, you can interleave by 1, 2,
// 4, 6, 8, 10, 12, 14, or 16. Note that you cannot interleave beyond the actual
// number of pipes on the card - if the card has 16 pipes and you open pipe 6,
// the maximum interleave would be 10.
//
//
// Gina24, Layla24, and Mona support digital input auto-mute. If the digital input
// auto-mute is enabled, the DSP will only enable the digital inputs if the card
// is syncing to a valid clock on the ADAT or S/PDIF inputs.
//
// If the auto-mute is disabled, the digital inputs are enabled regardless of
// what the input clock is set or what is connected.
//
//
#define ECHOGALS_FLAG_BADBOARD 0x0001 // Board could not be init or
// stopped responding
// (i.e. DSP crashed)
#define ECHOGALS_FLAG_SPDIF_NODITHER 0x0002 // Used to disable digital input
// dithering
#define ECHOGALS_FLAG_DIGITAL_IN_NODITHER 0x0002
#define ECHOGALS_FLAG_SYNCH_WAVE 0x0004 // Used to enable wave device
// synchronization. When set,
// all open wave devices for
// a single task start when the
// start for the last channel
// is received.
#define ECHOGALS_FLAG_SAMPLE_RATE_LOCKED 0x0010 // Set true if the rate has been locked
#define ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE 0x4000 // Set if the console needs to handle
// the digital input auto-mute
#define ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK 0x8000 // Set if this card can handle super
// interleave
#define ECHOGALS_FLAG_WRITABLE_MASK 0x3fff
//*****************************************************************************
//
// ECHOSTATUS return type - most of the generic driver functions
// return an ECHOSTATUS value
//
//*****************************************************************************
typedef unsigned long ECHOSTATUS;
//
// Return status values
//
// Changes here require a change in pStatusStrs in CEchoGals.cpp
//
#define ECHOSTATUS_OK 0x00
#define ECHOSTATUS_FIRST 0x00
#define ECHOSTATUS_BAD_FORMAT 0x01
#define ECHOSTATUS_BAD_BUFFER_SIZE 0x02
#define ECHOSTATUS_CANT_OPEN 0x03
#define ECHOSTATUS_CANT_CLOSE 0x04
#define ECHOSTATUS_CHANNEL_NOT_OPEN 0x05
#define ECHOSTATUS_BUSY 0x06
#define ECHOSTATUS_BAD_LEVEL 0x07
#define ECHOSTATUS_NO_MIDI 0x08
#define ECHOSTATUS_CLOCK_NOT_SUPPORTED 0x09
#define ECHOSTATUS_CLOCK_NOT_AVAILABLE 0x0A
#define ECHOSTATUS_BAD_CARDID 0x0B
#define ECHOSTATUS_NOT_SUPPORTED 0x0C
#define ECHOSTATUS_BAD_NOTIFY_SIZE 0x0D
#define ECHOSTATUS_INVALID_PARAM 0x0E
#define ECHOSTATUS_NO_MEM 0x0F
#define ECHOSTATUS_NOT_SHAREABLE 0x10
#define ECHOSTATUS_FIRMWARE_LOADED 0x11
#define ECHOSTATUS_DSP_DEAD 0x12
#define ECHOSTATUS_DSP_TIMEOUT 0x13
#define ECHOSTATUS_INVALID_CHANNEL 0x14
#define ECHOSTATUS_CHANNEL_ALREADY_OPEN 0x15
#define ECHOSTATUS_DUCK_FULL 0x16
#define ECHOSTATUS_INVALID_INDEX 0x17
#define ECHOSTATUS_BAD_CARD_NAME 0x18
#define ECHOSTATUS_IRQ_NOT_OURS 0x19
#define ECHOSTATUS_NO_DATA 0x1E
#define ECHOSTATUS_BUFFER_OVERFLOW 0x1F
#define ECHOSTATUS_OPERATION_CANCELED 0x20
#define ECHOSTATUS_EVENT_NOT_OPEN 0x21
#define ECHOSTATUS_ASIC_NOT_LOADED 0x22
#define ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED 0x23
#define ECHOSTATUS_RESERVED 0x24
#define ECHOSTATUS_BAD_COOKIE 0x25
#define ECHOSTATUS_MIXER_DISABLED 0x26
#define ECHOSTATUS_NO_SUPER_INTERLEAVE 0x27
#define ECHOSTATUS_DUCK_NOT_WRAPPED 0x28
#define ECHOSTATUS_LAST 0x29
//*****************************************************************************
//
// ECHOSTATUS return type - most of the generic driver functions
// return an ECHOSTATUS value
//
//*****************************************************************************
//
// ECHOGALS_AUDIOFORMAT describes the audio buffer format for a pipe
//
// byMonoToStereo is used to resolve an ambiguity when wDataInterleave is set
// to one. Say you're writing a Windows driver and someone tells you to play mono data;
// what they really mean is that they want the same signal sent out of both left
// and right channels.
//
// Now, say you're writing an ASIO driver and the ASIO host wants mono data
// sent out of a single output only. byMonoToStereo is a flag used to resolve
// this; if byMonoToStereo is non-zero, then the same signal is sent out both channels.
// If byMonoToStereo is zero, then only one output channel is used.
//
typedef struct tECHOGALS_AUDIOFORMAT
{
WORD wDataInterleave; // How the data is arranged in memory
// Mono = 1, stereo = 2
WORD wBitsPerSample; // 8, 16, 32
BYTE byMonoToStereo; // Only used if wDataInterleave is 1 and
// if this is an output pipe.
BYTE byDataAreBigEndian; // 1 = Apple, 0 = Intel
} ECHOGALS_AUDIOFORMAT, * PECHOGALS_AUDIOFORMAT;
//
// All kinds of peak and VU meters. Only cards with virtual outputs will
// have output pipe meters.
//
// All data are scaled integers in units of dB X 256
//
typedef struct tECHOGALS_METERS
{
int iNumPipesOut; // These numbers only apply in the context of this structure;
int iNumPipesIn; // they indicate the number of entries in each of the arrays.
int iNumBussesOut;
int iNumBussesIn;
int iPipeOutVU[ECHO_MAXAUDIOOUTPUTS];
int iPipeOutPeak[ECHO_MAXAUDIOOUTPUTS];
int iPipeInVU[ECHO_MAXAUDIOINPUTS];
int iPipeInPeak[ECHO_MAXAUDIOINPUTS];
int iBusOutVU[ECHO_MAXAUDIOOUTPUTS];
int iBusOutPeak[ECHO_MAXAUDIOOUTPUTS];
int iBusInVU[ECHO_MAXAUDIOINPUTS];
int iBusInPeak[ECHO_MAXAUDIOINPUTS];
} ECHOGALS_METERS, * PECHOGALS_METERS;
//
// ECHOGALS_AUDIO_PIPE describes a single pipe.
//
// Note that nPipe is *not* a pipe index; it's just the number for the pipe.
// This is meant to make life easier for you, the driver developer; the code
// is meant to be set up that you don't have to go around calculating the
// pipe index.
//
// In other words, if you want to specify the first input pipe, do this:
//
// nPipe = 0
// bIsInput = TRUE
//
// Don't set nPipe equal to the number of output pipes, since it's not a pipe
// index.
//
typedef struct tECHOGALS_AUDIO_PIPE
{
WORD nPipe; // Pipe number (not a pipe index!)
BOOL bIsInput; // Set TRUE for input pipe, FALSE for output
WORD wInterleave; // Interleave factor for this pipe
// Mono = 1, stereo = 2, 5.1 surround = 6
} ECHOGALS_AUDIO_PIPE, * PECHOGALS_AUDIO_PIPE;
//
// This structure is used to open a pipe and reserve it for your exclusive use.
//
// Note that if you set wInterleave in the ECHOGALS_AUDIO_PIPE sub-struct
// to greater than one, you are actually reserving more than one pipe; in fact
// you are reserving the pipe specified by the nPipe field as well as
// the next wInterleave-1 pipes.
//
// ProcessId is used in specific situations in the Windows driver where
// several pipes are opened as different devices, but you want them all
// to start synchronously. The driver attempts to start the pipes in groups
// based on the ProcessId field.
//
// If you don't want to hassle with this, just set ProcessId to NULL; the
// generic code will then ignore the ProcessId.
//
// ProcessId is also ignored if you clear the ECHOGALS_FLAG_SYNCH_WAVE flag.
//
typedef struct tECHOGALS_OPENAUDIOPARAMETERS
{
ECHOGALS_AUDIO_PIPE Pipe; // Pipe descriptor
BOOL bIsCyclic; // Set TRUE if using circular buffers
// Set FALSE for linked list of use
// once and discard buffers
PVOID ProcessId; // Caller process ID for implementing
// synchronous wave start
} ECHOGALS_OPENAUDIOPARAMETERS, * PECHOGALS_OPENAUDIOPARAMETERS;
//
// Yes, it's the world's simplest structure.
//
typedef struct tECHOGALS_CLOSEAUDIOPARAMETERS
{
WORD wPipeIndex;
} ECHOGALS_CLOSEAUDIOPARAMETERS, * PECHOGALS_CLOSEAUDIOPARAMETERS;
//
// One nifty feature is that the DSP is constantly writing the DMA position
// for each pipe to the comm page without the driver having to do anything.
// You can therefore obtain a pointer to this location and directly read
// the position from anywhere.
//
// The pointer returned should be treated as a read-only pointer and is
// kind of dangerous, since it points directly into the driver.
//
// Note that the value pointed to by pdwPosition will be in little-endian
// format.
//
// The value pointed to by pdwPosition is the number of bytes transported
// by the DSP; it will constantly increase until it hits the 32-bit boundary
// and then wraps around. It does *not* represent the offset into a circular
// DMA buffer; this value is treated identically for cyclic and non-cyclic
// buffer schemes.
//
typedef struct tECHOGALS_POSITION
{
PDWORD pdwPosition;
} ECHOGALS_POSITION, * PECHOGALS_POSITION;
/*
ECHOGALS_CAPS
This structure is used to differentiate one card from another.
szName Zero-terinated char string; unique name for
this card.
wCardType One of the DARLA, GINA, etc. card IDs at the
top of this header file
dwOutClockTypes This is a bit mask describing all the different
output clock types that can be set. If the bit mask
is zero, then the output clock cannot be set on this
card. The bits will be one of the ECHO_CLOCK_BIT_???
defines above.
dwInClockTypes Again, a bit mask describing what this card can
sync to. This mask is fixed, regardless of what is
or is not currently connected to the hardware. Again,
this uses the ECHO_CLOCK_BIT_??? defines.
dwDigitalModes Some cards (right now, Gina24, Layla24 and Mona) have
what we call a Digital Mode Switch or DMS.
Use the ECHOCAPS_HAS_DIGITAL_MODE_??? defines to determine
which digital modes this card supports.
fHasVmixer Boolean flag- if this field is non-zero, then this card
supports virtual outputs.
wNumPipesOut Should be self-explanatory, given the definitions of
wNumPipesIn pipes and busses above. Note that these are all in terms
wNumBussesOut of mono pipes and busses.
wNumBussesIn
wFirstDigitalBusOut Gives you the number of, well, the first bus that
goes out an S/PDIF or ADAT output. If this card has
no digital outputs, wFirstDigitalBusOut will be equal
to wNumBussesOut. This may seem strange, but remember
that the busses are numbered starting at zero and that
valid bus numbers therefore range from zero to
(wNumBussesOut - 1). Doing it this way actually
turned out to simplify writing consoles and so forth.
wFirstDigitalBusIn Just like the last one, but for inputs
wFirstDigitalPipeOut Gives you the number of the first pipe that is connected
to a digital output bus. If this card has no digital output
busses, this will be equal to wNumPipesOut. Cards with
virtual outputs will always have this member set equal
to wNumPipesOut.
wFirstDigitalPipeIn Again, just like wFirstDigitalPipeOut, but for inputs.
dwPipeOutCaps[] Array of bit fields with information about each output
pipe. This tells you what controls are available for
each output pipe, as well as whether or not this pipe
is connected to a digital output. Use the ECHOCAPS_???
bits above to parse this bit field.
dwPipeInCaps[] More arrays for the other busses and pipes; works
dwBusOutCaps[] just like dwPipeOutCaps.
dwBusInCaps[]
wNumMidiOut Number of MIDI inputs and outputs on this card.
wNumMidiIn
*/
enum
{
ECHOCAPS_GAIN = 0x00000001,
ECHOCAPS_MUTE = 0x00000004,
ECHOCAPS_PAN = 0x00000010,
ECHOCAPS_PEAK_METER = 0x00000020,
ECHOCAPS_VU_METER = 0x00000040,
ECHOCAPS_NOMINAL_LEVEL = 0x00000080, // aka +4/-10
ECHOCAPS_DUMMY = 0x40000000, // Used for Indigo; indicates
// a dummy input or output
ECHOCAPS_DIGITAL = 0x80000000 // S/PDIF or ADAT connection
};
typedef struct tECHOGALS_CAPS
{
CHAR szName[ ECHO_MAXNAMELEN ]; // Name of this card
WORD wCardType; // Type of card
DWORD dwOutClockTypes; // Types of output clocks
DWORD dwInClockTypes; // Types of input clocks
DWORD dwDigitalModes; // Digital modes supported
BOOL fHasVmixer;
WORD wNumPipesOut;
WORD wNumPipesIn;
WORD wNumBussesOut;
WORD wNumBussesIn;
WORD wFirstDigitalBusOut; // Equal to wNumBussesOut if this card has
// no digital output busses
WORD wFirstDigitalBusIn; // Equal to wNumBussesIn if this card has
// no digital input busses
WORD wFirstDigitalPipeOut; // Works just like wFirstDigitalBus... above
WORD wFirstDigitalPipeIn;
DWORD dwPipeOutCaps[ ECHO_MAXAUDIOOUTPUTS ];
DWORD dwPipeInCaps[ ECHO_MAXAUDIOINPUTS ];
DWORD dwBusOutCaps[ ECHO_MAXAUDIOOUTPUTS ];
DWORD dwBusInCaps[ ECHO_MAXAUDIOINPUTS ];
WORD wNumMidiOut; // Number of MIDI out jacks
WORD wNumMidiIn; // Number of MIDI in jacks
} ECHOGALS_CAPS, *PECHOGALS_CAPS;
#endif // _ECHOGALSXFACE_
// end file EchoGalsXface.h

View File

@ -0,0 +1,348 @@
// ****************************************************************************
//
// MixerXface.H
//
// Include file for mixer interfacing with the EchoGals-derived classes.
//
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
// Prevent problems with multiple includes
#ifndef _MIXERXFACE_
#define _MIXERXFACE_
#include "EchoGalsXface.h"
//
// Gain ranges
//
#define ECHOGAIN_MUTED DSP_TO_GENERIC(-128) // Minimum possible gain
#define ECHOGAIN_MINOUT DSP_TO_GENERIC(-128) // Min output gain in dB
#define ECHOGAIN_MAXOUT DSP_TO_GENERIC(6) // Max output gain in dB
#define ECHOGAIN_MININP DSP_TO_GENERIC(-25) // Min input gain in dB
#define ECHOGAIN_MAXINP DSP_TO_GENERIC(25) // Max input gain in dB
#define ECHOGAIN_UPDATE 0xAAAAAA // Using this value means:
// Re-set the gain
// to the DSP using the
// currently stored value.
//=============================================================================
//
// Most of the mixer functions have been unified into a single interface;
// you pass either a single MIXER_FUNCTION struct or an array of MIXER_FUNCTION
// structs. Each MIXER_FUNCTION is generally used to set or get one or more
// values.
//
//=============================================================================
//
// Structure to specify a bus, pipe, or a monitor being routed from
// the input to the output
//
enum ECHO_CHANNEL_TYPES
{
ECHO_BUS_OUT = 0,
ECHO_BUS_IN,
ECHO_PIPE_OUT,
ECHO_PIPE_IN,
ECHO_MONITOR,
ECHO_NO_CHANNEL_TYPE = 0xffff,
ECHO_CHANNEL_UNUSED = 0xffff
};
typedef struct tMIXER_AUDIO_CHANNEL
{
WORD wCardId; // This field is obsolete
WORD wChannel; // channel index
DWORD dwType; // One of the above enums
} MIXER_AUDIO_CHANNEL, *PMIXER_AUDIO_CHANNEL;
//
// Output pipe control change
//
typedef struct
{
WORD wBusOut; // For cards without vmixer, should
// be the same as wChannel in MIXER_AUDIO_CHANNEL
union
{
INT32 iLevel; // New gain in dB X 256
INT32 iPan; // 0 <= new pan <= MAX_MIXER_PAN,
// 0 = full left MAX_MIXER_PAN = full right
BOOL bMuteOn; // To mute or not to mute
// MXF_GET_MONITOR_MUTE &
// MXF_SET_MONITOR_MUTE
} Data;
} MIXER_PIPE_OUT, PMIXER_PIPE_OUT;
//
// The MIXER_AUDIO_CHANNEL header has the card and input channel.
// This structure has the output channel and the gain, mute or pan
// state for one monitor.
//
typedef struct tMIXER_MONITOR
{
WORD wBusOut;
union
{
INT32 iLevel; // New gain in dB X 256
INT32 iPan; // 0 <= new pan <= MAX_MIXER_PAN,
// 0 = full left MAX_MIXER_PAN = full right
BOOL bMuteOn; // To mute or not to mute
// MXF_GET_MONITOR_MUTE &
// MXF_SET_MONITOR_MUTE
} Data;
} MIXER_MONITOR, *PMIXER_MONITOR;
//
// Mixer Function Tags
//
// These codes are used to specify the mixer function you want to perform;
// they determine which field in the Data union to use
//
#define MXF_GET_CAPS 1 // Get card capabilities
#define MXF_GET_LEVEL 2 // Get level for one channel
#define MXF_SET_LEVEL 3 // Set level for one channel
#define MXF_GET_NOMINAL 4 // Get nominal level for one channel
#define MXF_SET_NOMINAL 5 // Set nominal level for one channel
#define MXF_GET_MONITOR 6 // Get monitor for one channel
#define MXF_SET_MONITOR 7 // Set monitor for one channel
#define MXF_GET_INPUT_CLOCK 8 // Get input clock
#define MXF_SET_INPUT_CLOCK 9 // Set input clock for one card
#define MXF_GET_METERS 10 // Get meters for all channels on one card
#define MXF_GET_METERS_ON 11 // Get meters on state for one card
#define MXF_SET_METERS_ON 12 // Set meters on state for one card
// Meters must only be enabled while
// driver for card exists; the meters are
// written via bus mastering directly to memory
#define MXF_GET_PROF_SPDIF 13 // Get Professional or consumer S/PDIF mode
// for one card
#define MXF_SET_PROF_SPDIF 14 // Set Professional or consumer S/PDIF mode
// for one card
#define MXF_GET_MUTE 15 // Get mute state for one channel
#define MXF_SET_MUTE 16 // Set mute state for one channel
#define MXF_GET_MONITOR_MUTE 19 // Get monitor mute state for one channel
#define MXF_SET_MONITOR_MUTE 20 // Set monitor mute state for one channel
#define MXF_GET_MONITOR_PAN 23 // Get monitor pan value for one stereo channel
#define MXF_SET_MONITOR_PAN 24 // Set monitor pan value for one stereo channel
#define MXF_GET_FLAGS 27 // Get driver flags. i.e. S/PDIF no
// dither mode
#define MXF_SET_FLAGS 28 // Set driver flag. i.e. S/PDIF no
// dither mode
#define MXF_CLEAR_FLAGS 29 // Clear driver flag. i.e. S/PDIF no
// dither mode for one card
#define MXF_GET_SAMPLERATE_LOCK 30 // Get locked sample rate for one card
#define MXF_SET_SAMPLERATE_LOCK 31 // Set locked sample rate for one card
#define MXF_GET_SAMPLERATE 32 // Get actual sample rate for one card
#define MXF_GET_MIDI_IN_ACTIVITY 35 // Get MIDI in activity state
#define MXF_GET_MIDI_OUT_ACTIVITY 36 // Get MIDI out activity state
#define MXF_GET_DIGITAL_MODE 37 // Get digital mode
#define MXF_SET_DIGITAL_MODE 38 // Get digital mode
#define MXF_GET_PAN 39 // Get & set pan
#define MXF_SET_PAN 40
#define MXF_GET_OUTPUT_CLOCK 41 // Get output clock
#define MXF_SET_OUTPUT_CLOCK 42 // Set output clock for one card
#define MXF_GET_CLOCK_DETECT 43 // Get the currently detected clocks
#define MXF_GET_DIG_IN_AUTO_MUTE 44 // Get the state of the digital input auto-mute
#define MXF_SET_DIG_IN_AUTO_MUTE 45 // Set the state of the digital input auto-mute
//
// Mixer Function Data Structure
//
typedef struct tMIXER_FUNCTION
{
MIXER_AUDIO_CHANNEL Channel; // Which channel to service
INT32 iFunction; // What function to do
ECHOSTATUS RtnStatus; // Return Result
union
{
ECHOGALS_CAPS Capabilities; // MXF_GET_CAPS
INT32 iNominal; // MXF_GET_NOMINAL & MXF_SET_NOMINAL
INT32 iLevel; // MXF_GET_LEVEL & MXF_SET_LEVEL
MIXER_MONITOR Monitor; // MXF_GET_MONITOR & MXF_SET_MONITOR
// MXF_GET_MONITOR_MUTE & MXF_SET_MONITOR_MUTE
// MXF_GET_MONITOR_PAN & MXF_SET_MONITOR_PAN
WORD wClock; // MXF_GET_INPUT_CLOCK & MXF_SET_INPUT_CLOCK
// MXF_GET_OUTPUT_CLOCK & MXF_SET_OUTPUT_CLOCK
DWORD dwClockDetectBits;
// MXF_GET_CLOCK_DETECTs
ECHOGALS_METERS Meters; // MXF_GET_METERS
BOOL bMetersOn; // MXF_GET_METERS_ON &
// MXF_SET_METERS_ON
BOOL bProfSpdif; // MXF_GET_PROF_SPDIF &
// MXF_SET_PROF_SPDIF
BOOL bMuteOn; // MXF_GET_MUTE & MXF_SET_MUTE
BOOL bNotifyOn; // MXF_GET_NOTIFY_ON &
// MXF_SET_NOTIFY_ON
WORD wFlags; // MXF_GET_FLAGS, MXF_SET_FLAGS &
// MXF_CLEAR_FLAGS (See
// ECHOGALS_FLAG_??? in file
// EchoGalsXface.h)
DWORD dwLockedSampleRate;
// MXF_GET_SAMPLERATE_LOCK &
// MXF_SET_SAMPLERATE_LOCK
DWORD dwSampleRate; // MXF_GET_SAMPLERATE
BOOL bMidiActive; // MXF_GET_MIDI_IN_ACTIVITY &
// MXF_GET_MIDI_OUT_ACTIVITY
INT32 iDigMode; // MXF_GET_DIGITAL_MODE &
// MXF_SET_DIGITAL_MODE
MIXER_PIPE_OUT PipeOut; // MXF_GET_LEVEL & MXF_SET_LEVEL
// MXF_GET_MUTE & MXF_SET_MUTE
// MXF_GET_PAN & MXF_SET_PAN
BOOL fDigitalInAutoMute; // MXF_GET_DIG_IN_AUTO_MUTE
// MXF_SET_DIG_IN_AUTO_MUTE
} Data;
} MIXER_FUNCTION, *PMIXER_FUNCTION;
//
// Mixer Multifunction Interface
//
// Allow user to supply an array of commands to be performed in one call.
// Since this is a variable length structure, user beware!
//
typedef struct tMIXER_MULTI_FUNCTION
{
INT32 iCount;
MIXER_FUNCTION MixerFunction[ 1 ];
} MIXER_MULTI_FUNCTION, *PMIXER_MULTI_FUNCTION;
//
// Use this macro to size the data structure
//
#define ComputeMixerMultiFunctionSize(Ct) \
( sizeof( MIXER_MULTI_FUNCTION ) + ( sizeof( MIXER_FUNCTION ) * ( Ct - 1 ) ) )
//
// Notification
//
// Mixers allow for notification whenever a change occurs.
// Mixer notify structure contains channel and parameter(s) that
// changed.
//
//
// Mixer Parameter Changed definitions
//
#define MXN_LEVEL 0 // Level changed
#define MXN_NOMINAL 1 // Nominal level changed
#define MXN_INPUT_CLOCK 2 // Input clock changed
#define MXN_SPDIF 3 // S/PDIF - Professional mode changed
#define MXN_MUTE 4 // Mute state changed
#define MXN_PAN 6 // Pan value changed
#define MXN_FLAGS 12 // A driver flag changed. I.E.
// S/PDIF no dither state changed
#define MXN_DIGITAL_MODE 14 // Digital mode changed
#define MXN_OUTPUT_CLOCK 15 // Output clock changed
#define MXN_MAX 15 // Max notify parameters
typedef struct tMIXER_NOTIFY
{
WORD wType; // Same as enums used for MIXER_AUDIO_CHANNEL
union
{
WORD wBusIn;
WORD wPipeIn;
WORD wPipeOut;
} u;
WORD wBusOut; // For monitor & output pipe notifies only
WORD wParameter; // One of the above MXN_*
} MIXER_NOTIFY, *PMIXER_NOTIFY;
typedef struct tMIXER_MULTI_NOTIFY
{
DWORD dwCookie;
DWORD dwCount; // When passed to the generic driver,
// dwCount holds the size of the Notifies array.
// On returning from the driver, dwCount
// holds the number of entries in Notifies
// filled out by the generic driver.
MIXER_NOTIFY Notifies[1]; // Dynamic array; there are dwCount entries
} MIXER_MULTI_NOTIFY, *PMIXER_MULTI_NOTIFY;
//
// Max pan value
//
#define MAX_MIXER_PAN 1000 // this is pan hard right
//=============================================================================
//
// After designing eighteen or nineteen consoles for this hardware, we've
// learned that it's useful to be able to get all the following stuff at
// once. Typically the console will run a timer that fetchs this periodically.
//
// dwCookie is the unique ID for the mixer client; this is obtained by calling
// CEchoGals::OpenMixer. The generic driver will maintain a separate notify
// queue for each client.
//
// Meters and dwClockDetectBits are exactly the same as you would get if you
// did each of those mixer functions separately.
//
// dwNumPendingNotifies is how many notifies are in the queue associated with
// the cookie. You can use this number to create an array of MIXER_NOTIFY
// structures and call CEchoGals::GetControlChanges. This way you only check
// for control changes if the controls have actually changed.
//
//=============================================================================
typedef struct tECHO_POLLED_STUFF
{
DWORD dwCookie;
ECHOGALS_METERS Meters;
DWORD dwClockDetectBits;
DWORD dwNumPendingNotifies;
} ECHO_POLLED_STUFF;
#endif
// MixerXface.h

View File

@ -0,0 +1,430 @@
// ****************************************************************************
//
// OsSupportWDM.cpp
//
// Implementation file for WDM support services to the CEchoGals
// generic driver class.
//
// This will need to be rewritten for each new target OS.
//
// Set editor tabs to 3 for your viewing pleasure.
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#include "CEchoGals.h"
#include <stdarg.h>
#include <portcls.h>
/****************************************************************************
Byte swapping for supporting big endian machines; obviously, this isn't
needed since this is OsSupportWDM. This is just here as an example
for those who wish to develop for big endian machines.
****************************************************************************/
#ifdef BIG_ENDIAN_HOST
#pragma warning( disable : 4035 )
WORD SwapBytesShort
(
WORD wIn
)
{
_asm mov AX, wIn
_asm bswap EAX
_asm shr EAX,16
}
DWORD SwapBytesLong
(
DWORD dwIn
)
{
_asm mov EAX, dwIn
_asm bswap EAX
}
WORD SwapBytes
(
WORD wIn // 16 bit quantity to swap
)
{
return( SwapBytesShort( wIn ) );
}
DWORD SwapBytes
(
DWORD dwIn // 32 bit quantity to swap
)
{
return( SwapBytesLong( dwIn ) );
}
#endif // BIG_ENDIAN_HOST
/****************************************************************************
Memory management - not part of COsSupport
****************************************************************************/
//===========================================================================
//
// Init the memory tracking counter; right now, this just uses a simple
// scheme that tracks the number of allocations
//
//===========================================================================
DWORD gdwAllocNonPagedCount = 0;
void OsAllocateInit()
{
gdwAllocNonPagedCount = 0;
} // OsAllocateInit
//===========================================================================
//
// OsAllocateNonPaged is used to allocate a block of memory that will always
// be resident; that is, this particular block of memory won't be swapped
// out as virtual memory and can always be accessed at interrupt time.
//
// gdwAllocNonPagedCount tracks the number of times this has been
// successfully called.
//
// This is primarily used for overloading the new operator for the various
// generic classes.
//
//===========================================================================
ECHOSTATUS OsAllocateNonPaged
(
DWORD dwByteCt, // Block size in bytes
PPVOID ppMemAddr // Where to return memory ptr
)
{
ASSERT( DISPATCH_LEVEL >= KeGetCurrentIrql() );
*ppMemAddr = ExAllocatePoolWithTag( NonPagedPool, dwByteCt, ECHO_POOL_TAG );
if ( NULL == *ppMemAddr )
{
ECHO_DEBUGPRINTF( ("OsAllocateNonPaged : Failed on %d bytes\n",
dwByteCt) );
ECHO_DEBUGBREAK();
return ECHOSTATUS_NO_MEM;
}
RtlZeroMemory( *ppMemAddr, dwByteCt );
gdwAllocNonPagedCount++;
ECHO_DEBUGPRINTF(("gdwAllocNonPagedCount %d\n",gdwAllocNonPagedCount));
return ECHOSTATUS_OK;
} // ECHOSTATUS OsAllocateNonPaged
//===========================================================================
//
// OsFreeNonPaged is used to free memory allocated by OsAllocateNonPaged.
//
// gdwAllocNonPagedCount tracks the number of times this has been
// successfully called.
//
//===========================================================================
ECHOSTATUS OsFreeNonPaged
(
PVOID pMemAddr
)
{
ASSERT( DISPATCH_LEVEL >= KeGetCurrentIrql() );
ExFreePool( pMemAddr );
gdwAllocNonPagedCount--;
ECHO_DEBUGPRINTF(("gdwAllocNonPagedCount %d\n",gdwAllocNonPagedCount));
return ECHOSTATUS_OK;
} // ECHOSTATUS OsFreeNonPaged
//***********************************************************************
//
// This class is uniquely defined for each OS. It provides
// information that other components may require.
//
// For example, in Windows NT it contains a device object used by various
// memory management methods.
//
// An instance of this class must be constructed and initialized prior to
// constructing the CEchoGals derived object. The CEchoGals and
// CDspCommObject classes must have access to it during their respective
// construction times.
//
//***********************************************************************
//===========================================================================
//
// Construction/destruction
//
//===========================================================================
COsSupport::COsSupport
(
DWORD dwDeviceId // PCI bus subsystem ID
)
{
KeQuerySystemTime( (PLARGE_INTEGER) &m_ullStartTime );
// All system time calls relative to this
m_dwDeviceId = dwDeviceId;
} // COsSupport::COsSupport()
COsSupport::~COsSupport()
{
} // COsSupport::~COsSupport()
//===========================================================================
//
// Timer methods
//
//===========================================================================
//---------------------------------------------------------------------------
//
// Return the system time in microseconds.
// Return error status if the OS doesn't support this function.
//
//---------------------------------------------------------------------------
ECHOSTATUS COsSupport::OsGetSystemTime
(
PULONGLONG pullTime // Where to return system time
)
{
KeQuerySystemTime( (PLARGE_INTEGER) pullTime );
*pullTime /= 10;
return ECHOSTATUS_OK;
} // ECHOSTATUS COsSupport::OsGetSystemTime
//---------------------------------------------------------------------------
//
// Stall execution for dwTime microseconds.
// Return error status if the OS doesn't support this
// function.
//
//---------------------------------------------------------------------------
ECHOSTATUS COsSupport::OsSnooze
(
DWORD dwTime // Duration in micro seconds
)
{
LARGE_INTEGER Interval;
if ( KeGetCurrentIrql() < DISPATCH_LEVEL )
{
//
// Use negative number to express relative time.
// Convert micro seconds into 100 nano second units
//
Interval.QuadPart = -( (LONGLONG) dwTime * 10 );
KeDelayExecutionThread( KernelMode, FALSE, &Interval );
}
else
{
//
// This is very nasty, but we have no choice
//
KeStallExecutionProcessor( dwTime );
}
return ECHOSTATUS_OK;
} // ECHOSTATUS COsSupport::OsSnooze
//===========================================================================
//
// More memory management
//
//===========================================================================
//---------------------------------------------------------------------------
//
// Allocate locked, non-pageable, physically contiguous memory pages
// in the drivers address space. Used to allocate memory for the DSP
// communications area.
//
// Currently, none of the generic code ever sets dwPageCt to higher than
// one. On the platforms we've developed for so far, a page is 4096
// bytes and is aligned on a 4096 byte boundary. None of the structures
// allocated by OsPageAllocate are more than 4096 bytes; memory
// allocated by this routine should be at least aligned on a 32 byte
// boundary and be physically contiguous.
//
// Note that this code is not 64 bit ready, since it's only using
// the low 32 bits of the physical address.
//
//---------------------------------------------------------------------------
ECHOSTATUS COsSupport::OsPageAllocate
(
DWORD dwPageCt, // How many pages to allocate
PPVOID ppPageAddr, // Where to return the memory ptr
PPHYS_ADDR pPhysicalPageAddr // Where to return the physical PCI address
)
{
PHYSICAL_ADDRESS LogicalAddress;
ASSERT( DISPATCH_LEVEL >= KeGetCurrentIrql() );
*ppPageAddr = ExAllocatePoolWithTag(NonPagedPool,
PAGE_SIZE * dwPageCt,
'OHCE');
if (NULL != *ppPageAddr)
{
PHYSICAL_ADDRESS PhysTemp;
PhysTemp = MmGetPhysicalAddress(*ppPageAddr);
*pPhysicalPageAddr = PhysTemp.LowPart;
}
RtlZeroMemory( *ppPageAddr, dwPageCt * PAGE_SIZE );
return ECHOSTATUS_OK;
} // ECHOSTATUS COsSupport::OsPageAllocate
//---------------------------------------------------------------------------
//
// Unlock and free non-pageable, physically contiguous memory pages in
// the drivers address space; the inverse of OsPageAllocate
//
//---------------------------------------------------------------------------
ECHOSTATUS COsSupport::OsPageFree
(
DWORD dwPageCt, // How many pages to free
PVOID pPageAddr, // Virtual memory ptr
PHYS_ADDR PhysicalPageAddr // Physical PCI addr
)
{
PHYSICAL_ADDRESS LogicalAddress;
ASSERT( DISPATCH_LEVEL >= KeGetCurrentIrql() );
if (NULL == pPageAddr)
return ECHOSTATUS_OK;
ExFreePool(pPageAddr);
return ECHOSTATUS_OK;
} // ECHOSTATUS COsSupport::OsPageFree
//---------------------------------------------------------------------------
//
// Display an error message w/title; currently not supported under WDM.
//
//---------------------------------------------------------------------------
void COsSupport::EchoErrorMsg
(
PCHAR pszMsg,
PCHAR pszTitle
)
{
} // void COsSupport::EchoErrorMsg( PCHAR )
//---------------------------------------------------------------------------
//
// Overload new & delete so memory for this object is allocated from
// non-paged memory.
//
//---------------------------------------------------------------------------
PVOID COsSupport::operator new( size_t Size )
{
PVOID pMemory;
ECHOSTATUS Status;
Status = OsAllocateNonPaged(Size,&pMemory);
if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
{
ECHO_DEBUGPRINTF(("COsSupport::operator new - memory allocation failed\n"));
pMemory = NULL;
}
else
{
memset( pMemory, 0, Size );
}
return pMemory;
} // PVOID COsSupport::operator new( size_t Size )
VOID COsSupport::operator delete( PVOID pVoid )
{
if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
{
ECHO_DEBUGPRINTF(("COsSupport::operator delete "
"memory free failed\n"));
}
} // VOID COsSupport::operator delete( PVOID pVoid )

View File

@ -0,0 +1,289 @@
// ****************************************************************************
//
// OsSupportWDM.H
//
// Include file for WDM Support Services to the CEchoGals
// generic driver class
//
// Set editor tabs to 3 for your viewing pleasure.
//
// ----------------------------------------------------------------------------
//
// Copyright Echo Digital Audio Corporation (c) 1998 - 2002
// All rights reserved
// www.echoaudio.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Echo Digital Audio, nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// ****************************************************************************
#ifdef _DEBUG
#pragma optimize("",off)
#endif
// Prevent problems with multiple includes
#ifndef _ECHOOSSUPPORTWDM_
#define _ECHOOSSUPPORTWDM_
extern "C"
{
#include <wdm.h>
#include <stdio.h>
#include <windef.h>
#include <portcls.h>
// hack - I have to do this- this prototype only
// shows up in ntddk.h, but wdm.h prevents ntddk.h
// from compiling... mattg
NTKERNELAPI
PHYSICAL_ADDRESS
MmGetPhysicalAddress (
IN PVOID BaseAddress
);
}
#ifdef _DEBUG
extern "C"
{
// WDM debug printf macro
//#define ECHO_DEBUGPRINTF( strings ) DbgPrint##strings
#define ECHO_DEBUGPRINTF( strings )
//#define ECHO_DEBUGBREAK()
#define ECHO_DEBUGBREAK() _asm int 3;
#define ECHO_DEBUG
}
#else
#define ECHO_DEBUGPRINTF( strings )
#define ECHO_DEBUGBREAK()
#endif
//
// Specify OS specific types
//
typedef void ** PPVOID;
typedef signed char INT8;
//
// Return Status Values
//
typedef unsigned long ECHOSTATUS;
//
// Define generic byte swapping functions
//
#ifdef BIG_ENDIAN_HOST
WORD SwapBytes( WORD dwIn );
DWORD SwapBytes( DWORD dwIn );
#define SWAP(x) SwapBytes( x )
#else
#define SWAP(x) x
#endif
//
// Define what a physical address is on this OS
//
typedef unsigned long PHYS_ADDR; // Define physical addr type
typedef unsigned long * PPHYS_ADDR; // Define physical addr pointer type
//
// Global Memory Management Functions
//
//
// This tag is used to mark all memory allocated by EchoGals.
// Due to the way PoolMon displays things, we spell Echo backwards
// so it displays correctly.
//
#define ECHO_POOL_TAG 'OHCE'
//
// OsAllocateInit - Set up memory tracking. Call this once - not
// once per PCI card, just one time.
//
void OsAllocateInit();
//
// Allocate locked, non-pageable block of memory. Does not have to be
// physically contiguous. Primarily used to implement the overloaded
// new operator for classes that must remain memory resident.
//
ECHOSTATUS OsAllocateNonPaged
(
DWORD dwByteCt,
PPVOID ppMemAddr
);
//
// Unlock and free, non-pageable block of memory.
//
ECHOSTATUS OsFreeNonPaged
(
PVOID pMemAddr
);
//
// Copy memory
//
#define OsCopyMemory(pDest,pSrc,dwBytes) RtlCopyMemory(pDest,pSrc,dwBytes)
//
// Set memory to zero
//
#define OsZeroMemory(pDest,dwBytes) RtlZeroMemory(pDest,dwBytes)
//
// This class is uniquely defined for each OS. It provides
// information that other components may require.
// For example, in Windows NT it contains a device object used by various
// memory management methods.
// Since static variables are used in place of globals, an instance must
// be constructed and initialized by the OS Interface object prior to
// constructing the CEchoGals derived object. The CEchoGals and
// CDspCommObject classes must have access to it during their respective
// construction times.
//
class COsSupport
{
public:
//
// Construction/destruction
//
COsSupport
(
DWORD dwDeviceId // PCI bus device id
);
~COsSupport();
//
// Timer Methods
//
//
// Return the system time in microseconds.
// Return error status if the OS doesn't support this function.
//
ECHOSTATUS OsGetSystemTime
(
PULONGLONG pullTime
);
//
// Stall execution for dwTime microseconds.
// Return error status if the OS doesn't support this function.
//
ECHOSTATUS OsSnooze
(
DWORD dwTime
);
//
// Memory Management Methods
//
//
// Allocate locked, non-pageable, physically contiguous memory pages
// in the drivers address space. Used to allocate memory for the DSP
// communications area and Ducks.
//
ECHOSTATUS OsPageAllocate
(
DWORD dwPageCt, // How many pages to allocate
PPVOID ppPageAddr, // Where to return the memory ptr
PPHYS_ADDR pPhysicalPageAddr // Where to return the physical PCI addr
);
//
// Unlock and free non-pageable, physically contiguous memory pages
// in the drivers address space.
// Used to free memory for the DSP communications area and Ducks.
//
ECHOSTATUS OsPageFree
(
DWORD dwPageCt, // How many pages to free
PVOID pPageAddr, // Virtual memory ptr
PHYS_ADDR PhysicalPageAddr // Physical PCI addr
);
//
// Add additional methods here
//
//
// Display and/or log an error message w/title
//
void EchoErrorMsg
(
PCHAR pszMsg,
PCHAR pszTitle
);
//
// Return PCI card device ID
//
DWORD GetDeviceId()
{ return( m_dwDeviceId ); }
//
// Overload new & delete so memory for this object is allocated
// from non-paged memory.
//
PVOID operator new( size_t Size );
VOID operator delete( PVOID pVoid );
protected:
private:
DWORD m_dwDeviceId; // PCI Device ID
//
// Define data here.
//
KIRQL m_IrqlCurrent; // Old IRQ level
ULONGLONG m_ullStartTime; // All system time relative to this time
class CPtrQueue * m_pPtrQue; // Store read only ptrs so they
// can be unmapped
}; // class COsSupport
typedef COsSupport * PCOsSupport;
#endif // _ECHOOSSUPPORTWDM_

View File

@ -0,0 +1,94 @@
/********************************************************************************
*
* family.h
*
* This header file deals with variations between the different families of
* products. Current families:
*
* Echogals - Darla20, Gina20, Layla20, and Darla24
* Echo24 - Gina24, Layla24, Mona, and Mia
*
* ----------------------------------------------------------------------------
*
* Copyright Echo Digital Audio Corporation (c) 1998 - 2002
* All rights reserved
* www.echoaudio.com
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal with the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimers.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Echo Digital Audio, nor the names of its
* contributors may be used to endorse or promote products derived from
* this Software without specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
*
*
********************************************************************************/
#ifndef _FAMILY_H_
#define _FAMILY_H_
//===========================================================================
//
// Echogals
//
// To build an Echogals driver, make sure and #define ECHOGALS_FAMILY
//
//===========================================================================
#ifdef ECHOGALS_FAMILY
#define MIDI_SUPPORT
#define NUM_ASIC_TESTS 5
#define READ_DSP_TIMEOUT 1000000L // one second
#endif // ECHOGALS_FAMILY
//===========================================================================
//
// Echo24
//
// To build an Echo24 driver, make sure and #define ECHO24_FAMILY
//
//===========================================================================
#ifdef ECHO24_FAMILY
#define MIDI_SUPPORT
#define DSP_56361 // Some Echo24 cards use the 56361 DSP
#define DIGITAL_INPUT_AUTO_MUTE_SUPPORT // Gina24, Layla24, and Mona
#define NUM_ASIC_TESTS 1
#define READ_DSP_TIMEOUT 100000L // .1 second
#define STEREO_BIG_ENDIAN32_SUPPORT
#endif // ECHO24_FAMILY
#endif // _FAMILY_H_

View File

@ -0,0 +1,30 @@
Copyright (c) 2002 Echo Digital Audio
All rights reserved.
www.echoaudio.com
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal with the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimers.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
- Neither the name of Echo Digital Audio, nor the names of its
contributors may be used to endorse or promote products derived from
this Software without specific prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.