日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DirectSound 混音的实现

發布時間:2023/12/9 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DirectSound 混音的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

啥叫混音呢,其實很簡單,如果兩個人同時說話 ,他們倆發出的聲波在空氣中進行了波的疊加,這其實就是個混音。計算機的混音,其實是一個虛擬的混音操作,因為計算機其實是只有一個聲源(現在的計算機通常有兩聲道甚至5聲道的立體聲,先忽略這些,我們先抽象,把計算機看作一個聲源),通過在計算機內部進行運算,把兩個波形進行疊加運算,然后由計算機唯一的音箱輸出,這就是計算機混音技術。微軟的API PlaySound是不支持混音的,調用一個PlaySound的時候,會終止上一個PlaySound調用所播放的聲音(異步調用),如果要用PlaySound來實現混音效果,就需要自己寫一個混音算法。幸運的是,該疊加算法不需要我們去寫,微軟的DirectX早已提供給我們了現成的算法,而且非常強大,參與疊加的每個聲音分量甚至都能夠有自己獨立的空間坐標,這也就是3D音效了。我們不需要3d音效,只要能夠多路混音就可以了,晚上找到一個開源的對DirectSound的封裝,非常好用,現把代碼公開如下:

-------------------------------------------------------------------------------------------------

// DSBuffer.h : Definition of CDSBuffer class
//

#if !defined(AFX_DSBUFFER_H__7517D749_96E3_11D2_BBF3_9EB4940D843C__INCLUDED_)
#define AFX_DSBUFFER_H__7517D749_96E3_11D2_BBF3_9EB4940D843C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <mmsystem.h>
#include <dsound.h>

struct WaveHeader
{
BYTE RIFF[4]; // "RIFF"
DWORD dwSize; // Size of data to follow
BYTE WAVE[4]; // "WAVE"
BYTE fmt_[4]; // "fmt "
DWORD dw16; // 16
WORD wOne_0; // 1
WORD wChnls; // Number of Channels
DWORD dwSRate; // Sample Rate
DWORD BytesPerSec; // Sample Rate
WORD wBlkAlign; // 1
WORD BitsPerSample; // Sample size
BYTE DATA[4]; // "DATA"
DWORD dwDSize; // Number of Samples
};

class CDSBuffer : public CObject
{
// Attribute
protected:
LPDIRECTSOUNDBUFFER m_lpDSBuffer; // Sound buffer
LPDIRECTSOUND3DBUFFER m_lpDS3DBuffer; // 3D buffer

// Construction / Destruction
public:
CDSBuffer();
CDSBuffer(const char* FileName, LPDIRECTSOUND lpDS, DWORD dwFlags = DSBCAPS_CTRLDEFAULT);
~CDSBuffer();

// Methods
public:
BOOL PlaySound(DWORD dwFlags);
BOOL StopSound();
BOOL CreateSoundBuffer(LPDIRECTSOUND lpDS, DWORD dwFlags, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo);
BOOL ReadData(FILE* pFile, DWORD dwSize, DWORD dwPos);
BOOL IsValid();
LPDIRECTSOUNDBUFFER GetBuffer() { return m_lpDSBuffer;}
LPDIRECTSOUND3DBUFFER Get3DBuffer() { return m_lpDS3DBuffer;}
};


#endif // !defined(AFX_DSBUFFER_H__7517D749_96E3_11D2_BBF3_9EB4940D843C__INCLUDED_)

-------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------

///
// //
// DirectSound Mixer //
// //
// V1.0 by lob_b@hotmail.com 1999 //
// //
// with core inputs from //
// Stack-Up //
// V1.0 ?Tool@theWaterCooler.com 1998 //
// http://www.theWaterCooler.com/Tool //
// also Petr.Stejskal@vslib.cz //
// //
///

// DSBuffer.cpp : Implementation of CDSBuffer class
//

#include "stdafx.h"
#include "DSBuffer.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CDSBuffer

CDSBuffer::CDSBuffer()
{
// Reset the sound buffer
m_lpDSBuffer = NULL;

// Reset the 3D buffer
m_lpDS3DBuffer = NULL;
}

