Directsound 定时器播音

来源:互联网 发布:网络服务器的管理 编辑:程序博客网 时间:2024/04/28 23:51


#include "CHI_AO_DSound.h"
#include <process.h>
#include <afxwin.h>


#define  DIRECTSOUNDFRAME          20

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CHI_AO_DSound::CHI_AO_DSound()
{
 m_hWnd = NULL;
 m_pSoundBuffer8 = NULL;
 m_pDSound8  = NULL;
 m_pDSNotify = NULL;
 m_S32Volume = 0;
 m_hdlThread = NULL;
 m_pWaveFormat.cbSize = 0; //sizeof(WAVEFORMATEX);
 m_pWaveFormat.nChannels = 2;
 m_pWaveFormat.nSamplesPerSec = 8000;
 m_pWaveFormat.wBitsPerSample = 16;
 m_pWaveFormat.wFormatTag = WAVE_FORMAT_PCM;
 m_pWaveFormat.nBlockAlign = 2;
 m_pWaveFormat.nAvgBytesPerSec = 16000;
 m_dwNextPlayOffset = 0;
 m_dwNotifySize = 320;
 m_dwBuffSize = 320;

 m_AOBuffData = NULL;

 m_COMMONRingBuffer.RB_Init(PLAY_AUDIO_MAX_RB_SIZE);
 m_s32LeftNum = 0;
 m_s32RightNum = PLAY_AUDIO_PACKAGE_NUM;
 m_LastPlayLen = 0;
 m_lpGuid = NULL;
 m_bMute = HI_FALSE;
 m_u64TimeStamp = 0;
 m_hNotificationEvent = NULL;


 m_bPauseing = HI_FALSE;
 TIMECAPS tcaps;

 const int TIMER_ACCURACY = 1;
 if(timeGetDevCaps(&tcaps, sizeof(TIMECAPS)) == TIMERR_NOERROR)    
 {
  m_wAccuracy = min(max(tcaps.wPeriodMin, TIMER_ACCURACY), tcaps.wPeriodMax);
  timeBeginPeriod(m_wAccuracy);
 }
 m_TilerID_play = 0;

 m_pDataBuffer = NULL;
}


CHI_AO_DSound::~CHI_AO_DSound()
{
 if (m_AOBuffData)
 {
  delete []m_AOBuffData;
  m_AOBuffData = NULL;
 }
 if (m_pDSound8)
 {
  m_pDSound8->Release();
  m_pDSound8 = NULL;
 }
 m_COMMONRingBuffer.RB_Destroy();
 if (m_pDataBuffer)
 {
  delete []m_pDataBuffer;
  m_pDataBuffer = NULL;
 }
}


HI_VOID PASCAL CHI_AO_DSound::PlaySoundThread(UINT wTimerID, UINT msg,DWORD_PTR dwUser,DWORD_PTR dwl,DWORD_PTR dw2)
{
 __try
 {
  if (dwUser != 0)
  {
   ((CHI_AO_DSound*)dwUser)->PlayData();
  }
 }
 __except(EXCEPTION_EXECUTE_HANDLER)
 {
 }
}

HI_VOID CHI_AO_DSound::HI_AO_SetWnd(HI_VOID* hWnd)
{
 m_hWnd = (HWND)hWnd;
}


//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_Play
* 描  述        : 音频播放
* 返回类型       : HI_S32
* 参数           : UINT uFrequency
* 设计者         : lizhaozao
* 最后修订时间   : 2008-1-18 17:12:47
************************************************/

HRESULT CHI_AO_DSound::HI_AO_Play(HI_U32 u32Frequency)
{
// DirectSoundEnumerate(LPDSENUMCALLBACKA(DSEnumProc), this);
  HRESULT hResult;
 if (FAILED(hResult =  DirectSoundCreate8(NULL, &m_pDSound8, NULL)))
 {
  return hResult;
 }
 if(FAILED( hResult = m_pDSound8->SetCooperativeLevel( m_hWnd, DSSCL_PRIORITY)))
 {
  return hResult;
 }

 LPDIRECTSOUNDBUFFER          pSoundBuffer;
 DSBUFFERDESC        dsdesc;
 memset(&dsdesc,0,sizeof(DSBUFFERDESC));
 dsdesc.dwSize  = sizeof(DSBUFFERDESC);
 dsdesc.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS  | DSBCAPS_LOCSOFTWARE;
 dsdesc.dwBufferBytes  =  m_dwBuffSize;
 dsdesc.lpwfxFormat   = &m_pWaveFormat;

 if (FAILED(hResult = m_pDSound8->CreateSoundBuffer(&dsdesc, &pSoundBuffer, NULL)))
 {
  return hResult;
 }
 hResult = pSoundBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&m_pSoundBuffer8);
 pSoundBuffer->Release();
 pSoundBuffer = NULL;

 // hResult = InitNotifications();

 if (!m_AOBuffData)
 {
  m_AOBuffData = new BYTE[PLAY_AUDIO_FRAME_SIZE];
  memset(m_AOBuffData, 0, PLAY_AUDIO_FRAME_SIZE);
 }

 if (!m_pDataBuffer)
 {
  m_pDataBuffer = new HI_U8[DIRECTSOUNDFRAME * 340];
 }

 hResult = m_pSoundBuffer8->SetCurrentPosition(0);

 if (m_bMute)
 {
  hResult = m_pSoundBuffer8->SetVolume(MUTE_VALUE);
 }
 else
 {
  hResult = m_pSoundBuffer8->SetVolume((long)m_S32Volume);
 }
 StartPlay();
    return hResult;
}

//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_Stop
* 描  述        : 停止音频播放
* 返回类型       : HI_S32
* 参数           : HI_VOID
* 设计者         : lizhaozao
* 最后修订时间   : 2008-1-18 17:13:42
************************************************/

HRESULT CHI_AO_DSound::HI_AO_Stop(HI_VOID)
{
 if (m_pSoundBuffer8)
 {
  m_pSoundBuffer8->Stop();
 }
 m_bPlaying = HI_FALSE;
 if (m_hdlThread)
 {
  WaitForSingleObject(m_hdlThread, INFINITE);
  CloseHandle(m_hdlThread);
  m_hdlThread = NULL;
 }
 if (m_AOBuffData)
 {
  delete []m_AOBuffData;
  m_AOBuffData = NULL;
 }
 if (m_pSoundBuffer8)
 {
  m_pSoundBuffer8->Release();
  m_pSoundBuffer8 = NULL;
 }
 if (m_pDSound8)
 {
  m_pDSound8->Release();
  m_pDSound8 = NULL;
 }
 if(m_hNotificationEvent)
 {
//  WaitForSingleObject(m_hNotificationEvent, INFINITE);
  CloseHandle(m_hNotificationEvent);
  m_hNotificationEvent = NULL;
 }

 if (0 != m_TilerID_play)
 {
  if(TIMERR_NOERROR == timeKillEvent(m_TilerID_play))
  {
   m_TilerID_play = 0;
  }
 }
 (HI_VOID)timeEndPeriod(m_wAccuracy);
    return HI_SUCCESS;
}

//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_GetAudioPTS
* 描  述        : 获取当前播放的音频时间戳
* 返回类型       : HI_S32
* 参数           : HI_U32 *pTimeStamp
* 设计者         : lizhaozao
* 最后修订时间   : 2008-1-18 17:11:35
************************************************/
HRESULT CHI_AO_DSound::HI_AO_GetAudioPTS(HI_U64 *pTimeStamp)
{
 if (NULL == pTimeStamp)
 {
  return HI_ERR_NULL_POINTER;
 }
 /*获取当前播放的音频时间戳*/
 *pTimeStamp = m_u64TimeStamp;
    return HI_SUCCESS;
}


HRESULT CHI_AO_DSound::HI_AO_Pause()

 m_bPauseing = m_bPauseing == HI_FALSE? HI_TRUE : HI_FALSE;
    return HI_SUCCESS;
}


//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_SetMute
* 描  述        : 设置静音状态
* 返回类型       : HI_S32
* 参数           : HI_S32 s32Mute
* 设计者         : lizhaozao
* 最后修订时间   : 2008-1-18 17:12:57
************************************************/
HRESULT CHI_AO_DSound::HI_AO_SetMute(HI_BOOL bMute)
{
 if (m_bMute == bMute)
 {
  return HI_SUCCESS;
 }
 m_bMute = bMute;
 if (!m_pSoundBuffer8)
 {
  return S_OK;
 }
 HRESULT hResult;
 if (m_bMute == HI_FALSE)
 {
  hResult = m_pSoundBuffer8->SetVolume(m_S32Volume);
 }
 else
 {
  hResult = m_pSoundBuffer8->SetVolume(MUTE_VALUE);
 }
    return HI_SUCCESS;
}

 

HRESULT CHI_AO_DSound::HI_AO_SetOutFormat(const PLAYER_ATTR_AUDIO_S* struAStreamParam)
{
 if (!struAStreamParam)
 {
  return HI_ERR_NULL_POINTER;
 }
 m_pWaveFormat.cbSize = 0;
 m_pWaveFormat.nBlockAlign = struAStreamParam->lBlockAlign;
 m_pWaveFormat.nChannels = struAStreamParam->lChannels;
 m_pWaveFormat.wFormatTag = WAVE_FORMAT_PCM;
 m_pWaveFormat.nSamplesPerSec = struAStreamParam->lSamplesPerSec;
 m_pWaveFormat.nAvgBytesPerSec = struAStreamParam->lSamplesPerSec * struAStreamParam->lBlockAlign;
 m_pWaveFormat.wBitsPerSample = 16;
 switch(struAStreamParam->lBitsPerSample)
 {
 case 8:
  m_dwNotifySize = 640 * 3;
  m_dwBuffSize = 640 * 3;
  m_unTimeEscape = 40 * 3;
  break;
 case 16:
  m_dwNotifySize = 320;
  m_dwBuffSize = 320;
  m_unTimeEscape = 20;
  break;
 case 4:
  m_dwNotifySize = 640;
  m_dwBuffSize  = 640;
  m_unTimeEscape = 40;
  break;
 }
 m_dwNotifySize = 320 * DIRECTSOUNDFRAME;
 m_dwBuffSize = 320 * DIRECTSOUNDFRAME;
 m_unTimeEscape = 20 * DIRECTSOUNDFRAME;
    return HI_SUCCESS;
}

HRESULT CHI_AO_DSound::HI_AO_GetOutFormat(PLAYER_ATTR_AUDIO_S *pAStreamParam)
{
 if (!pAStreamParam)
 {
  return HI_ERR_NULL_POINTER;
 }
 pAStreamParam->lChannels = m_pWaveFormat.nChannels;
 pAStreamParam->lSamplesPerSec = m_pWaveFormat.nSamplesPerSec;
 pAStreamParam->lBitsPerSample = m_pWaveFormat.wBitsPerSample;
 pAStreamParam->lBlockAlign = m_pWaveFormat.nBlockAlign;
    return HI_SUCCESS;
}

//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_ClearRb
* 描  述        : 清空视频rb
* 返回类型       : HI_S32
* 参数           : HI_VOID
* 设计者         : lizhaozao
* 最后修订时间   : 2007-1-16 21:15:03
************************************************/
HI_S32 CHI_AO_DSound::HI_AO_ClearRb(HI_VOID)
{
    /*清空Rb,清空rb中数据*/
    m_COMMONRingBuffer.RB_Clear();
    return HI_SUCCESS;
}

//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_GetMuteState
* 描  述        : 获取静音状态
* 返回类型       : HI_S32
* 参数           : LONG *pMuteState
* 设计者         : lizhaozao
* 最后修订时间   : 2008-1-18 17:11:55
************************************************/
HRESULT CHI_AO_DSound::HI_AO_GetMuteState(HI_BOOL *pMuteState)
{
    if (NULL == pMuteState)
    {
        return HI_ERR_NULL_POINTER;
    }
 *pMuteState = m_bMute;
    return HI_SUCCESS;
}

//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_SetPara
* 描  述        : 设置同步参数
* 返回类型       : HI_S32
* 参数           : HI_S32 s32Dowm
* 参数           : HI_S32 s32Up
* 设计者         : lizhaozao
* 最后修订时间   : 2008-1-18 17:13:10
************************************************/
HI_S32 CHI_AO_DSound::HI_AO_SetPara(HI_S32 s32Dowm, HI_S32 s32Up)
{
    if ((s32Dowm >= s32Up) || (s32Dowm < 0) || (s32Up < 0))
    {
        /*无效的同步参数,上限必须大于下限*/
        return HI_ERR_INVALID_ARGUMENTS;
    }
 m_s32RightNum = s32Up;
 m_s32LeftNum = s32Dowm;
    return HI_SUCCESS;
}

//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_GetAudioNodesNum
* 描  述        : 获取当前音频rb中的音频包个数
* 返回类型       : HI_S32
* 参数           : LONG *pNodesNum
* 设计者         : lizhaozao
* 最后修订时间   : 2007-1-16 22:45:51
************************************************/
HI_S32 CHI_AO_DSound::HI_AO_GetAudioNodesNum(LONG *pNodesNum)
{
    if (NULL == pNodesNum)
    {
        return HI_ERR_NULL_POINTER;
    }
    *pNodesNum = (LONG)m_COMMONRingBuffer.RB_GetNodeNums();

    return HI_SUCCESS;
}

//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_GetPara
* 描  述        : 获取音频同步参数
* 返回类型       : HI_S32
* 参数           : LONG *pDowm
* 参数           : LONG *pUp
* 设计者         :
* 最后修订时间   : 2008-1-18 17:12:11
************************************************/
HI_S32 CHI_AO_DSound::HI_AO_GetPara(LONG *pDowm, LONG *pUp)
{
 if ((NULL == pDowm) || (NULL == pUp))
 {
  return HI_ERR_NULL_POINTER;
 }
 /*获取同步参数*/
 *pUp = m_s32RightNum;
 *pDowm = m_s32LeftNum;
    return HI_SUCCESS;
}

//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_SetVolume
* 描  述        : 设置左右声道的音量
* 返回类型       : HI_S32
* 参数           : WORD wLeftVolume
* 参数           : WORD wRightVolume
* 设计者         : lizhaozao
* 最后修订时间   : 2008-1-18 17:13:25
************************************************/

HRESULT CHI_AO_DSound::HI_AO_SetVolume(HI_U32 u32LeftVolume, HI_U32 u32RightVolume)
{
 if ((u32LeftVolume > MAX_AUDIO_VOLUME) || (u32RightVolume > MAX_AUDIO_VOLUME) )
 {
  /*非法音量参数*/
  return HI_ERR_INVALID_ARGUMENTS;
 }
 u32RightVolume *= 100;
 u32RightVolume /= 0xffff;
 m_S32Volume = u32RightVolume;
 m_S32Volume = ((HI_S32)u32RightVolume - 100) * VOLUME_WEIGHT + VOLUME_OFFSET;
 if ( m_pSoundBuffer8)
 {
  if (!m_bMute)
  {
   HRESULT hResult =  m_pSoundBuffer8->SetVolume((LONG)m_S32Volume);
  }
 }
    return HI_SUCCESS;
}

//////////////////////////////////////////////////////////////////////////
/************************************************
* 函数名      : CHI_AO_DSound::HI_AO_GetVolume
* 描  述        : 获取左右声道音量
* 返回类型       : HI_S32
* 参数           : LONG *pLeftVolume
* 参数           : LONG *pRightVolume
* 设计者         : lizhaozao
* 最后修订时间   : 2008-1-18 17:12:25
************************************************/

HRESULT CHI_AO_DSound::HI_AO_GetVolume(HI_U32 *pLeftVolume, HI_U32 *pRightVolume)
{
 if ((NULL == pLeftVolume) && (NULL == pRightVolume))
 {
  return HI_ERR_NULL_POINTER;
 }
 /*获取左声道的音量*/
 if (pLeftVolume)
 {
  *pLeftVolume = ((m_S32Volume -  VOLUME_OFFSET)/ VOLUME_WEIGHT + 100) * 0xffff / 100;
 }
 /*获取右声道的音量*/
 if (pRightVolume)
 {
  *pRightVolume = *pLeftVolume;
 }
    return HI_SUCCESS;
}

BOOL CHI_AO_DSound::DSEnumProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext)
{
 CHI_AO_DSound *ChiAO_DSound = (CHI_AO_DSound*)lpContext;
 if (lpGUID)
 {
  ChiAO_DSound->m_lpGuid = lpGUID;
 }
 return TRUE;
}

HRESULT CHI_AO_DSound::InitNotifications()
{
 if(!m_pSoundBuffer8 )
 {
  return E_FAIL;
 }
 HRESULT hr;
  
 if(FAILED(hr = m_pSoundBuffer8 ->QueryInterface(IID_IDirectSoundNotify,(VOID**)&m_pDSNotify)))
 {
  return hr;
 }
 for( INT i = 0; i < NUM_PLAY_NOTIFICATIONS; i++ )
 {
  m_hNotificationEvent = CreateEvent(NULL,FALSE,TRUE,NULL); //
  m_aPosNotify.dwOffset = m_dwNotifySize * (i + 1)  - 1;
  m_aPosNotify.hEventNotify = m_hNotificationEvent;
 }
 if(FAILED( hr =m_pDSNotify->SetNotificationPositions( NUM_PLAY_NOTIFICATIONS, &m_aPosNotify)))
 {
 }
 m_pDSNotify->Release();
 m_pDSNotify = NULL;
 return hr;
}


void CHI_AO_DSound::StartPlay()
{
 if (!m_pSoundBuffer8)
 {
  return;
 }
//  LPVOID lplockbuf1;
//  DWORD len1;
//  LPVOID lplockbuf2;
//  DWORD len2;
//
//  m_pSoundBuffer8->Lock(0,0,&lplockbuf1,&len1, NULL , NULL,DSBLOCK_ENTIREBUFFER);
//  if (lplockbuf1)
//  {
//   memset(lplockbuf1, 0, len1);
//  }
//  m_pSoundBuffer8->Unlock(lplockbuf1,len1,NULL,0);
//  m_pSoundBuffer8->SetCurrentPosition(0);
//  m_pSoundBuffer8->Play(0,0,DSBPLAY_LOOPING );
//  m_dwNextPlayOffset = 0;


 if (0 == m_TilerID_play)
 {
  m_TilerID_play =  timeSetEvent(m_unTimeEscape, m_wAccuracy, (LPTIMECALLBACK)PlaySoundThread,
   (DWORD_PTR)this, TIME_PERIODIC);
 }
//  m_hdlThread = (HANDLE)_beginthreadex(NULL, 0, ThreadPlay, this, 0, NULL);
//  if(!m_hdlThread)
//  {
//   return;
//  }
}

HI_U32 CHI_AO_DSound::ThreadPlay(LPVOID lpParam)
{
 CHI_AO_DSound* pAODSound = (CHI_AO_DSound*)lpParam; 

 LPVOID lplockbuf1;
 DWORD len1;

 pAODSound->m_pSoundBuffer8->Lock(0,0,&lplockbuf1,&len1, NULL , NULL,DSBLOCK_ENTIREBUFFER);
 if (lplockbuf1)
 {
  memset(lplockbuf1, 0, len1);
 }
 pAODSound->m_pSoundBuffer8->Unlock(lplockbuf1,len1,NULL,0);
 pAODSound->m_pSoundBuffer8->SetCurrentPosition(0);
 pAODSound->m_pSoundBuffer8->Play(0,0,DSBPLAY_LOOPING);
 pAODSound->m_dwNextPlayOffset = 0;
 OSVERSIONINFO  osVer;
 osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 BOOL b = GetVersionEx(&osVer);
 HI_S32 s32Sleep = 18;
 if (osVer.dwMajorVersion == 5 && osVer.dwMinorVersion == 1) // xp 系统
 {
  s32Sleep = 100;
 }
 DWORD dwResult =0;
 pAODSound->m_bPlaying = HI_TRUE;

 while(pAODSound->m_bPlaying)
 {
  dwResult = WaitForSingleObject( pAODSound->m_hNotificationEvent, s32Sleep);
  switch( dwResult )
  {
  case WAIT_OBJECT_0:
   pAODSound->PlayData();
   break;
  default: // win7 系统启动不了事件,强制超时处理。
   pAODSound->PlayData();
   break;
  }
 }
 return 0;
}

HRESULT CHI_AO_DSound::PlayData()
{
 if (m_bPauseing == HI_TRUE)
 {
  return 0;
 }
 HRESULT  hResult;
 DWORD dwReadPos;
 DWORD dwPlayPos;
 LONG lLockSize;
 VOID *pbPlayData1 = NULL;
 DWORD dwPlayLength1;
 VOID *pbPlayData2 = NULL;
 DWORD dwPlayLength2;
 HI_U32 u32Lenght = 0;

 int nBuffPos = 0;
 if(FAILED(hResult = m_pSoundBuffer8->GetCurrentPosition(&dwPlayPos ,&dwReadPos)))
 {
  return hResult;
 }
 lLockSize = dwReadPos - m_dwNextPlayOffset;
 if (lLockSize <  0)
 {
  lLockSize += m_dwBuffSize;
 }
 HI_S32 s32NodeNum =  m_COMMONRingBuffer.RB_GetNodeNums();
 static HI_U32 u32Len = 0;
 if (u32Len == 0)
 {
  if (s32NodeNum != 0)
  {
   u32Len =  m_COMMONRingBuffer.RB_GetLen_X();
  }
 }

 if (s32NodeNum <( DIRECTSOUNDFRAME / ((u32Len == 328) ? 1:2)))
 {
  if ((hResult = m_pSoundBuffer8->Lock(m_dwNextPlayOffset, m_dwNotifySize, &pbPlayData1, &dwPlayLength1, &pbPlayData2, &dwPlayLength2, 0)) == DSERR_BUFFERLOST)
  {
   m_pSoundBuffer8->Restore();
   hResult = m_pSoundBuffer8->Lock(m_dwNextPlayOffset,m_dwNotifySize, &pbPlayData1, &dwPlayLength1, &pbPlayData2, &dwPlayLength2, 0);
  }
  if (FAILED(hResult))
  {
   goto END;
   return hResult;
  }
  char *pTempBuffer = new char[dwPlayLength1 + dwPlayLength2 + 1];
  memset(pTempBuffer,0 ,dwPlayLength1 + dwPlayLength2 + 1);
  for(HI_S32 S32Num = 0; S32Num < s32NodeNum; S32Num++)
  {
   HI_S32  s32Rel = m_COMMONRingBuffer.RB_Read_X(m_AOBuffData + m_LastPlayLen, &u32Lenght);
   memcpy(pTempBuffer + nBuffPos, m_AOBuffData + m_LastPlayLen + sizeof(HI_AUDIOSample), u32Lenght - sizeof(HI_AUDIOSample));
   nBuffPos += u32Lenght - sizeof(HI_AUDIOSample);
   if (u32Lenght < 0)
   {
    goto END;
   }
   m_LastPlayLen += u32Lenght;
  }
//  m_LastPlayLen -= (m_dwNotifySize + sizeof(HI_AUDIOSample));
  m_LastPlayLen = 0;
  if (pbPlayData1)
  {
   CopyMemory(pbPlayData1, pTempBuffer , dwPlayLength1);
   m_dwNextPlayOffset += dwPlayLength1;
  }
  if (pbPlayData2)
  {
   CopyMemory(pbPlayData2, pTempBuffer + dwPlayLength1, dwPlayLength2);
   m_dwNextPlayOffset += dwPlayLength2;
  }
  hResult = m_pSoundBuffer8->Unlock(pbPlayData1, dwPlayLength1, pbPlayData2, dwPlayLength2);
  m_dwNextPlayOffset %= m_dwBuffSize;
  hResult = m_pSoundBuffer8->Play(0, 0 , DSBPLAY_LOOPING);

  if (pTempBuffer)
  {
   delete []pTempBuffer;
   pTempBuffer = NULL;
  }

  return 0;
  u32Lenght = m_dwNotifySize/*BUFFER_NOTIFY_SIZE*/;
  memset(m_AOBuffData, 0, u32Lenght);
 }
 if (s32NodeNum <= m_s32LeftNum )
 { // 补充静音数据
 }
 else
 {
  if (s32NodeNum >= m_s32RightNum)
  {// 丢4个音频包
   HI_S32 s32Lost = s32NodeNum - 4;
   for (HI_S32 i = 0; i <s32Lost; i++)
   {
    m_COMMONRingBuffer.SkipOneNodeReadPos();
   }
  }
 }
 DWORD nPos = m_LastPlayLen + sizeof(HI_AUDIOSample);

 while (m_LastPlayLen < m_dwNotifySize  + sizeof(HI_AUDIOSample) * (DIRECTSOUNDFRAME / ((u32Len == 328)? 1 : 2 ) ))
 {
  HI_S32  s32Rel = m_COMMONRingBuffer.RB_Read_X(m_AOBuffData + m_LastPlayLen, &u32Lenght);
  HI_AUDIOSample audioSample;
  memcpy(&audioSample, m_AOBuffData + m_LastPlayLen, sizeof(HI_AUDIOSample));
  if (s32Rel != HI_SUCCESS)
  {
   goto END;
   return S_FALSE;
  }
  memcpy(m_pDataBuffer + nBuffPos, m_AOBuffData + m_LastPlayLen + sizeof(HI_AUDIOSample), u32Lenght - sizeof(HI_AUDIOSample));
  nBuffPos += u32Lenght - sizeof(HI_AUDIOSample);
  if (u32Lenght < 0)
  {
   goto END;
  }
  m_LastPlayLen += u32Lenght;
 }
// m_LastPlayLen -= (m_dwNotifySize + sizeof(HI_AUDIOSample));
 m_LastPlayLen = 0;
  
 if ((hResult = m_pSoundBuffer8->Lock(m_dwNextPlayOffset, m_dwNotifySize, &pbPlayData1, &dwPlayLength1, &pbPlayData2, &dwPlayLength2, 0)) == DSERR_BUFFERLOST)
 {
  m_pSoundBuffer8->Restore();
  hResult = m_pSoundBuffer8->Lock(m_dwNextPlayOffset,m_dwNotifySize, &pbPlayData1, &dwPlayLength1, &pbPlayData2, &dwPlayLength2, 0);
 }
 if (FAILED(hResult))
 {
  goto END;
  return hResult;
 }
 if (pbPlayData1)
 {
  CopyMemory(pbPlayData1, m_pDataBuffer , dwPlayLength1);
  m_dwNextPlayOffset += dwPlayLength1;
 }
 if (pbPlayData2)
 {
  CopyMemory(pbPlayData2, m_pDataBuffer + dwPlayLength1, dwPlayLength2);
  m_dwNextPlayOffset += dwPlayLength2;
 }
 hResult = m_pSoundBuffer8->Unlock(pbPlayData1, dwPlayLength1, pbPlayData2, dwPlayLength2);
 m_dwNextPlayOffset %= m_dwBuffSize;
 hResult = m_pSoundBuffer8->Play(0, 0 , DSBPLAY_LOOPING);
END:
 return hResult;
}