1189251Ssam// **************************************************************************** 2189251Ssam// 3189251Ssam// CMia.cpp 4189251Ssam// 5252726Srpaulo// Implementation file for the CMia driver class. 6252726Srpaulo// Set editor tabs to 3 for your viewing pleasure. 7189251Ssam// 8189251Ssam// ---------------------------------------------------------------------------- 9189251Ssam// 10189251Ssam// This file is part of Echo Digital Audio's generic driver library. 11189251Ssam// Copyright Echo Digital Audio Corporation (c) 1998 - 2005 12214734Srpaulo// All rights reserved 13252726Srpaulo// www.echoaudio.com 14189251Ssam// 15189251Ssam// This library is free software; you can redistribute it and/or 16189251Ssam// modify it under the terms of the GNU Lesser General Public 17189251Ssam// License as published by the Free Software Foundation; either 18189251Ssam// version 2.1 of the License, or (at your option) any later version. 19189251Ssam// 20189251Ssam// This library is distributed in the hope that it will be useful, 21189251Ssam// but WITHOUT ANY WARRANTY; without even the implied warranty of 22189251Ssam// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23189251Ssam// Lesser General Public License for more details. 24189251Ssam// 25189251Ssam// You should have received a copy of the GNU Lesser General Public 26189251Ssam// License along with this library; if not, write to the Free Software 27189251Ssam// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28189251Ssam// 29189251Ssam// **************************************************************************** 30189251Ssam 31189251Ssam#include "CMia.h" 32189251Ssam 33189251Ssam#define MIA_ANALOG_OUTPUT_LATENCY 63 34189251Ssam#define MIA_ANALOG_INPUT_LATENCY 62 35189251Ssam 36189251Ssam 37189251Ssam 38189251Ssam/**************************************************************************** 39189251Ssam 40189251Ssam Construction and destruction 41189251Ssam 42189251Ssam ****************************************************************************/ 43189251Ssam 44189251Ssam//=========================================================================== 45189251Ssam// 46189251Ssam// Overload new & delete so memory for this object is allocated 47189251Ssam// from non-paged memory. 48189251Ssam// 49189251Ssam//=========================================================================== 50189251Ssam 51189251SsamPVOID CMia::operator new( size_t Size ) 52189251Ssam{ 53189251Ssam PVOID pMemory; 54189251Ssam ECHOSTATUS Status; 55189251Ssam 56189251Ssam Status = OsAllocateNonPaged(Size,&pMemory); 57189251Ssam 58189251Ssam if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory )) 59189251Ssam { 60189251Ssam ECHO_DEBUGPRINTF(("CMia::operator new - memory allocation failed\n")); 61189251Ssam 62189251Ssam pMemory = NULL; 63189251Ssam } 64189251Ssam else 65189251Ssam { 66189251Ssam memset( pMemory, 0, Size ); 67189251Ssam } 68189251Ssam 69189251Ssam return pMemory; 70189251Ssam 71189251Ssam} // PVOID CMia::operator new( size_t Size ) 72189251Ssam 73189251Ssam 74189251SsamVOID CMia::operator delete( PVOID pVoid ) 75189251Ssam{ 76189251Ssam if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) ) 77189251Ssam { 78189251Ssam ECHO_DEBUGPRINTF(("CMia::operator delete memory free failed\n")); 79189251Ssam } 80189251Ssam} // VOID CMia::operator delete( PVOID pVoid ) 81189251Ssam 82189251Ssam 83189251Ssam//=========================================================================== 84189251Ssam// 85189251Ssam// Constructor and destructor 86189251Ssam// 87189251Ssam//=========================================================================== 88189251Ssam 89189251SsamCMia::CMia( PCOsSupport pOsSupport ) 90189251Ssam : CEchoGalsVmixer( pOsSupport ) 91189251Ssam{ 92189251Ssam ECHO_DEBUGPRINTF( ( "CMia::CMia() is born!\n" ) ); 93189251Ssam 94189251Ssam // 95189251Ssam // Mia's virtual outputs make things tricky, since a pipe can 96189251Ssam // go to either bus. 97189251Ssam // 98189251Ssam m_wAnalogOutputLatency = MIA_ANALOG_OUTPUT_LATENCY; 99189251Ssam m_wAnalogInputLatency = MIA_ANALOG_INPUT_LATENCY; 100189251Ssam 101189251Ssam} 102189251Ssam 103189251SsamCMia::~CMia() 104189251Ssam{ 105189251Ssam ECHO_DEBUGPRINTF( ( "CMia::~CMia() is toast!\n" ) ); 106189251Ssam} 107189251Ssam 108189251Ssam 109189251Ssam 110189251Ssam 111189251Ssam/**************************************************************************** 112189251Ssam 113189251Ssam Setup and hardware initialization 114189251Ssam 115189251Ssam ****************************************************************************/ 116189251Ssam 117189251Ssam//=========================================================================== 118189251Ssam// 119189251Ssam// Every card has an InitHw method 120189251Ssam// 121189251Ssam//=========================================================================== 122189251Ssam 123189251SsamECHOSTATUS CMia::InitHw() 124189251Ssam{ 125189251Ssam ECHOSTATUS Status; 126189251Ssam WORD i; 127189251Ssam 128189251Ssam // 129189251Ssam // Call the base method 130189251Ssam // 131189251Ssam if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) ) 132189251Ssam return Status; 133189251Ssam 134189251Ssam // 135189251Ssam // Create the DSP comm object 136337817Scy // 137189251Ssam ECHO_ASSERT(NULL == m_pDspCommObject ); 138189251Ssam m_pDspCommObject = new CMiaDspCommObject( (PDWORD) m_pvSharedMemory, 139189251Ssam m_pOsSupport ); 140189251Ssam if (NULL == m_pDspCommObject) 141189251Ssam { 142189251Ssam ECHO_DEBUGPRINTF(("CMia::InitHw - could not create DSP comm object\n")); 143189251Ssam return ECHOSTATUS_NO_MEM; 144189251Ssam } 145189251Ssam 146189251Ssam // 147189251Ssam // Load the DSP 148189251Ssam // 149189251Ssam GetDspCommObject()->LoadFirmware(); 150189251Ssam if ( GetDspCommObject()->IsBoardBad() ) 151189251Ssam return ECHOSTATUS_DSP_DEAD; 152189251Ssam 153189251Ssam // 154189251Ssam // Clear the "bad board" flag; set the flags to indicate that 155189251Ssam // Mia can handle super-interleave. 156189251Ssam // 157189251Ssam m_wFlags &= ~ECHOGALS_FLAG_BADBOARD; 158189251Ssam m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK; 159189251Ssam 160189251Ssam // 161189251Ssam // Must call this here after DSP is init to 162189251Ssam // init gains and mutes 163189251Ssam // 164189251Ssam Status = InitLineLevels(); 165189251Ssam if ( ECHOSTATUS_OK != Status ) 166189251Ssam return Status; 167189251Ssam 168189251Ssam // 169189251Ssam // Set defaults for +4/-10 170189251Ssam // 171189251Ssam for (i = 0; i < GetFirstDigitalBusOut(); i++ ) 172189251Ssam { 173189251Ssam GetDspCommObject()-> 174189251Ssam SetNominalLevel( i, FALSE ); // FALSE is +4 here 175189251Ssam } 176189251Ssam for ( i = 0; i < GetFirstDigitalBusIn(); i++ ) 177189251Ssam { 178189251Ssam GetDspCommObject()-> 179189251Ssam SetNominalLevel( GetNumBussesOut() + i, FALSE ); 180189251Ssam } 181189251Ssam 182189251Ssam // 183189251Ssam // Set the digital mode to S/PDIF RCA 184189251Ssam // 185189251Ssam SetDigitalMode( DIGITAL_MODE_SPDIF_RCA ); 186189251Ssam 187189251Ssam // 188189251Ssam // Get default sample rate from DSP 189189251Ssam // 190189251Ssam m_dwSampleRate = GetDspCommObject()->GetSampleRate(); 191189251Ssam 192189251Ssam // 193189251Ssam // Is this a Mia MIDI card? 194189251Ssam // 195189251Ssam if (MIA_MIDI_REV == m_pOsSupport->GetCardRev()) 196189251Ssam { 197189251Ssam Status = m_MidiIn.Init( this ); 198189251Ssam } 199189251Ssam 200189251Ssam 201189251Ssam ECHO_DEBUGPRINTF( ( "CMia::InitHw()\n" ) ); 202189251Ssam return Status; 203189251Ssam 204189251Ssam} // ECHOSTATUS CMia::InitHw() 205189251Ssam 206189251Ssam 207189251Ssam 208189251Ssam 209189251Ssam/**************************************************************************** 210189251Ssam 211189251Ssam Informational methods 212189251Ssam 213189251Ssam ****************************************************************************/ 214189251Ssam 215189251Ssam//=========================================================================== 216189251Ssam// 217189251Ssam// Override GetCapabilities to enumerate unique capabilties for this card 218189251Ssam// 219189251Ssam//=========================================================================== 220189251Ssam 221189251SsamECHOSTATUS CMia::GetCapabilities 222189251Ssam( 223189251Ssam PECHOGALS_CAPS pCapabilities 224337817Scy) 225189251Ssam{ 226189251Ssam ECHOSTATUS Status; 227189251Ssam WORD i; 228189251Ssam 229189251Ssam Status = GetBaseCapabilities(pCapabilities); 230189251Ssam if ( ECHOSTATUS_OK != Status ) 231189251Ssam return Status; 232189251Ssam 233189251Ssam // 234189251Ssam // Add nominal level control to analog ins & outs 235189251Ssam // 236189251Ssam for (i = 0 ; i < GetFirstDigitalBusOut(); i++) 237189251Ssam { 238189251Ssam pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; 239189251Ssam } 240189251Ssam 241189251Ssam for (i = 0 ; i < GetFirstDigitalBusIn(); i++) 242189251Ssam { 243189251Ssam pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; 244189251Ssam } 245189251Ssam 246189251Ssam pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_SPDIF; 247189251Ssam pCapabilities->dwOutClockTypes = 0; 248189251Ssam 249189251Ssam return Status; 250189251Ssam 251189251Ssam} // ECHOSTATUS CMia::GetCapabilities 252189251Ssam 253189251Ssam 254189251Ssam//=========================================================================== 255189251Ssam// 256189251Ssam// QueryAudioSampleRate is used to find out if this card can handle a 257189251Ssam// given sample rate. 258189251Ssam// 259337817Scy//=========================================================================== 260189251Ssam 261189251SsamECHOSTATUS CMia::QueryAudioSampleRate 262189251Ssam( 263189251Ssam DWORD dwSampleRate 264189251Ssam) 265189251Ssam{ 266189251Ssam if ( dwSampleRate != 32000 && 267189251Ssam dwSampleRate != 44100 && 268189251Ssam dwSampleRate != 48000 && 269189251Ssam dwSampleRate != 88200 && 270189251Ssam dwSampleRate != 96000 ) 271189251Ssam { 272189251Ssam ECHO_DEBUGPRINTF( 273189251Ssam ("CMia::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) ); 274189251Ssam return ECHOSTATUS_BAD_FORMAT; 275189251Ssam } 276189251Ssam 277189251Ssam ECHO_DEBUGPRINTF( ( "CMia::QueryAudioSampleRate()\n" ) ); 278189251Ssam return ECHOSTATUS_OK; 279189251Ssam 280189251Ssam} // ECHOSTATUS CMia::QueryAudioSampleRate 281189251Ssam 282189251Ssam 283189251Ssamvoid CMia::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate) 284189251Ssam{ 285189251Ssam dwMinRate = 32000; 286189251Ssam dwMaxRate = 96000; 287189251Ssam} 288189251Ssam 289189251Ssam 290189251Ssam 291189251Ssam//=========================================================================== 292189251Ssam// 293189251Ssam// GetInputClockDetect returns a bitmask consisting of all the input 294189251Ssam// clocks currently connected to the hardware; this changes as the user 295189251Ssam// connects and disconnects clock inputs. 296189251Ssam// 297189251Ssam// You should use this information to determine which clocks the user is 298189251Ssam// allowed to select. 299189251Ssam// 300189251Ssam// Mia supports S/PDIF input clock. 301189251Ssam// 302189251Ssam//=========================================================================== 303189251Ssam 304189251SsamECHOSTATUS CMia::GetInputClockDetect(DWORD &dwClockDetectBits) 305189251Ssam{ 306189251Ssam //ECHO_DEBUGPRINTF(("CMia::GetInputClockDetect\n")); 307189251Ssam 308189251Ssam if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() ) 309189251Ssam { 310189251Ssam //ECHO_DEBUGPRINTF( ("CMia::GetInputClockDetect: DSP Dead!\n") ); 311189251Ssam return ECHOSTATUS_DSP_DEAD; 312189251Ssam } 313189251Ssam 314189251Ssam // 315189251Ssam // Map the DSP clock detect bits to the generic driver clock detect bits 316189251Ssam // 317189251Ssam DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect(); 318189251Ssam 319189251Ssam dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL; 320189251Ssam 321189251Ssam if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SPDIF)) 322189251Ssam dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF; 323189251Ssam 324189251Ssam return ECHOSTATUS_OK; 325189251Ssam 326189251Ssam} // GetInputClockDetect 327189251Ssam 328189251Ssam 329189251Ssam 330189251Ssam// *** Mia.cpp *** 331189251Ssam