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

📄 aaci_audio.c

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 C
📖 第 1 页 / 共 5 页
字号:
        dwStatus = AACI_RegRead32(AACIReg_Channel1Status);
        dwCount++;
    } 

    // Disable FIFO and clear interrupts
    AACI_RegWrite32( AACIReg_Channel1TxControl, 
                     AACI_RegRead32(AACIReg_Channel1TxControl) & 
                     ~(AACIBit_EnableFIFO) );
    AACI_RegWrite32( AACIReg_IntClear, AACIBit_TxUEC1 );

    // Had to quit out of busy loop?
    if( dwCount == 10 )
    {
        WRNMSG2("ClearTransmitFIFO: WARNING! count=%d, status=0x%04x", 
                dwCount, AACI_RegRead32(AACIReg_Channel1Status));
        return FALSE;
    }    

    return TRUE;
}

// Clear the FIFO by reading the received data
static BOOL ClearReceiveFIFO( DWORD *pdwDataRead )
{
    DWORD dwData, dwCount = 0; // dwStatus, dwNewStatus;

    // Make sure FIFO disabled and clear interrupts
    AACI_RegWrite32( AACIReg_Channel1RxControl, 
                     AACI_RegRead32(AACIReg_Channel1RxControl) & 
                     ~(AACIBit_EnableFIFO) );
    AACI_RegWrite32( AACIReg_IntClear, AACIBit_RxTOFEC1 | AACIBit_RxOEC1 );
    
    // Read all the data in the FIFO
    // (NOTE: Do not use RX_FIFOSIZE as we may be called from the Test API in 
    //  different modes)
    while( !(AACI_RegRead32(AACIReg_Channel1Status) & AACIBit_RXFIFOEmpty) && 
           dwCount < (RX_FIFOSIZE_NOTCOMPACT*2) )
    {
        dwData = AACI_RegRead32( AACIReg_Channel1FIFO );
        dwCount++;        
    }

    // Return bytes read if we are given something to put them in
    if( pdwDataRead ) *pdwDataRead = dwCount;

    // Did something go wrong? (usually means that there is incoming data 
    //  held in slots, we can ignore this)
    if( dwCount == (RX_FIFOSIZE_NOTCOMPACT*2) || 
        (AACI_RegRead32(AACIReg_Channel1Status) & AACIBit_RXFIFOBusy) )
    {
        WRNMSG2("ClearReceiveFIFO: WARNING! read=%d, status=0x%04x", dwCount, 
                AACI_RegRead32(AACIReg_Channel1Status));
        return FALSE;
    }

    return TRUE;
}


#ifdef DEBUG
//-----------------------------------------------------------------------
// Debug information
//-----------------------------------------------------------------------

#define PRINT_STEREO_VOLUME(m,v) \
    PRINTMSG( ZONE_INIT, \
        (TEXT("%21s = 0x%04x (Mute = %d, Left = 0x%03x, Right = 0x%03x)\n"), \
            TEXT(m), v, (v & LM4549A_BIT_VOLUME_MUTE) != 0, (v >> 8) & 0x3F, \
            v & 0x3F) )

#define PRINT_MONO_VOLUME(m,v) \
    PRINTMSG( ZONE_INIT, \
        (TEXT("%21s = 0x%04x (Mute = %d, Mono = 0x%03x)\n"), \
            TEXT(m), v, (v & LM4549A_BIT_VOLUME_MUTE) != 0, v & 0x3F) )

#define PRINT_SETTING(m,s) \
    PRINTMSG( ZONE_INIT, \
        (TEXT("%21s = 0x%04x\n"), TEXT(m), s) )

static void DumpCurrentSettings()
{
    USHORT codec_data;

    codec_data = AACI_CodecRead16( LM4549A_RESET );
    PRINT_SETTING( "Reset", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_MASTER_VOLUME );
    PRINT_STEREO_VOLUME( "Master volume", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_LINE_LEV_OUT_VOL );
    PRINT_STEREO_VOLUME( "Line Level out volume", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_MASTER_VOLUME_MONO );
    PRINT_MONO_VOLUME( "Master Mono volume", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_PC_BEEP_VOLUME );
    PRINTMSG( ZONE_INIT, (TEXT("%21s = 0x%04x (Mute = %d, Mono = 0x%02x)\n"), 
        TEXT("PC Beep volume"), codec_data, 
        (codec_data & LM4549A_BIT_VOLUME_MUTE) != 0, (codec_data>>1) & 0xF) );

    codec_data = AACI_CodecRead16( LM4549A_PHONE_VOLUME );
    PRINT_MONO_VOLUME( "Phone volume", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_MIC_VOLUME );
    PRINTMSG( ZONE_INIT, (TEXT("%21s = 0x%04x (Mute = %d, Gain = %d, Mono = 0x%03x)\n"), 
        TEXT("Mic volume"), codec_data, 
        (codec_data & LM4549A_BIT_VOLUME_MUTE) != 0, 
        (codec_data & LM4549A_BIT_VOLUME_GAIN) != 0, codec_data & 0x1F) );

    codec_data = AACI_CodecRead16( LM4549A_LINE_IN_VOLUME );
    PRINT_STEREO_VOLUME( "Line in volume", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_CD_VOLUME );
    PRINT_STEREO_VOLUME( "CD volume", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_VIDEO_VOLUME );
    PRINT_STEREO_VOLUME( "Video volume", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_AUX_VOLUME );
    PRINT_STEREO_VOLUME( "AUX volume", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_PCM_OUT_VOL );
    PRINT_STEREO_VOLUME( "PCM out volume", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_RECORD_SELECT );
    PRINTMSG( ZONE_INIT, (TEXT("%21s = 0x%04x (Left = 0x%02x, Right = 0x%02x)\n"), 
        TEXT("Record Select"), codec_data, (codec_data >> 8) & 0x7, 
        codec_data & 0x7) );

    codec_data = AACI_CodecRead16( LM4549A_RECORD_GAIN );
    PRINTMSG( ZONE_INIT, (TEXT("%21s = 0x%04x (Mute = %d, Left = 0x%02x, Right = 0x%02x)\n"), 
        TEXT("Record Gain"), codec_data, 
        (codec_data & LM4549A_BIT_VOLUME_MUTE) != 0, (codec_data >> 8) & 0xF, 
        codec_data & 0xF) );

    codec_data = AACI_CodecRead16( LM4549A_GENERAL_PURPOSE );
    PRINT_SETTING( "General Purpose", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_3D_CONTROL );
    PRINT_SETTING( "3D Control", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_POWERDOWN_CTRL_STAT );
    PRINT_SETTING( "Powerdown Status", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_EXT_AUDIO_ID );
    PRINT_SETTING( "Extended Audio ID", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_EXT_AUDIO_CTRL_STAT );
    PRINT_SETTING( "Extended Audio Status", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_PCM_FRONT_DAC_RATE );
    PRINT_SETTING( "PCM Front DAC Rate", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_PCM_ADC_RATE );
    PRINT_SETTING( "PCM ADC Rate", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_VENDOR_ID1 );
    PRINT_SETTING( "Vendor ID1", codec_data );

    codec_data = AACI_CodecRead16( LM4549A_VENDOR_ID2 );
    PRINT_SETTING( "Vendor ID2", codec_data );
}
#endif // DEBUG

#ifdef TEST_API
// -----------------------------------------------------------------------------
// Test Functions
// -----------------------------------------------------------------------------

#define TESTWAIT_TRANSMIT   5000
#define TESTWAIT_RECEIVE    5000

#define PAUSE   Sleep(100)


DWORD TestTransmit( DWORD uMsg )
{
    DWORD dwTest;
    DWORD dwTXCtrl, dwTXSize;
    DWORD dwRet = MMSYSERR_NOERROR, dwResult;

    RETAILMSG( DBG_AACI, (TEXT("TestTransmit v0.5\n")) );

    if( !g_fInUse[WAPI_OUT] )
    {
        RETAILMSG( DBG_AACI, (TEXT("TestTransmit_xxx: ERROR - WaveOut channel should have been opened\n")) );
        return MMSYSERR_ERROR;
    }

    if( g_fInUse[WAPI_IN] )
    {
        // We need to take over the whole AACI so we need both channels
        RETAILMSG( DBG_AACI, (TEXT("TestTransmit_xxx: ERROR - WaveIn channel in use\n")) );
        return MMSYSERR_ERROR;
    }

    g_fTesting = TRUE;
    g_fInUse[WAPI_IN] = TRUE;   // Stop anyone else using the record channel 
                                //  whilst we are testing playback
    g_fTestIntDisable = TRUE;   // Assume we don't want interrupts to continue 
                                //  after the first one

    // Reset device to get into known state
    ResetDevice();

    dwTXCtrl = AACIBit_Slot3DataInFIFO | AACIBit_Slot4DataInFIFO | 
                AACIBit_EnableFIFOMode;

    // Set output rate to 8KHz
    AACI_CodecWrite16( LM4549A_PCM_FRONT_DAC_RATE, 8000 );

    // Disable AACI and then Transmit & Receive FIFOs
    PAUSE;
    AACI_RegWrite32( AACIReg_MainControl, 0 );
    AACI_RegWrite32( AACIReg_Channel1TxControl, 0 );
    AACI_RegWrite32( AACIReg_Channel1RxControl, 0 );

    PAUSE;
    // Turn on AACI without slot comms
    AACI_RegWrite32( AACIReg_MainControl, AACIBit_Enable );

    // Create an interrupt event
    g_hTestInterrupt = CreateEvent( NULL, FALSE, FALSE, NULL );

    for( dwTest = 0; dwTest < 6; dwTest++ )
    {
        switch( dwTest )
        {
        case 0:
            RETAILMSG( DBG_AACI, (TEXT("Data size 16 bits: ")) );
            dwTXSize = AACIBit_DataSize16bits;
            break;
        case 1:
            RETAILMSG( DBG_AACI, (TEXT("Data size 12 bits: ")) );
            dwTXSize = AACIBit_DataSize12bits;
            break;
        case 2:
            RETAILMSG( DBG_AACI, (TEXT("Data size 18 bits: ")) );
            dwTXSize = AACIBit_DataSize18bits;
            break;
        case 3:
            RETAILMSG( DBG_AACI, (TEXT("Data size 20 bits: ")) );
            dwTXSize = AACIBit_DataSize20bits;
            break;
        case 4:
            RETAILMSG( DBG_AACI, (TEXT("Data size 16 bits compact: ")) );
            dwTXSize = AACIBit_DataSize16bits | AACIBit_EnableCompactMode;
            break;
        case 5:
            RETAILMSG( DBG_AACI, (TEXT("Data size 12 bits compact: ")) );
            dwTXSize = AACIBit_DataSize12bits | AACIBit_EnableCompactMode;
            break;
        }
        // Set up Transmit FIFO (Disable AACI whilst changing transmit size 
        //  and compact mode)
        AACI_RegWrite32( AACIReg_MainControl, 0 );
        AACI_RegWrite32( AACIReg_Channel1TxControl, dwTXCtrl | dwTXSize );
        AACI_RegWrite32( AACIReg_Channel1IntEnable, 0 );
        PAUSE;
        AACI_RegWrite32( AACIReg_MainControl, AACIBit_Enable );

        // Clear the event of any previous interrupts
        ResetEvent( g_hTestInterrupt );

        switch (uMsg)
        {
            case TESTTX_FIFOSIZE:
                dwResult = TestTransmit_FIFOSize( (dwTest < 4) );
                break;
            case TESTTX_COMPLETE:
                dwResult = TestTransmit_Complete( (dwTest < 4) );
                break;
            case TESTTX_HALFEMPTY:
                dwResult = TestTransmit_HalfEmpty( (dwTest < 4) );
                break;
            default:
                RETAILMSG(DBG_AACI, (TEXT("TestTransmit: Unsupported test %d\n"), 
                        uMsg) );
                dwResult = MMSYSERR_ERROR;
        }
        if( dwResult != MMSYSERR_NOERROR ) dwRet = dwResult;

        // Check for error?
        if( !ClearTransmitFIFO() )
        {
            RETAILMSG(DBG_AACI, (TEXT("TestTransmit: WARNING - problems clearing FIFO after test\n")) );
        }
    }

    CloseHandle( g_hTestInterrupt );

    // Clean up
    ResetDevice();
    AACI_SetVolume(g_nVolume);

    g_fInUse[WAPI_IN] = FALSE;
    g_fTesting = FALSE;

    return dwRet;
}

static DWORD TestTransmit_FIFOSize( BOOL fNotCompact )
{
    DWORD dwCount = 0;

    // Fill up FIFO!
    while( !(AACI_RegRead32( AACIReg_Channel1Status ) & AACIBit_TXFIFOFull) && 
           dwCount <= TX_FIFOSIZE_NOTCOMPACT )
    {
        // Left Channel (or both when compact enabled)
        AACI_RegWrite32( AACIReg_Channel1FIFO, 0 );
        dwCount++;

        // Right Channel (when not compact)
        if( fNotCompact )
        {
            AACI_RegWrite32( AACIReg_Channel1FIFO, 0 );
            dwCount++;
        }
    }

    if( ((fNotCompact && dwCount == TX_FIFOSIZE_NOTCOMPACT) || 
         (!fNotCompact && dwCount == TX_FIFOSIZE_COMPACT)) &&
         (AACI_RegRead32( AACIReg_Channel1Status ) & AACIBit_TXFIFOFull) )
    {
        RETAILMSG( DBG_AACI, (TEXT("PASS\n")) );
        return MMSYSERR_NOERROR;
    }

    RETAILMSG( DBG_AACI, (TEXT("FAIL (size=%d)\n"),dwCount) );
    return MMSYSERR_ERROR;
}


static DWORD TestTransmit_Complete( BOOL fNotCompact )
{
    DWORD dwRet;

    // Fill the FIFO for transmitting (to allow us some time to receive the 
    //  interrupt)
    while( !(AACI_RegRead32( AACIReg_Channel1Status ) & AACIBit_TXFIFOFull) )
    {
        AACI_RegWrite32( AACIReg_Channel1FIFO, 0 );
    }

    // Enable Interrupt
    g_dwTestIntStatus = 0;
    AACI_RegWrite32( AACIReg_Channel1IntEnable, AACIBit_TxCIE );

    // Enable Transmit and wait for completion
    AACI_RegWrite32( AACIReg_Channel1TxControl, 
                     AACI_RegRead32(AACIReg_Channel1TxControl) | 
                     AACIBit_EnableFIFO );
    dwRet = WaitForSingleObject( g_hTestInterrupt, TESTWAIT_TRANSMIT );

    // Disable interrupts
    AACI_RegWrite32( AACIReg_Channel1IntEnable, 0 );

    if( g_dwTestIntStatus & AACIBit_TxCIE )
    {
        RETAILMSG( DBG_AACI, (TEXT("PASS\n")) );
        return MMSYSERR_NOERROR;
    }

    RETAILMSG( DBG_AACI, (TEXT("FAIL (ints=0x%04x)\n"), g_dwTestIntStatus) );
    return MMSYSERR_ERROR;
}


static DWORD TestTransmit_HalfEmpty( BOOL fNotCompact )
{
    DWORD dwCount, dwDataCount;
    DWORD dwRet;

    dwDataCount = (fNotCompact ? 2 : 1);

    do
    {
        // Put some data words into the FIFO for transmitting
        for( dwCount = 0; dwCount < dwDataCount; dwCount++ )
        {
            AACI_RegWrite32( AACIReg_Channel1FIFO, 0 );
        }

        // Enable the half-way (or less) interrupt to see what the status of 
        //  the FIFO is
        g_dwTestIntStatus = 0;
        AACI_RegWrite32( AACIReg_Channel1IntEnable, AACIBit_TxIE );

        dwRet = WaitForSingleObject( g_hTestInterrupt, TESTWAIT_TRANSMIT );

        // Make sure interrupts disabled
        AACI_RegWrite32( AACIReg_Channel1IntEnable, 0 );

        // Check for when we don't have the half-way or less interrupt set
        if( !(g_dwTestIntStatus & AACIBit_TxIE) )
        

⌨️ 快捷键说明

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