CDSBuffer::CDSBuffer(const char *FileName, LPDIRECTSOUND lpDS, DWORD dwFlags)
{
// Reset the sound buffer
m_lpDSBuffer = NULL;

// Reset the 3D buffer
m_lpDS3DBuffer = NULL;

// Open the wave file
FILE* pFile = fopen(FileName, "rb");
if(!pFile)
return;

// Read in the wave header
WaveHeader wavHdr;
if (fread(&wavHdr, sizeof(wavHdr), 1, pFile) != 1)
{
fclose(pFile);
return;
}

// Figure out the size of the data region
DWORD dwSize = wavHdr.dwDSize;

// Is this a stereo or mono file?
BOOL bStereo = wavHdr.wChnls > 1 ? true : false;

// Create the sound buffer for the wave file
if(CreateSoundBuffer(lpDS, dwFlags, dwSize, wavHdr.dwSRate, wavHdr.BitsPerSample, wavHdr.wBlkAlign, bStereo))
{
// Read the data for the wave file into the sound buffer
if (!ReadData(pFile, dwSize, sizeof(wavHdr)))
AfxMessageBox("Error - DS - Reading Data");
else if (dwFlags & DSBCAPS_CTRL3D)
{
// Get pointer to 3D buffer
if (S_OK != m_lpDSBuffer->QueryInterface(IID_IDirectSound3DBuffer, (void **)&m_lpDS3DBuffer))
AfxMessageBox("DirectSound3DBuffer not available");
}
}

fclose(pFile);
}


CDSBuffer::~CDSBuffer()
{
StopSound();
if(m_lpDSBuffer)
{
m_lpDSBuffer->Release();
}

if(m_lpDS3DBuffer)
{
m_lpDS3DBuffer->Release();
}
}


BOOL CDSBuffer::CreateSoundBuffer(LPDIRECTSOUND lpDS, DWORD dwFlags, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo)
{
PCMWAVEFORMAT pcmwf;
DSBUFFERDESC dsbdesc;

// Set up wave format structure.
memset( &pcmwf, 0, sizeof(PCMWAVEFORMAT) );
pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.wf.nChannels = bStereo ? 2 : 1;
pcmwf.wf.nSamplesPerSec = dwFreq;
pcmwf.wf.nBlockAlign = (WORD)dwBlkAlign;
pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
pcmwf.wBitsPerSample = (WORD)dwBitsPerSample;

// Set up DSBUFFERDESC structure.
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // Zero it out.
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = dwFlags;
dsbdesc.dwBufferBytes = dwBufSize;
dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;

if (DS_OK != lpDS->CreateSoundBuffer(&dsbdesc, &m_lpDSBuffer, NULL))
{
AfxMessageBox("Error - DS - CreateSoundBuffer");
return FALSE;
}

return TRUE;
}


BOOL CDSBuffer::ReadData(FILE* pFile, DWORD dwSize, DWORD dwPos)
{
// Seek to correct position in file (if necessary)
if (dwPos != 0xffffffff)
{
if (fseek(pFile, dwPos, SEEK_SET) != 0)
{
return FALSE;
}
}

// Lock data in buffer for writing
LPVOID pData1;
DWORD dwData1Size;
LPVOID pData2;
DWORD dwData2Size;
HRESULT rval;

rval = m_lpDSBuffer->Lock(0, dwSize, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_FROMWRITECURSOR);
if (rval != DS_OK)
{
return FALSE;
}

// Read in first chunk of data
if (dwData1Size > 0)
{
if (fread(pData1, dwData1Size, 1, pFile) != 1)
{
return FALSE;
}
}

// read in second chunk if necessary
if (dwData2Size > 0)
{
if (fread(pData2, dwData2Size, 1, pFile) != 1)
{
return FALSE;
}
}

// Unlock data in buffer
rval = m_lpDSBuffer->Unlock(pData1, dwData1Size, pData2, dwData2Size);
if (rval != DS_OK)
{
return FALSE;
}

return TRUE;
}

