📄 audlinux_esound.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
//===================================================================================
//
// audESound.cpp
//
// CLASS: CAudioOutESound
//
// Implements the sound subsystem for the Enlightenment Sound
// Deamon.
//
//===================================================================================
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <dlfcn.h>
#include "audlinux_esound.h"
#include "ihxpckts.h"
#include "hxtick.h"
//------------------------------------------
// Ctors and Dtors.
//------------------------------------------
CAudioOutESound::CAudioOutESound() :
CAudioOutUNIX(),
m_nDevID(NO_FILE_DESCRIPTOR),
m_nESoundServerID(NO_FILE_DESCRIPTOR),
m_nESoundPlayerID(NO_FILE_DESCRIPTOR),
m_ulTickCount(0),
m_ulPausePosition(0),
m_strRealplayerName(""),
m_pESDLib(NULL),
m_fpESDPlayStream(NULL),
m_fpESDGetAllInfo(NULL),
m_fpESDFreeAllInfo(NULL),
m_fpESDClose(NULL),
m_fpESDSetStreamPan(NULL),
m_fpESDAudioFlush(NULL),
m_fpESDOpenSound(NULL)
{
//Construct a proccess specific name to register with ESD.
m_strRealplayerName.Format( "%s-%d", "realplayer", getpid() );
};
CAudioOutESound::~CAudioOutESound()
{
HX_DELETE( m_pESDLib );
};
//-------------------------------------------------------
// These Device Specific methods must be implemented
// by the platform specific sub-classes.
//-------------------------------------------------------
INT16 CAudioOutESound::_Imp_GetAudioFd(void)
{
return m_nDevID;
}
//Devic specific method to set the audio device characteristics. Sample rate,
//bits-per-sample, etc.
//Method *must* set member vars. m_unSampleRate and m_unNumChannels.
HX_RESULT CAudioOutESound::_SetDeviceConfig( const HXAudioFormat* pFormat )
{
if ( m_nESoundServerID < 0 )
return RA_AOE_DEVNOTOPEN;
//We can only do this once after opening the audio device.
if( m_nDevID != NO_FILE_DESCRIPTOR )
return RA_AOE_DEVBUSY;
// Open the audio device if it isn't already open
esd_format_t format = ESD_STREAM | ESD_PLAY;
//Set steareo or mono
if( 2 == pFormat->uChannels )
{
format |= ESD_STEREO;
}
else
{
format |= ESD_MONO;
}
//Now set the format. Either 8-bit or 16-bit audio is supported.
if( pFormat->uBitsPerSample == 16)
{
format |= ESD_BITS16;
}
else
{
format |= ESD_BITS8;
}
//Now open our connection with ESD on the local host.
m_nDevID = m_fpESDPlayStream( format, pFormat->ulSamplesPerSec, NULL, (const char *)m_strRealplayerName);
if ( m_nDevID < 0 )
{
#ifdef _DEBUG
fprintf( stderr, "Failed to open audio!!!!!!! Code is: %d errno: %d\n",
m_nDevID, errno );
#endif
//Error opening device.
return RA_AOE_DEVNOTOPEN;
}
m_wBlockSize = m_ulBytesPerGran;
m_unNumChannels = pFormat->uChannels;
m_unSampleRate = pFormat->ulSamplesPerSec;
m_ulDeviceBufferSize = ESD_BUF_SIZE*4;
m_uSampFrameSize = pFormat->uBitsPerSample/8;
//Now, here is the tricky part. We must get a list of players from
//the esd deamon and interate through them until we find our self.
//Was we find us we need to store the ID for later use in setting
//the volume (panning).
//n
// From esd.h:
//
// typedef struct esd_info {
//
// esd_server_info_t *server;
// esd_player_info_t *player_list;
// esd_sample_info_t *sample_list;
//
// } esd_info_t;
//
// typedef struct esd_player_info {
// struct esd_player_info *next; /* point to next entry in list */
// esd_server_info_t *server; /* the server that contains this stream */
// int source_id; /* either a stream fd or sample id */
// char name[ ESD_NAME_MAX ]; /* name of stream for remote control */
// int rate; /* sample rate */
// int left_vol_scale; /* volume scaling */
// int right_vol_scale;
// esd_format_t format; /* magic int with the format info */
// } esd_player_info_t;
esd_player_info_t *pPlayerInfo = _GetPlayerInfo();
if( NULL == pPlayerInfo )
{
return RA_AOE_GENERAL;
}
m_nESoundPlayerID = pPlayerInfo->source_id;
HX_DELETE( pPlayerInfo );
if( m_nESoundPlayerID == NO_FILE_DESCRIPTOR )
{
#ifdef _DEBUG
fprintf( stderr, "Can't find the realaudio stream in the ESD server list.\n");
#endif
return RA_AOE_GENERAL;
}
#ifdef _DEBUG
fprintf( stderr, "Device Configured:\n");
fprintf( stderr, " Sample Rate: %d\n", m_unSampleRate);
fprintf( stderr, " Sample Width: %d\n", m_uSampFrameSize);
fprintf( stderr, " Num channels: %d\n", m_unNumChannels);
fprintf( stderr, " Block size: %d\n", m_wBlockSize);
fprintf( stderr, " Device buffer size: %lu\n", m_ulDeviceBufferSize);
#endif
return RA_AOE_NOERR;
}
//FREE THE RETURNED POINTER!!!!!!!!!!!!!!!
esd_player_info_t* CAudioOutESound::_GetPlayerInfo() const
{
esd_info_t *pServerInfo = NULL;
esd_player_info_t *pPlayerInfo = NULL;
esd_player_info_t *pRetVal = NULL;
pServerInfo = m_fpESDGetAllInfo(m_nESoundServerID);
if( pServerInfo == NULL )
{
#ifdef _DEBUG
fprintf( stderr, "Can't get server info from ESD.\n");
#endif
return NULL;
}
if( pServerInfo->player_list == NULL )
{
#ifdef _DEBUG
fprintf( stderr, "There seem to be no players connected to esd server.\n");
#endif
m_fpESDFreeAllInfo( pServerInfo );
return NULL;
}
pPlayerInfo = pServerInfo->player_list;
while( pPlayerInfo )
{
if( strcmp( pPlayerInfo->name, (const char *)m_strRealplayerName ) == 0 )
{
//found it.
break;
}
pPlayerInfo = pPlayerInfo->next;
}
//We found it. Make a new one and copy.
pRetVal = new esd_player_info_t(*pPlayerInfo);
if( NULL == pRetVal )
{
//OOps.
return NULL;
}
pRetVal->next = NULL; //Don't even think about it.
pRetVal->server = NULL;
// pRetVal->source_id = pPlayerInfo->source_id;
// strcpy(pRetVal->name, pPlayerInfo->name );
// pRetVal->rate = pPlayerInfo->rate;
// pRetVal->left_vol_scale = pPlayerInfo->left_vol_scale;
// pRetVal->right_vol_scale = pPlayerInfo->right_vol_scale
// pRetVal->format = pPlayerInfo->format;
//Free the info struct.
m_fpESDFreeAllInfo( pServerInfo );
return pRetVal;
}
//Device specific method to write bytes out to the audiodevice and return a
//count of bytes written.
HX_RESULT CAudioOutESound::_WriteBytes( UCHAR* buffer, ULONG32 ulBuffLength, LONG32& lCount )
{
HX_RESULT retCode = RA_AOE_NOERR;
if( m_nDevID < 0 )
{
retCode = RA_AOE_DEVNOTOPEN;
}
else
{
if( m_ulTickCount == 0 )
m_ulTickCount = GetTickCount();
lCount = ::write( m_nDevID, buffer, ulBuffLength);
if( lCount < 0 )
{
//Error occurred.
if( errno == EAGAIN )
retCode = RA_AOE_NOERR;
if( errno == EINTR )
retCode = RA_AOE_DEVBUSY;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -