1 // **************************************************************************** 2 // 3 // CGdDspCommObject.cpp 4 // 5 // Implementation file for Gina20/Darla20 DSP interface class. 6 // 7 // Darla20 and Gina20 are very similar; this class is used for both. 8 // CGinaDspCommObject and CDarlaDspCommObject dervie from this class, in 9 // turn. 10 // 11 // ---------------------------------------------------------------------------- 12 // 13 // This file is part of Echo Digital Audio's generic driver library. 14 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005 15 // All rights reserved 16 // www.echoaudio.com 17 // 18 // This library is free software; you can redistribute it and/or 19 // modify it under the terms of the GNU Lesser General Public 20 // License as published by the Free Software Foundation; either 21 // version 2.1 of the License, or (at your option) any later version. 22 // 23 // This library is distributed in the hope that it will be useful, 24 // but WITHOUT ANY WARRANTY; without even the implied warranty of 25 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 26 // Lesser General Public License for more details. 27 // 28 // You should have received a copy of the GNU Lesser General Public 29 // License along with this library; if not, write to the Free Software 30 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 31 // 32 // **************************************************************************** 33 34 #include "CEchoGals.h" 35 #include "CGinaDspCommObject.h" 36 37 38 /**************************************************************************** 39 40 Construction and destruction 41 42 ****************************************************************************/ 43 44 //=========================================================================== 45 // 46 // Constructor 47 // 48 //=========================================================================== 49 50 CGdDspCommObject::CGdDspCommObject 51 ( 52 PDWORD pdwRegBase, // Virtual ptr to DSP registers 53 PCOsSupport pOsSupport 54 ) : CDspCommObject( pdwRegBase, pOsSupport ) 55 { 56 57 m_byGDCurrentSpdifStatus = GD_SPDIF_STATUS_UNDEF; 58 m_byGDCurrentClockState = GD_CLOCK_UNDEF; 59 60 } // CGdDspCommObject::CGinaDspCommObject( DWORD dwPhysRegBase ) 61 62 63 //=========================================================================== 64 // 65 // Destructor 66 // 67 //=========================================================================== 68 69 CGdDspCommObject::~CGdDspCommObject() 70 { 71 } // CGdDspCommObject::~CGdDspCommObject() 72 73 74 75 76 /**************************************************************************** 77 78 Hardware config 79 80 ****************************************************************************/ 81 82 //=========================================================================== 83 // 84 // Called after LoadFirmware to restore old gains, meters on, monitors, etc. 85 // No error checking is done here. 86 // 87 //=========================================================================== 88 89 void CGdDspCommObject::RestoreDspSettings() 90 { 91 92 m_pDspCommPage->byGDClockState = GD_CLOCK_UNDEF; 93 m_pDspCommPage->byGDSpdifStatus = GD_SPDIF_STATUS_UNDEF; 94 95 CDspCommObject::RestoreDspSettings(); 96 97 } // void CGdDspCommObject::RestoreDspSettings() 98 99 100 //=========================================================================== 101 // 102 // SetSampleRate 103 // 104 // Set the audio sample rate for Gina/Darla 105 // 106 // For Gina and Darla, three parameters need to be set: the resampler state, 107 // the clock state, and the S/PDIF output status state. The idea is that 108 // these parameters are changed as infrequently as possible. 109 // 110 // Resampling is no longer supported. 111 // 112 //=========================================================================== 113 114 DWORD CGdDspCommObject::SetSampleRate( DWORD dwNewSampleRate ) 115 { 116 BYTE byGDClockState, byGDSpdifStatus; 117 DWORD fUseSpdifInClock; 118 119 if ( !WaitForHandshake() ) 120 return ECHOSTATUS_DSP_DEAD; 121 122 // 123 // Pick the clock 124 // 125 fUseSpdifInClock = (GetCardType() == GINA) && 126 (GetInputClock() == ECHO_CLOCK_SPDIF); 127 if (fUseSpdifInClock) 128 { 129 byGDClockState = GD_CLOCK_SPDIFIN; 130 } 131 else 132 { 133 switch (dwNewSampleRate) 134 { 135 case 44100 : 136 byGDClockState = GD_CLOCK_44; 137 break; 138 139 case 48000 : 140 byGDClockState = GD_CLOCK_48; 141 break; 142 143 default : 144 byGDClockState = GD_CLOCK_NOCHANGE; 145 break; 146 } 147 } 148 149 if ( m_byGDCurrentClockState == byGDClockState ) 150 { 151 byGDClockState = GD_CLOCK_NOCHANGE; 152 } 153 154 // 155 // Select S/PDIF output status 156 // 157 byGDSpdifStatus = SelectGinaDarlaSpdifStatus( dwNewSampleRate ); 158 159 // 160 // Write the audio state to the comm page 161 // 162 m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate ); 163 m_pDspCommPage->byGDClockState = byGDClockState; 164 m_pDspCommPage->byGDSpdifStatus = byGDSpdifStatus; 165 m_pDspCommPage->byGDResamplerState = 3; // magic number - 166 // should always be 3 167 168 // 169 // Send command to DSP 170 // 171 ClearHandshake(); 172 SendVector( DSP_VC_SET_GD_AUDIO_STATE ); 173 174 // 175 // Save the new audio state 176 // 177 if ( byGDClockState != GD_CLOCK_NOCHANGE ) 178 m_byGDCurrentClockState = byGDClockState; 179 180 if ( byGDSpdifStatus != GD_SPDIF_STATUS_NOCHANGE ) 181 m_byGDCurrentSpdifStatus = byGDSpdifStatus; 182 183 return dwNewSampleRate; 184 185 } // DWORD CGdDspCommObject::SetSampleRate( DWORD dwNewSampleRate ) 186 187 188 //=========================================================================== 189 // 190 // SelectGinaDarlaSpdifStatus 191 // 192 //=========================================================================== 193 194 BYTE CGdDspCommObject::SelectGinaDarlaSpdifStatus( DWORD dwNewSampleRate ) 195 { 196 BYTE byNewStatus = 0; 197 198 switch (dwNewSampleRate) 199 { 200 case 44100 : 201 byNewStatus = GD_SPDIF_STATUS_44; 202 break; 203 204 case 48000 : 205 byNewStatus = GD_SPDIF_STATUS_48; 206 break; 207 208 default : 209 byNewStatus = GD_SPDIF_STATUS_NOCHANGE; 210 break; 211 } 212 213 if (byNewStatus == m_byGDCurrentSpdifStatus) 214 { 215 byNewStatus = GD_SPDIF_STATUS_NOCHANGE; 216 } 217 218 return byNewStatus; 219 220 } // BYTE CGdDspCommObject::SelectGinaDarlaSpdifStatus( DWORD dwNewSampleRate ) 221 222 223 224 /**************************************************************************** 225 226 Power management 227 228 ****************************************************************************/ 229 230 //=========================================================================== 231 // 232 // Tell the DSP to go into low-power mode 233 // 234 //=========================================================================== 235 236 ECHOSTATUS CGdDspCommObject::GoComatose() 237 { 238 ECHO_DEBUGPRINTF(("CGdDspCommObject::GoComatose\n")); 239 240 m_byGDCurrentClockState = GD_CLOCK_UNDEF; 241 m_byGDCurrentSpdifStatus = GD_SPDIF_STATUS_UNDEF; 242 243 return CDspCommObject::GoComatose(); 244 245 } // end of GoComatose 246 247 248 // **** GinaDspCommObject.cpp **** 249