⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hwctxt.cpp

📁 pxa270平台 windows mobile 5.2 wm9713 触摸屏+音频驱动
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// Copyright (c) Wolfson Microelectronics plc.  All rights reserved.
//
// This software as well as any related documentation is furnished under 
// license and may only be used or copied in accordance with the terms of the 
// license. The information in this file is furnished for informational use 
// only, is subject to change without notice, and should not be construed as 
// a commitment by Wolfson Microelectronics plc. Wolfson Microelectronics plc
// assumes no responsibility or liability for any errors or inaccuracies that
// may appear in this document or any software that may be provided in
// association with this document. 
//
// Except as permitted by such license, no part of this document may be 
// reproduced, stored in a retrieval system, or transmitted in any form or by 
// any means without the express written consent of Wolfson Microelectronics plc. 
//
// $Id: hwctxt.cpp 3998 2006-10-03 13:00:37Z fb $
//
// This file provides the rest of the WaveDev2 driver with the access to
// Wolfson codecs via the Wolfson Driver API.
//
// Warning:
//  This driver is specifically written for Wolfson Audio Codecs.  It is
//  not a general audio CODEC device driver.
//-----------------------------------------------------------------------------

//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// -----------------------------------------------------------------------------
//
//      THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//      ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//      PARTICULAR PURPOSE.
//
// -----------------------------------------------------------------------------

//
// Include files
//
#include "wavemain.h"
#include "hwctxt.h"

#include "WDCL.h"

#if !WM_AUDIO || !WM_AUDIO_STREAM
#error Mismatch: The Wolfson API is not configured for Audio or Audio Streaming, build system is configured for Audio
#endif // !WM_AUDIO || !WM_AUDIO_STREAM

//
// NOTE: The audio path functions that are included by WMAudioPaths.h
//       and used in this file is only an example of one way of setting
//       up paths through the codec. In general we have gone for the
//       approach of enabling as many paths through the codec as possible
//       so that there is a good chance that which ever input and output
//       is used some audio will get through.
//
//       It is therefore important that developers optimize this to suit
//       the application. It may be that you need to make changes to these 
//       functions or use different functions from this file.
//
//       If you have any queries, or suggestions for audio paths that
//       are not covered in the WolfsonAPI please feel free to contact the
//       apps team (apps@wolfsonmicro.com). 
//

//
// Global definitions
//
HardwareContext *g_pHWContext=NULL;

//
// Work out what sort of chip it is.
//
#define IS_WM9705_DEVICE( _device )  (WM_CHIP_WM9705 == (_device))
#define IS_WM9707_DEVICE( _device )  (WM_CHIP_WM9707 == (_device))
#define IS_WM9712_DEVICE( _device )  (WM_CHIP_WM9712 == (_device))
#define IS_WM9713_DEVICE( _device )  (WM_CHIP_WM9713 == (_device))

//
// Whether to clear partial buffers.
//
#define CLEAR_BUFFER        TRUE

// WinCE volume scheme: 16 bits of Left and 16 bits of Right (0xRRRRLLLL)
#define RIGHT_VOLUME_MASK	0xFFFF0000
#define RIGHT_VOLUME_SHIFT	16
#define LEFT_VOLUME_MASK	0x0000FFFF
#define LEFT_VOLUME_SHIFT   0
#define RIGHT_VOL( _vol )   ((unsigned short)(((_vol) & RIGHT_VOLUME_MASK) >> RIGHT_VOLUME_SHIFT))
#define LEFT_VOL( _vol )    ((unsigned short)(((_vol) & LEFT_VOLUME_MASK) >> LEFT_VOLUME_SHIFT))

#define OUTPUTDMARUNNING( _pWMAudioData )  ( _pWMAudioData->HiFiOutputDMARunning    || \
                                             _pWMAudioData->VoiceOutputDMARunning   || \
                                             _pWMAudioData->MonoOutputDMARunning       \
                                          )

#define INPUTDMARUNNING( _pWMAudioData )  (  _pWMAudioData->HiFiInputDMARunning    || \
                                            _pWMAudioData->VoiceInputDMARunning       \
                                         )

//
// Class data
//

//
// Function prototypes
//
#if WM_USE_DYNAMIC_DMA_CHANNEL
void CallHiFiInputInterruptThread(HardwareContext *pHWContext);
void CallHiFiOutputInterruptThread(HardwareContext *pHWContext);
#   if WM_VOICE
void CallVoiceOutputInterruptThread(HardwareContext *pHWContext);
void CallVoiceInputInterruptThread(HardwareContext *pHWContext);
#   endif // WM_VOICE
#   if WM_MONODAC
void CallMonoOutputInterruptThread(HardwareContext *pHWContext);
#   endif // WM_MONODAC
#else // WM_USE_DYNAMIC_DMA_CHANNEL
void CallInterruptThread(HardwareContext *pHWContext);
#endif // WM_USE_DYNAMIC_DMA_CHANNEL

#if WM_OUTPUT_MUTE_DELAY
void CallOutputMuteInterruptThread(HardwareContext *pHWContext);
#endif

//-----------------------------------------------------------------------------
// Class:    HardwareContext
//
// This class handles the communication with the codec, so the rest
// of the driver doesn't have to worry about it.
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Member function:    CreateHWContext
//
// Creates the global hardware context if it doesn't yet exist.
//
// Parameters:
//      Index		driver index, used for path selection.
//
// Returns:     BOOL
//      TRUE = created
//		FALSE = not created
//-----------------------------------------------------------------------------
BOOL HardwareContext::CreateHWContext(DWORD Index)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+HardwareContext::CreateHWContext")));

    if (g_pHWContext)
    {
        return TRUE;
    }

    g_pHWContext = new HardwareContext;
    if (!g_pHWContext)
    {
        return FALSE;
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-HardwareContext::CreateHWContext")));

    return g_pHWContext->Init(Index);
}

//-----------------------------------------------------------------------------
// Constructor:    HardwareContext
//
// Constructor for HardwareContext
//
// Parameters:
//     none
//-----------------------------------------------------------------------------
HardwareContext::HardwareContext()
: m_HiFiInputDeviceContext(), m_HiFiOutputDeviceContext()
#if WM_VOICE
,m_VoiceInputDeviceContext(), m_VoiceOutputDeviceContext()
#endif // WM_VOICE
#if WM_MONODAC
, m_MonoOutputDeviceContext()
#endif // WM_MONODAC
{
    InitializeCriticalSection(&m_Lock);
    m_Initialized=FALSE;
}

//-----------------------------------------------------------------------------
// Destructor:    ~HardwareContext
//
// Destructor for HardwareContext - cleans up when it is destroyed.
//-----------------------------------------------------------------------------
HardwareContext::~HardwareContext()
{
    DeleteCriticalSection(&m_Lock);
}

