分享

alsa播放音频类

 昵称17328427 2014-07-25

alsa播放音频类  

2012-10-26 09:53:57|  分类: Linux |举报 |字号 订阅

//CAudioplayer.h
#include <alsa/asoundlib.h>
class CAudioPlayer
{
public:
CAudioPlayer();
~CAudioPlayer();

bool InitPlayer(int iHwnd, int iSampleRate, char nBits,
char nChannels, int iFrameSize);
bool OpenPlayer();
void ClosePlayer();
void PlaySound(char *pszBuffer, int iSize, int iMillSec);

bool PausePlay();
bool ResumePlay();
private:
bool m_bFirstPlay; //第一次播放
int m_iHwnd; //播放窗口句柄
int m_iFrameSize; //帧数据大小

int m_iSampleRate; //采样率
char m_nSampleBits; //位宽
char m_nChannels; //通道数

snd_pcm_sw_params_t *m_sw_params;
snd_pcm_hw_params_t *m_params;
snd_pcm_t *m_hDevice;
int m_iBytesPerSample;
int m_iBufferSize;
int m_iBytesPerPeriod;
};

//CAudioplayer.cpp
#include "audioplayer.h"
#define THIS_FILE "audioplayer.cpp"

CAudioPlayer::CAudioPlayer()
{
m_bFirstPlay = true; //第一次播放
m_iHwnd = NULL; //播放窗口句柄
m_iFrameSize = 0; //帧数据大小

m_iSampleRate = 8000; //采样率
m_nSampleBits = 16; //位宽
m_nChannels = 1; //通道数

m_sw_params = NULL;
m_params = NULL;
m_hDevice = NULL;
m_iBytesPerSample = 0;
m_iBufferSize = 0;
m_iBytesPerPeriod = 0;

}


CAudioPlayer::~CAudioPlayer()
{
ClosePlayer();

}


bool CAudioPlayer::InitPlayer(int iHwnd, int iSampleRate, char nBits,
char nChannels, int iFrameSize)
{
m_bFirstPlay = true;
m_iHwnd = iHwnd;
m_iFrameSize = iFrameSize;

m_iSampleRate = iSampleRate;
m_nSampleBits = nBits;
m_nChannels = nChannels;

return true;
}


bool CAudioPlayer::OpenPlayer()
{

m_iBytesPerSample = m_nChannels*m_nSampleBits/8;

int rc = snd_pcm_open(&m_hDevice, "default", SND_PCM_STREAM_PLAYBACK, 0);
if( rc < 0 )
{
return false;
}

if( snd_pcm_nonblock( m_hDevice, 1 ) < 0 )
{
WriteLog("snd_pcm_nonblock error");
return false;
}

snd_pcm_hw_params_alloca( &m_params );
snd_pcm_sw_params_alloca(&m_sw_params);

if( (rc = snd_pcm_hw_params_any( m_hDevice, m_params ) ) < 0 )
{
return false;
}


rc = snd_pcm_hw_params_set_access(m_hDevice, m_params, SND_PCM_ACCESS_RW_INTERLEAVED);
if ( rc < 0 )
{
WriteLog("audioplayer set hw access failed!");
return false;
}

if( ( rc = snd_pcm_hw_params_set_format(m_hDevice, m_params, SND_PCM_FORMAT_S16_LE) ) < 0 )
{
WriteLog("audioplayer set hw format failed!");
return false;
}

WriteLog("%s set channels:%d!", THIS_FILE, m_nChannels);
if( ( rc = snd_pcm_hw_params_set_channels(m_hDevice, m_params, m_nChannels) ) < 0 )
{
WriteLog("audioplayer set hw channels failed!");
return false;
}


//samplerate
int val = m_iSampleRate;
WriteLog("%s set rate:%d!", THIS_FILE, val);
if( ( rc = snd_pcm_hw_params_set_rate_near( m_hDevice, m_params, (unsigned int *)&val, NULL ) ) < 0 )
{
WriteLog("audioplayer set hw rate failed!");
return false;
}
WriteLog("%s rate set to:%d!", THIS_FILE, val);


//hardware buffer times
unsigned int ibuffertime = 500000;
if ( ( rc = snd_pcm_hw_params_set_buffer_time_near( m_hDevice, m_params, &ibuffertime, NULL ) ) < 0 )
{
WriteLog("audioplayer set hw buffer time failed!");
return false;
}

//cache count
unsigned int fragcount = 16;
if ( ( rc = snd_pcm_hw_params_set_periods_near( m_hDevice, m_params, &fragcount, NULL ) ) < 0 )
{
WriteLog("audioplayer set hw periods failed!");
return false;
}


/* finally install hardware parameters */
if ( ( rc = snd_pcm_hw_params(m_hDevice, m_params ) ) < 0 )
{
WriteLog("audioplayer set hw params failed!");
return false;
}
// end setting hw-params

// gets buffersize for control
snd_pcm_uframes_t bufsize = 0;
if ( ( rc = snd_pcm_hw_params_get_buffer_size( m_params, &bufsize ) ) < 0 )
{
return false;
}
else
{
m_iBufferSize = bufsize * m_iBytesPerSample;
WriteLog("audioplayer get buffersize = %d", m_iBufferSize);
}

//get sample count per period
snd_pcm_uframes_t chunksize = 0;
if ( ( rc = snd_pcm_hw_params_get_period_size( m_params, &chunksize, NULL ) ) < 0 )
{
WriteLog("audioplayer get period failed!");
return false;
}
else
{
WriteLog("audioplayer get period = %d", chunksize);
}
m_iBytesPerPeriod = chunksize * m_iBytesPerSample;

/* setting software parameters */
if ( ( rc = snd_pcm_sw_params_current( m_hDevice, m_sw_params ) ) < 0 )
{
WriteLog("audioplayer sw params current failed, errorcode = %s", snd_strerror(rc) );
return false;
}

/* start playing when one period has been written */
if ( ( rc = snd_pcm_sw_params_set_start_threshold( m_hDevice, m_sw_params, chunksize ) ) < 0 )
{
WriteLog("audioplayer sw params start threshold failed, errorcode = %s", snd_strerror(rc) );
return false;
}

snd_pcm_uframes_t boundary;
if ( ( rc = snd_pcm_sw_params_get_boundary( m_sw_params, &boundary ) ) < 0 )
{
WriteLog("audioplayer sw params get boundary failed, errorcode = %s", snd_strerror(rc) );
return false;
}

/* disable underrun reporting */
if ( ( rc = snd_pcm_sw_params_set_stop_threshold(m_hDevice, m_sw_params, boundary ) ) < 0 )
{
WriteLog("audioplayer sw params stop threshold failed, errorcode = %s", snd_strerror(rc) );
return false;
}

/* play silence when there is an underrun */
if ( ( rc = snd_pcm_sw_params_set_silence_size( m_hDevice, m_sw_params, boundary ) ) < 0 )
{
WriteLog("audioplayer sw params set silence size failed, errorcode = %s", snd_strerror(rc) );
return false;
}

if ( ( rc = snd_pcm_sw_params( m_hDevice, m_sw_params ) ) < 0 )
{
WriteLog("audioplayer sw params failed, errorcode = %s", snd_strerror(rc) );
return false;
}
/* end setting sw-params */

return true;
}


void CAudioPlayer::ClosePlayer()
{
m_bFirstPlay = true;

if( NULL != m_hDevice )
{
snd_pcm_drain(m_hDevice);
snd_pcm_close(m_hDevice);
m_hDevice = NULL;
}
}


void CAudioPlayer::PlaySound(char *pszBuffer, int iSize, int iMillSec)
{
if(NULL == pszBuffer)
{
return;
}

int iNumFrames = 0;
snd_pcm_sframes_t res = 0;

iNumFrames = iSize/m_iBytesPerSample;

do
{
res = snd_pcm_writei( m_hDevice, pszBuffer, iNumFrames );
if ( res == -EINTR )
{
res = 0;
}
else if ( res == -ESTRPIPE )
{
WriteLog("audio player play return -ESTRPIPE1");
while ( (res = snd_pcm_resume(m_hDevice)) == -EAGAIN )
{
WriteLog("audio player play return -ESTRPIPE2");
Tos_thread_sleep(1);
}
}

if ( res < 0 )
{
if ( ( res = snd_pcm_prepare(m_hDevice) ) < 0 )
{
return ;
}
}
} while (res == 0);

}


bool CAudioPlayer::PausePlay()
{
int err = 0;
if ( (err = snd_pcm_drop(m_hDevice)) < 0 )
{
return false;
}

return true;
}

bool CAudioPlayer::ResumePlay()
{
int err = 0;
if((err = snd_pcm_prepare(m_hDevice)) < 0)
{
return false;
}

return true;
}


阅读(609)| 评论(2)
|      
喜欢 推荐 转载

最近读者

热度

评论

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多