BOOL CDSBuffer::PlaySound(DWORD dwFlags)
{
if(m_lpDSBuffer) // Make sure we have a valid sound buffer
{
DWORD dwStatus;
if (DS_OK != m_lpDSBuffer->GetStatus(&dwStatus))
{
AfxMessageBox("Error - DS - GetStatus");
return FALSE;
}

if((dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING)
{
if (DS_OK != m_lpDSBuffer->Play(0, 0, dwFlags)) // Play the sound
{
AfxMessageBox("Error - DS - Play");
return FALSE;
}
}
}

return TRUE;
}

BOOL CDSBuffer::StopSound()
{
if(m_lpDSBuffer) // Make sure we have a valid sound buffer
{
DWORD dwStatus;
if (DS_OK != m_lpDSBuffer->GetStatus(&dwStatus))
{
AfxMessageBox("Error - DS - GetStatus");
return FALSE;
}

if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
{
if (DS_OK != m_lpDSBuffer->Stop()) // Stop the sound
{
AfxMessageBox("Error - DS - Stop");
return FALSE;
}

}
}
return TRUE;
}


BOOL CDSBuffer::IsValid()
{
if (m_lpDSBuffer)
return TRUE;
else
return FALSE;
}

?

-------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------

// DSList.h : Definition of CDSList class
//

#if !defined(AFX_DSLIST_H__7517D749_96E3_11D2_BBF3_9EB4940D843C__INCLUDED_)
#define AFX_DSLIST_H__7517D749_96E3_11D2_BBF3_9EB4940D843C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "DSBuffer.h"

class CDSList : virtual protected CObList
{
// Attribute
private:
LPDIRECTSOUND m_lpDS; // DirectSound Object

// Construction / Destruction
public:
CDSList();
~CDSList();

// Methods
public:
BOOL Init();
BOOL StopAllBuffers();
BOOL AddNewBuffer(const char* FileName);
BOOL RemoveBuffer(int nBuffer);
BOOL PlayBuffer(int nBuffer, DWORD dwFlags);
BOOL StopBuffer(int nBuffer);
LPDIRECTSOUND GetDSObject() {return m_lpDS;}
};

#endif // !defined(AFX_DSLIST_H__7517D749_96E3_11D2_BBF3_9EB4940D843C__INCLUDED_)

-------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------

///
// //
// DirectSound Mixer //
// //
// V1.0 by lob_b@hotmail.com 1999 //
// //
// with core inputs from //
// Stack-Up //
// V1.0 ?Tool@theWaterCooler.com 1998 //
// http://www.theWaterCooler.com/Tool //
// also Petr.Stejskal@vslib.cz //
// //
///

// DSList.cpp : Implementation of CDSList class
//

#include "stdafx.h"
#include "DSList.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CDSList

CDSList::CDSList()
{
// Reset the DirectSound pointer
m_lpDS = NULL;
}


CDSList::~CDSList()
{
// Stop all playing buffers
StopAllBuffers();

if(m_lpDS)
{
m_lpDS->Release();
}
}


BOOL CDSList::Init()
{
// Create DirectSound Object
if (DS_OK != DirectSoundCreate(NULL, &m_lpDS, NULL))
{
AfxMessageBox("Error - DS - Create/nAudio cannot be used");
return FALSE;
}

// Set Cooperative Level
if (DS_OK != m_lpDS->SetCooperativeLevel(*AfxGetMainWnd(), DSSCL_NORMAL))
{
AfxMessageBox("Error - DS - SetCooperativeLevel");
return FALSE;
}

return TRUE;
}


BOOL CDSList::AddNewBuffer(const char* FileName)
{
// Make sure that audio is initialized
if (!m_lpDS)
{
AfxMessageBox("Error - DS - Audio not initialized");
return FALSE;
}

// Try creating the new buffer
CDSBuffer* pNewBuffer = new CDSBuffer(FileName, m_lpDS);

// If succesfull add to playlist
if (pNewBuffer->IsValid())
{
AddTail(pNewBuffer);
return TRUE;
}

// Else forget it
else
{
delete(pNewBuffer);
return FALSE;
}
}


BOOL CDSList::RemoveBuffer(int nBuffer)
{
// Make sure that the buffer index is valid
if ((nBuffer < 0) || (nBuffer >= GetCount()))
{
AfxMessageBox("Error - DS - Invalid buffer selection index");
return FALSE;
}

// First stop the buffer
if (StopBuffer(nBuffer))
{
// Find the buffer
POSITION Pos = FindIndex(nBuffer);

// Remove it
RemoveAt(Pos);
return TRUE;
}
return FALSE;
}


BOOL CDSList::PlayBuffer(int nBuffer, DWORD dwFlags)
{
// Make sure that the buffer index is valid
if ((nBuffer < 0) || (nBuffer >= GetCount()))
{
AfxMessageBox("Error - DS - Invalid buffer selection index");
return FALSE;
}

// Find the buffer
POSITION Pos = FindIndex(nBuffer);

// Retrieve a pointer
CDSBuffer* DSBuffer = (CDSBuffer *)GetAt(Pos);

// Try playing it
return DSBuffer->PlaySound(dwFlags);
}


BOOL CDSList::StopBuffer(int nBuffer)
{
// Make sure that the buffer index is valid
if ((nBuffer < 0) || (nBuffer >= GetCount()))
{
AfxMessageBox("Error - DS - Invalid buffer selection index");
return FALSE;
}

// Find the buffer
POSITION Pos = FindIndex(nBuffer);

// Retrieve a pointer
CDSBuffer* DSBuffer = (CDSBuffer *)GetAt(Pos);

// Try stopping it
return DSBuffer->StopSound();
}


BOOL CDSList::StopAllBuffers()
{
for (POSITION Pos = GetHeadPosition(); Pos != NULL; )
{
CDSBuffer* DSBuffer = (CDSBuffer *)GetNext(Pos);
DSBuffer->StopSound();
}
return TRUE;
}

?

-------------------------------------------------------------------------------------------------

代碼使用方法:

1、首先把四個文件添加到工程中。

2、包含相應的頭文件,在自己的代碼中添加如下代碼:

#include "DSList.h"

3、鏈接DirectSound的相關靜態鏈接庫

在自己的代碼中加入如下靜態鏈接代碼:
//連接LIB庫
#pragma comment (lib,"winmm.lib")
#pragma comment(lib,"dxguid.lib")
#pragma comment(lib,"dsound.lib")

4、在初始化代碼中載入波形文件到緩沖區:

代碼示例:


//初始化DirectSound混音器;
m_dslist.Init ();
m_dslist.AddNewBuffer(GetAppPath()+"//sound//one.wav");
m_dslist.AddNewBuffer(GetAppPath()+"//sound//two.wav");
m_dslist.AddNewBuffer(GetAppPath()+"//sound//three.wav");

5、在需要播放聲音的時候調用:m_dslist.PlayBuffer(index,0);

index參數指的是添加緩沖區索引,最先添加的緩沖區索引為0,依此類推。

該函數是異步執行,自動與以前調用該函數所產生的尚未結束的聲音混音輸出。

?

轉載于:https://www.cnblogs.com/lzhitian/archive/2012/02/13/2348601.html

總結

以上是生活随笔為你收集整理的DirectSound 混音的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 色播开心网 | av免| 3d成人动漫在线观看 | 中文字幕无码乱码人妻日韩精品 | 久久黄色精品视频 | 色很久| 男男一级淫片免费播放 | 日韩午夜精品视频 | 九九视频在线免费观看 | 久艹av | 91精品免费观看 | 国产无遮挡又黄又爽免费视频 | av激情小说| 国产区小视频 | 黄站在线观看 | 日韩在线一级 | 国产欧美日韩成人 | 少女视频的播放方法 | 国产制服91一区二区三区制服 | 国产特级aaaaaa大片 | 欧美精品一区二区蜜臀亚洲 | 亚洲欧美另类一区 | 一级黄色毛毛片 | 日韩一卡二卡 | 色网站在线免费观看 | 在线国产毛片 | 嫩草在线视频 | 九九热视| 午夜一区二区视频 | 超级变态重口av番号 | 健身教练巨大粗爽gay视频 | 91精品国产综合久久久久久久 | 国产日韩在线一区 | 在线xxxx| 日韩精彩视频在线观看 | 中文字幕一区二区三区乱码不卡 | 免费吃奶摸下激烈视频 | 日本高清视频一区二区 | 国产高清精品在线观看 | 99久热| 超碰97人人在线 | 精品在线一区二区三区 | 日本人性爱视频 | 国产探花视频在线观看 | 成人综合影院 | 国产精品一区2区 | m3u8成人免费视频 | 国产福利一区在线观看 | 小毛片| 少妇被狂c下部羞羞漫画 | 永久av在线免费观看 | 久久国产影院 | 亚洲视频网址 | 麻豆av导航 | 特级西西人体444www | 国产无套精品一区二区 | 久久精品99 | 麻豆精品网站 | 蜜臀精品一区二区三区 | 欧美日韩中文在线观看 | 艳妇乳肉亭妇荡乳av | 国产一区视频在线 | 在线观看的av网址 | 爱操综合 | 偷拍亚洲另类 | 香蕉在线观看 | 久久视频一区二区三区 | 自拍视频国产 | 午夜久久久久久久久 | 色亚洲天堂| 激情综合六月 | 午夜一区二区视频 | 天天综合视频 | 99久久精品免费视频 | 91黑丝美女 | 阿v视频在线免费观看 | 天躁夜夜躁狼狠躁 | 9.1在线观看免费 | 98色| 人人人草 | 国产天堂网 | 一区在线免费观看 | 久久精品高清 | 成人免费观看视频 | 国产亚洲欧美日韩高清 | 高潮毛片无遮挡免费看 | 免费毛片一区二区三区久久久 | 国产精品久久久久永久免费看 | 国产剧情av引诱维修工 | 超碰在线c | 午夜视频在线播放 | 成人a级免费视频 | 深田咏美在线x99av | 亚洲不卡在线观看 | 国产成a人亚洲精v品在线观看 | 超碰香蕉| 白丝av| 黄色片在线看 | 亚洲中文字幕无码av |