程序实现方法:    线城函数()
    {
        unsigned char* pa = new unsigned char[length];        pa = GetData();        dsound->filldata();        while (1)
        {
            if (dsound->isplay())
                 continus;            dsound->play();
            
            pa = GetData();            dsound->filldata();
        }
     }问题:    我每次得到1秒钟的数据,为什么声音会出现“扑哧”的噪音或停顿。

解决方案 »

  1.   

    你的缓冲区要分段, 类似环型缓冲区, 一段一段的填充, 系统在后台一段一段的播放你填好的缓冲区. 这样数据填充和播放的工作是并行的. 你可以看看DX SDK 8.1里面的例子. 其有不少是DirectSound的. 但其中的回放大多是直接建一个大的缓冲区的. 不过可以看关于SoundCapture的, 这方面就没有办法建一个大缓冲区了. 回放和Capture的使用方法差不多...
      

  2.   

    同意vcsongs(vcsongs)
    Ex:
    m_pIDirectSoundBuffer->QueryInterface(IID_IDirectSoundNotify,(LPVOID*)&m_pIDirectSoundNotify);
    m_pIDirectSoundNotify->SetNotificationPositions(2,m_DSBPOSITIONNOTIFY);
    播放时把buffer一段一段的填充到播放的buffer
    在SDK查SetNotificationPositions在关联的function可以找到更多的smaple
      

  3.   

    while (1)
            {
                if (dsound->isplay())//你在PLAY完了一段数据之后才写新数据
                     continus;            dsound->play();
                
                pa = GetData();            dsound->filldata();
            }
    你在PLAY完了一段数据之后才写新数据,当然会有停顿. 你PLAY的时候指定为循环播放(此时PLAY只需要执行一次).播放时DIRECT SOUND BUFFER有2个指针,一个指向当前播放的地方, 一个指向当前填写新数据的地方.你往第二个指针指向的地方写数据就可以了.void CEIENDSBuffer::Play()
    {
    DWORD dwStatus;
    if( m_lpDSBuffer )
      if (DS_OK == m_lpDSBuffer->GetStatus(&dwStatus))
        if((dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING)
          m_lpDSBuffer->Play(0, 0, DSBPLAY_LOOPING); //循环播放
    }
    void CEIENDSBuffer::WriteData( UINT length, unsigned char* pData )
    {
      DWORD CurrentWriteCursor;
      DWORD dwAudioBytes1;
      DWORD dwAudioBytes2;
      LPVOID pvAudioPtr1; 
      LPVOID pvAudioPtr2;
      HRESULT mmr;
      mmr = m_lpDSBuffer->GetCurrentPosition( NULL, 
            &CurrentWriteCursor );
      if( mmr == DS_OK )
      {//锁定内存,具体见DIRCT X SDK HELP
        mmr = m_lpDSBuffer->Lock( CurrentWriteCursor, length, 
              &pvAudioPtr1, &dwAudioBytes1, &pvAudioPtr2,    
               &dwAudioBytes2, 0 );
        if(mmr == DS_OK)
        {  
          if( pvAudioPtr1 )
            memcpy( pvAudioPtr1, pData, dwAudioBytes1 );
          if( pvAudioPtr2 )
            memcpy( pvAudioPtr2, pData + dwAudioBytes1, dwAudioBytes2 );
          m_lpDSBuffer->Unlock( pvAudioPtr1, dwAudioBytes1,   
                  pvAudioPtr2,dwAudioBytes2 );
        }
      }
    }
      

  4.   

    在其中一段数据播完之后写入新数据, 如 skqgd() 所说, 用NOTITY.