BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / audio / echo / generic / C3g.cpp
blobcef64d62ccaf003c70f750ecbed21f539561183c
1 // ****************************************************************************
2 //
3 // C3g.cpp
4 //
5 // Implementation file for the C3g driver class.
6 // Set editor tabs to 3 for your viewing pleasure.
7 //
8 // ----------------------------------------------------------------------------
9 //
10 // This file is part of Echo Digital Audio's generic driver library.
11 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005
12 // All rights reserved
13 // www.echoaudio.com
15 // This library is free software; you can redistribute it and/or
16 // modify it under the terms of the GNU Lesser General Public
17 // License as published by the Free Software Foundation; either
18 // version 2.1 of the License, or (at your option) any later version.
20 // This library is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 // Lesser General Public License for more details.
25 // You should have received a copy of the GNU Lesser General Public
26 // License along with this library; if not, write to the Free Software
27 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 // ****************************************************************************
31 #include "C3g.h"
33 #define ECHO3G_ANALOG_OUTPUT_LATENCY_1X (1 + 32 + 12) // ASIC + DSP + DAC
34 #define ECHO3G_ANALOG_OUTPUT_LATENCY_2X (1 + 32 + 5)
35 #define ECHO3G_ANALOG_INPUT_LATENCY_1X (1 + 32 + 12)
36 #define ECHO3G_ANALOG_INPUT_LATENCY_2X (1 + 32 + 9)
38 #define ECHO3G_DIGITAL_OUTPUT_LATENCY (1 + 32)
39 #define ECHO3G_DIGITAL_INPUT_LATENCY (1 + 32)
43 /****************************************************************************
45 Construction and destruction
47 ****************************************************************************/
49 //===========================================================================
51 // Overload new & delete so memory for this object is allocated
52 // from non-paged memory.
54 //===========================================================================
56 PVOID C3g::operator new( size_t Size )
58 PVOID pMemory;
59 ECHOSTATUS Status;
61 Status = OsAllocateNonPaged(Size,&pMemory);
63 if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
65 ECHO_DEBUGPRINTF(("C3g::operator new - memory allocation failed\n"));
67 pMemory = NULL;
69 else
71 memset( pMemory, 0, Size );
74 return pMemory;
76 } // PVOID C3g::operator new( size_t Size )
79 VOID C3g::operator delete( PVOID pVoid )
81 if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
83 ECHO_DEBUGPRINTF(("C3g::operator delete memory free failed\n"));
85 } // VOID C3g::operator delete( PVOID pVoid )
88 //===========================================================================
90 // Constructor and destructor
92 //===========================================================================
94 C3g::C3g( PCOsSupport pOsSupport )
95 : CEchoGalsMTC( pOsSupport )
97 ECHO_DEBUGPRINTF( ( "C3g::C3g() is born!\n" ) );
99 m_wAnalogOutputLatency = ECHO3G_ANALOG_OUTPUT_LATENCY_1X;
100 m_wAnalogInputLatency = ECHO3G_ANALOG_INPUT_LATENCY_1X;
101 m_wDigitalOutputLatency = ECHO3G_DIGITAL_OUTPUT_LATENCY;
102 m_wDigitalInputLatency = ECHO3G_DIGITAL_INPUT_LATENCY;
106 C3g::~C3g()
108 ECHO_DEBUGPRINTF( ( "C3g::~C3g() is toast!\n" ) );
114 /****************************************************************************
116 Setup and hardware initialization
118 ****************************************************************************/
120 //===========================================================================
122 // Every card has an InitHw method
124 //===========================================================================
126 ECHOSTATUS C3g::InitHw()
128 ECHOSTATUS Status;
129 WORD i;
132 // Call the base method
134 if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
135 return Status;
138 // Create the DSP comm object
140 ECHO_ASSERT(NULL == m_pDspCommObject );
141 m_pDspCommObject = new C3gDco( (PDWORD) m_pvSharedMemory, m_pOsSupport );
142 if (NULL == m_pDspCommObject)
144 ECHO_DEBUGPRINTF(("C3g::InitHw - could not create DSP comm object\n"));
145 return ECHOSTATUS_NO_MEM;
149 // Load the DSP
151 DWORD dwBoxType;
153 GetDspCommObject()->LoadFirmware();
155 GetDspCommObject()->Get3gBoxType(&dwBoxType,NULL);
156 if (NO3GBOX == dwBoxType)
157 return ECHOSTATUS_NO_3G_BOX;
159 if ( GetDspCommObject()->IsBoardBad() )
160 return ECHOSTATUS_DSP_DEAD;
163 // Clear the "bad board" flag; set the flags to indicate that
164 // 3G can handle super-interleave.
166 m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
167 m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK;
170 // Must call this here after DSP is init to
171 // init gains and mutes
173 Status = InitLineLevels();
174 if ( ECHOSTATUS_OK != Status )
175 return Status;
178 // Initialize the MIDI input
180 Status = m_MidiIn.Init( this );
181 if ( ECHOSTATUS_OK != Status )
182 return Status;
185 // Set defaults for +4/-10
187 for (i = 0; i < GetFirstDigitalBusOut(); i++ )
189 GetDspCommObject()->
190 SetNominalLevel( i, FALSE ); // FALSE is +4 here
192 for ( i = 0; i < GetFirstDigitalBusIn(); i++ )
194 GetDspCommObject()->
195 SetNominalLevel( GetNumBussesOut() + i, FALSE );
199 // Set the digital mode to S/PDIF RCA
201 SetDigitalMode( DIGITAL_MODE_SPDIF_RCA );
204 // Get default sample rate from DSP
206 m_dwSampleRate = GetDspCommObject()->GetSampleRate();
208 ECHO_DEBUGPRINTF( ( "C3g::InitHw()\n" ) );
209 return Status;
211 } // ECHOSTATUS C3g::InitHw()
216 /****************************************************************************
218 Informational methods
220 ****************************************************************************/
222 //===========================================================================
224 // Override GetCapabilities to enumerate unique capabilties for this card
226 //===========================================================================
228 ECHOSTATUS C3g::GetCapabilities
230 PECHOGALS_CAPS pCapabilities
233 ECHOSTATUS Status;
234 WORD i;
236 Status = GetBaseCapabilities(pCapabilities);
237 if ( ECHOSTATUS_OK != Status )
238 return Status;
241 // Add nominal level control to all ins & outs except the universal
243 for (i = 0 ; i < pCapabilities->wNumBussesOut; i++)
245 pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
248 for (i = 2 ; i < pCapabilities->wNumBussesIn; i++)
250 pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
253 pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_SPDIF |
254 ECHO_CLOCK_BIT_ADAT |
255 ECHO_CLOCK_BIT_MTC;
258 // Box-specific capabilities
260 DWORD dwBoxType;
262 GetDspCommObject()->Get3gBoxType(&dwBoxType,NULL);
263 switch (dwBoxType)
265 case GINA3G :
266 pCapabilities->dwBusInCaps[0] |= ECHOCAPS_PHANTOM_POWER;
267 pCapabilities->dwBusInCaps[1] |= ECHOCAPS_PHANTOM_POWER;
268 break;
270 case LAYLA3G :
271 pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_WORD;
272 break;
276 pCapabilities->dwOutClockTypes = 0;
278 return Status;
280 } // ECHOSTATUS C3g::GetCapabilities
283 //===========================================================================
285 // QueryAudioSampleRate is used to find out if this card can handle a
286 // given sample rate.
288 //===========================================================================
290 ECHOSTATUS C3g::QueryAudioSampleRate
292 DWORD dwSampleRate
296 // Check rates that are supported by continuous mode; only allow
297 // double-speed rates if not in ADAT mode
299 if ((dwSampleRate >= 32000) && (dwSampleRate <= 50000))
300 return ECHOSTATUS_OK;
302 if ( (DIGITAL_MODE_ADAT != GetDigitalMode()) &&
303 (dwSampleRate > 50000) &&
304 (dwSampleRate <= 100000))
305 return ECHOSTATUS_OK;
307 ECHO_DEBUGPRINTF(("C3g::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) );
309 return ECHOSTATUS_BAD_FORMAT;
311 } // ECHOSTATUS C3g::QueryAudioSampleRate
314 void C3g::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate)
316 dwMinRate = 32000;
317 dwMaxRate = 96000;
322 //===========================================================================
324 // GetInputClockDetect returns a bitmask consisting of all the input
325 // clocks currently connected to the hardware; this changes as the user
326 // connects and disconnects clock inputs.
328 // You should use this information to determine which clocks the user is
329 // allowed to select.
331 //===========================================================================
333 ECHOSTATUS C3g::GetInputClockDetect(DWORD &dwClockDetectBits)
335 if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
337 ECHO_DEBUGPRINTF( ("C3g::GetInputClockDetect: DSP Dead!\n") );
338 return ECHOSTATUS_DSP_DEAD;
342 // Map the DSP clock detect bits to the generic driver clock detect bits
344 DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
346 dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_MTC;
348 if (0 != (dwClocksFromDsp & E3G_CLOCK_DETECT_BIT_WORD))
349 dwClockDetectBits |= ECHO_CLOCK_BIT_WORD;
351 switch (GetDigitalMode())
353 case DIGITAL_MODE_SPDIF_RCA :
354 case DIGITAL_MODE_SPDIF_OPTICAL :
355 if (0 != (dwClocksFromDsp & E3G_CLOCK_DETECT_BIT_SPDIF))
356 dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
357 break;
359 case DIGITAL_MODE_ADAT :
360 if (0 != (dwClocksFromDsp & E3G_CLOCK_DETECT_BIT_ADAT))
361 dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT;
362 break;
365 return ECHOSTATUS_OK;
367 } // GetInputClockDetect
370 //===========================================================================
372 // Get the external box type
374 //===========================================================================
376 void C3g::Get3gBoxType(DWORD *pOriginalBoxType,DWORD *pCurrentBoxType)
378 GetDspCommObject()->Get3gBoxType(pOriginalBoxType,pCurrentBoxType);
382 //===========================================================================
384 // Get the external box name
386 //===========================================================================
388 char *C3g::Get3gBoxName()
390 char *pszName;
391 DWORD dwBoxType;
393 GetDspCommObject()->Get3gBoxType(&dwBoxType,NULL);
394 switch (dwBoxType)
396 case GINA3G :
397 pszName = "Gina3G";
398 break;
400 case LAYLA3G :
401 pszName = "Layla3G";
402 break;
404 case NO3GBOX :
405 default :
406 pszName = "Echo3G";
407 break;
410 return pszName;
414 //===========================================================================
416 // Get phantom power state for Gina3G
418 //===========================================================================
420 void C3g::GetPhantomPower(BOOL *pfPhantom)
422 *pfPhantom = m_fPhantomPower;
426 //===========================================================================
428 // Set phantom power state for Gina3G
430 //===========================================================================
432 void C3g::SetPhantomPower(BOOL fPhantom)
434 DWORD dwBoxType;
436 GetDspCommObject()->Get3gBoxType(&dwBoxType,NULL);
437 if (GINA3G == dwBoxType)
439 GetDspCommObject()->SetPhantomPower( fPhantom );
440 m_fPhantomPower = fPhantom;
445 //===========================================================================
447 // GetAudioLatency - returns the latency for a single pipe
449 //===========================================================================
451 void C3g::GetAudioLatency(ECHO_AUDIO_LATENCY *pLatency)
453 DWORD dwSampleRate;
456 // Adjust the stored latency values based on the sample rate
458 dwSampleRate = GetDspCommObject()->GetSampleRate();
459 if (dwSampleRate <= 50000)
461 m_wAnalogOutputLatency = ECHO3G_ANALOG_OUTPUT_LATENCY_1X;
462 m_wAnalogInputLatency = ECHO3G_ANALOG_INPUT_LATENCY_1X;
464 else
466 m_wAnalogOutputLatency = ECHO3G_ANALOG_OUTPUT_LATENCY_2X;
467 m_wAnalogInputLatency = ECHO3G_ANALOG_INPUT_LATENCY_2X;
471 // Let the base class worry about analog vs. digital
473 CEchoGals::GetAudioLatency(pLatency);
475 } // GetAudioLatency
479 //===========================================================================
481 // Start transport for a group of pipes
483 // Use this to make sure no one tries to start digital channels 3-8
484 // with the hardware in double speed mode.
486 //===========================================================================
488 ECHOSTATUS C3g::Start
490 PCChannelMask pChannelMask
493 PC3gDco pDCO;
496 // Double speed mode?
498 pDCO = GetDspCommObject();
499 if (pDCO->DoubleSpeedMode())
501 BOOL intersect;
504 // See if ADAT in 3-8 or out 3-8 are being started
506 intersect = pChannelMask->IsIntersectionOf( pDCO->m_Adat38Mask );
507 if (intersect)
509 ECHO_DEBUGPRINTF(("Cannot start ADAT channels 3-8 in double speed mode\n"));
510 return ECHOSTATUS_INVALID_CHANNEL;
514 return CEchoGals::Start(pChannelMask);
517 // *** C3g.cpp ***