//-----------------------------------------------------------------------------
// Member function:    Init
//
// Does any initialisation which can fail.
//
// Parameters:
//      Index   driver index (determines which paths to use).
//
// Returns:     BOOL
//      TRUE = initialisation done
//      FALSE = Already initialised, or initialisation failed
//-----------------------------------------------------------------------------
BOOL HardwareContext::Init(DWORD Index)
{
    DEBUGMSG(ZONE_INIT|ZONE_FUNCTION, (TEXT("+HardwareContext::Init")));

    if (m_Initialized)
    {
        return FALSE;
    }

    //
    // Create a mutex for the shared audio data.
    //
    m_hGlobalDataDeviceMutex = CreateMutex ( NULL, FALSE, WM_GLOBAL_DATA_MUTEX_NAME );
    if ( NULL == m_hGlobalDataDeviceMutex )
    {
        goto Exit;
    }

    //
    // Allocate shared memory for the shared audio data in the device
    // process.
    //
    m_pWMAudioDeviceData = ALLOC_SHARED_MEMORY( m_hAudioDevice,
                                                volatile WM_SHARED_AUDIO_DATA,
                                                sizeof( WM_SHARED_AUDIO_DATA ),
                                                _T("WMGlobalAudioDriverMemory")
                                              );
    if ( !m_pWMAudioDeviceData )
    {
        goto Exit;
    }

    //
    // Initialise the shared audio data.
    //
    m_pWMAudioDeviceData->inPowerHandler         = FALSE;
    m_pWMAudioDeviceData->HiFiInputDMARunning    = FALSE;
    m_pWMAudioDeviceData->HiFiOutputDMARunning   = FALSE;
    m_pWMAudioDeviceData->VoiceOutputDMARunning  = FALSE;
    m_pWMAudioDeviceData->VoiceInputDMARunning   = FALSE;
    m_pWMAudioDeviceData->MonoOutputDMARunning   = FALSE;
#if WM_OUTPUT_MUTE_DELAY
    m_pWMAudioDeviceData->HiFiOutputMuted        = TRUE;
    m_pWMAudioDeviceData->VoiceOutputMuted       = TRUE;
    m_pWMAudioDeviceData->MonoOutputMuted        = TRUE;
	m_pWMAudioDeviceData->OutputMuteTimerStarted = FALSE;
#endif

    m_DriverIndex           = Index;
	m_shuttingDown  		= FALSE;

#if !WM_USE_DYNAMIC_DMA_CHANNEL
    m_IntrAudio             = SYSINTR_AUDIO;
#endif // !WM_USE_DYNAMIC_DMA_CHANNEL

    m_NumForcedSpeaker      = 0;

    m_MasterOutputVolume    = 0xFFFFFFFF;
    m_MasterOutputMute      = FALSE;
    m_OutputMaxAtten        = FALSE;

    // Set up our API variables
    m_hAudioDevice          = WM_HANDLE_INVALID;
    m_hHiFiOutputStream     = WM_HANDLE_INVALID;
    m_hHiFiInputStream      = WM_HANDLE_INVALID;
#if WM_VOICE
    m_hVoiceOutputStream    = WM_HANDLE_INVALID;
    m_hVoiceInputStream     = WM_HANDLE_INVALID;
#endif // WM_VOICE
#if WM_MONODAC
    m_hMonoOutputStream     = WM_HANDLE_INVALID;
#endif // WM_MONODAC

    m_nextHiFiOutputBuf     = 0;
    m_HiFiOutputStarted     = FALSE;
    m_nextHiFiInputBuf      = 0;
    m_HiFiInputStarted      = FALSE;
#if WM_VOICE
    m_nextVoiceOutputBuf    = 0;
    m_VoiceOutputStarted    = FALSE;
    m_nextVoiceInputBuf     = 0;
    m_VoiceInputStarted     = FALSE;
#endif // WM_VOICE
#if WM_MONONDAC
    m_nextMonoOutputBuf     = 0;
    m_MonoOutputStarted     = FALSE;
#endif // WM_MONODAC

    // Configure the Codec
    if ( !InitCodec() )
    {
        goto Exit;
    }

#if WM_USE_DYNAMIC_DMA_CHANNEL
	// Link the stream and the DMA interrupt event.
    ASSERT( WM_HANDLE_INVALID != m_hHiFiOutputStream );
	hHiFiOutputIntEvent = WMAudioGetDMAEventHandle( m_hAudioDevice, m_hHiFiOutputStream );
    if( !hHiFiOutputIntEvent )
    {
		DEBUGMSG(ZONE_ERROR, 
                 (TEXT("WMAudioGetDMAEventHandle - ERROR: hHiFiOutputIntEvent is NULL\r\n"))
                );
        goto Exit;
    }

	if ( WM_HANDLE_INVALID != m_hHiFiInputStream )
	{
		hHiFiInputIntEvent = WMAudioGetDMAEventHandle( m_hAudioDevice, m_hHiFiInputStream );
		if(!hHiFiInputIntEvent)
		{
			DEBUGMSG(ZONE_ERROR, 
					 (TEXT("WMAudioGetDMAEventHandle - ERROR: hHiFiInputIntEvent is NULL\r\n"))
					);
			goto Exit;
		}
	}

#if WM_VOICE
	if ( WM_HANDLE_INVALID != m_hVoiceOutputStream )
	{
		hVoiceOutputIntEvent = WMAudioGetDMAEventHandle( m_hAudioDevice, m_hVoiceOutputStream );
		if( !hVoiceOutputIntEvent )
		{
			DEBUGMSG(ZONE_ERROR, 
					 (TEXT("WMAudioGetDMAEventHandle - ERROR: hVoiceOutputIntEvent is NULL\r\n"))
					);
			goto Exit;
		}
	}

	if ( WM_HANDLE_INVALID != m_hVoiceInputStream )
	{
        hVoiceInputIntEvent = WMAudioGetDMAEventHandle( m_hAudioDevice, m_hVoiceInputStream );
        if(!hVoiceInputIntEvent)
        {
            DEBUGMSG(ZONE_ERROR, 
                     (TEXT("WMAudioGetDMAEventHandle - ERROR: hVoiceInputIntEvent is NULL\r\n"))
                    );
            goto Exit;
        }
    }
#endif // WM_VOICE

#if WM_MONODAC
	if ( WM_HANDLE_INVALID != m_hMonoOutputStream )
	{
		hMonoOutputIntEvent = WMAudioGetDMAEventHandle( m_hAudioDevice, m_hMonoOutputStream );
		if( !hMonoOutputIntEvent )
		{
			DEBUGMSG(ZONE_ERROR, 
					 (TEXT("WMAudioGetDMAEventHandle - ERROR: hMonoOutputIntEvent is NULL\r\n"))
					);
			goto Exit;
		}
	}
#endif // WM_MONODAC

#endif // WM_USE_DYNAMIC_DMA_CHANNEL 

    if (!InitInterruptThread())
    {
        goto Exit;
    }

#if WM_OUTPUT_MUTE_DELAY
    if ( !InitOutputMuteTimerThread() )
    {
        goto Exit;
    }
#endif

    m_Initialized=TRUE;

Exit:
    DEBUGMSG(ZONE_INIT|ZONE_FUNCTION, (TEXT("-HardwareContext::Init")));
    return m_Initialized;
}

//-----------------------------------------------------------------------------
// Member function:    InitCodec
//
// This function sets up the codec and paths ready to start playing and
// recording.
//
// Parameters:
//      none
//
// Returns:     BOOL
//      TRUE = success
//      FALSE = failure
//-----------------------------------------------------------------------------
BOOL HardwareContext::InitCodec()
{
    DWORD    retval = MMSYSERR_NOERROR;
    WMSTATUS status = WMS_NO_SUPPORTED_DEVICE;

    //
    // Open a handle to the Wolfson Driver API.
    //
#if WM_I2S && defined( WM_AUDIO_I2S_DEVICE )
    //
    // Try the I2S first...
    //
    status = WMOpenAudioDevice( WM_DEV_PRIMARY_DEVICE( WM_AUDIO_I2S_DEVICE ), &m_hAudioDevice );
    if ( WM_SUCCESS( status ) )
    {
        DEBUGMSG( ZONE_PDD, ( TEXT( "PDD_AudioInitialise - primary I2S device\r\n" ) ) );
    }
    if ( WMS_CODEC_NOT_READY == status || WMS_NO_SUPPORTED_DEVICE == status )
    {
        //
        // Nothing responding on I2S primary - try secondary instead...
        //
        status = WMOpenAudioDevice( WM_DEV_SECONDARY_DEVICE( WM_AUDIO_I2S_DEVICE ), &m_hAudioDevice );
        if ( WM_SUCCESS( status ) )
        {
            DEBUGMSG( ZONE_PDD, ( TEXT( "PDD_AudioInitialise - secondary I2S device\r\n" ) ) );
        }
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -