Lo he visto muchas veces en distintos sitios, si mal no recuerdo todos eran tipo blogs ...
¿Alguien sabe que son?
¿Alguien sabe que son?
Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.
Mostrar Mensajes Menu/*
* Use this switch for embedded systems where no iostreams are available
* at all. STLport own iostreams will also get disabled automatically then.
* You can either use STLport iostreams, or no iostreams.
* If you want iostreams, you have to compile library in ../build/lib
* and supply resulting library at link time.
*/
#define _STLP_NO_IOSTREAMS 1
#include "DSoundDevice.h"
#include "ScreenWindows.h"
#pragma comment (lib,"dsound.lib")
using namespace PGL;
DSoundDevice::DSoundDevice(Audio* audio)
: Audio::Device(audio)
, lpDS(0), lpdsb(0), lpdsbPrimary(0), lpdsNotify(0)
, mMixingBuffer(0), mMixingSize(0), mInternalSize(0)
, mPlaying(false), mInitialized(false)
, mIsThereAnException(false), mException("No Exception")
{
}
DSoundDevice::~DSoundDevice()
{
assert( mInitialized == false );
}
void DSoundDevice::Update()
{
if(mIsThereAnException) throw mException;
}
void DSoundDevice::Init()
{
ScreenWindows* screen = static_cast<ScreenWindows*>(pAudio->Get_Screen());
mInternalFormat.Set_SampleFormat( Audio::Format::SIGNED_16_STEREO );
mInternalFormat.Set_Rate( 44100 );
mMixingFormat.Set_SampleFormat( Audio::Format::SIGNED_FIXED_8_24_STEREO );
// mMixingFormat.Set_SampleFormat( Audio::Format::SIGNED_16_STEREO );
mMixingFormat.Set_Rate( 44100 );
DSBUFFERDESC dsbdesc;
// DSound Init
if(DirectSoundCreate(0,&lpDS,0)!=DS_OK)
{
lpDS=0;
THROW_EXCEPTION( "Init() -> DirectSoundCreate" );
}
if(lpDS->SetCooperativeLevel(screen->Get_hWnd(),DSSCL_PRIORITY)!=DS_OK)
{
Destroy();
THROW_EXCEPTION( "Init() -> SetCooperativeLevel" );
}
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
dsbdesc.dwBufferBytes = 0;
dsbdesc.lpwfxFormat = NULL;
if(FAILED(lpDS->CreateSoundBuffer(&dsbdesc, &lpdsbPrimary, NULL)))
{
Destroy();
THROW_EXCEPTION( "Init() -> primary sound buffer CreateSoundBuffer()" );
}
// Setup primary buffer
WAVEFORMATEX wfx;
memset(&wfx, 0, sizeof(WAVEFORMATEX));
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = mInternalFormat.Get_Channels();
wfx.wBitsPerSample = mInternalFormat.Get_Bits();
wfx.nSamplesPerSec = mInternalFormat.Get_Rate();
wfx.nBlockAlign = mInternalFormat.Get_BlockAlign();
wfx.nAvgBytesPerSec = mInternalFormat.Get_AverageBytesPerSecond();
if(FAILED (lpdsbPrimary->SetFormat(&wfx)))
{
Destroy();
THROW_EXCEPTION( "Init() -> primary sound buffer SetFormat()" );
}
// get a buffer size which needs to be updated 40 times per second.
// and round it to a power of 2 (4096 bytes with 44100hz 16bits stereo)
mInternalSize = 1<<ilog2( wfx.nAvgBytesPerSec / BUFFER_UPDATES_PER_SECOND );
// Setup secondary buffer
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE;
dsbdesc.dwBufferBytes = mInternalSize * 2; // two buffers
dsbdesc.lpwfxFormat = &wfx;
memset(&wfx, 0, sizeof(WAVEFORMATEX));
wfx.wFormatTag = WAVE_FORMAT_PCM;
// the same format
wfx.nChannels = mInternalFormat.Get_Channels();
wfx.wBitsPerSample = mInternalFormat.Get_Bits();
wfx.nSamplesPerSec = mInternalFormat.Get_Rate();
wfx.nBlockAlign = mInternalFormat.Get_BlockAlign();
wfx.nAvgBytesPerSec = mInternalFormat.Get_AverageBytesPerSecond();
if(FAILED(lpDS->CreateSoundBuffer(&dsbdesc, &lpdsb, NULL)))
{
Destroy();
THROW_EXCEPTION( "Init() -> secondary sound buffer CreateSoundBuffer()" );
}
// Setup notifications
for (int i = 0; i < NUMEVENTS; i++)
{
rghEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
if (NULL == rghEvent[i])
{
Destroy();
THROW_EXCEPTION( "Init() -> CreateEvent()" );
}
}
rgdsbpn[0].dwOffset = 0;
rgdsbpn[0].hEventNotify = rghEvent[0];
rgdsbpn[1].dwOffset = (dsbdesc.dwBufferBytes/2);
rgdsbpn[1].hEventNotify = rghEvent[1];
if(FAILED(lpdsb->QueryInterface(IID_IDirectSoundNotify, (VOID **)&lpdsNotify)))
{
Destroy();
THROW_EXCEPTION( "Init() -> QueryInterface()" );
}
if(FAILED(lpdsNotify->SetNotificationPositions(NUMEVENTS, rgdsbpn)))
{
IDirectSoundNotify_Release(lpdsNotify);
Destroy();
THROW_EXCEPTION( "Init() -> SetNotificationPositions()" );
}
lpdsb->Play(0, 0, DSBPLAY_LOOPING);
mPlaying = true;
mMixingSize = (mInternalSize * mMixingFormat.Get_BlockAlign()) / mInternalFormat.Get_BlockAlign();
mMixingBuffer = new char[mMixingSize];
// fill the buffer for the first time
Mix(mMixingBuffer, mMixingSize, mMixingFormat);
mInitialized = true;
Start();
}
void DSoundDevice::Destroy()
{
Stop();
// DSound destroy
mInitialized = false;
if(lpdsNotify)
{
lpdsNotify->Release();
lpdsNotify = 0;
}
if(lpdsb)
{
lpdsb->Release();
lpdsb = 0;
}
if(lpdsbPrimary)
{
lpdsbPrimary->Release();
lpdsbPrimary = 0;
}
if(lpDS)
{
lpDS->Release();
lpDS = 0;
}
if(mMixingBuffer)
{
delete mMixingBuffer;
mMixingBuffer = 0;
}
}
void DSoundDevice::Run()
{
try {
if(!mInitialized) THROW_EXCEPTION( "DSound device not initialized" );
bool done = false;
// let's auto set the priority to max!
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
// Let's assure the granularity
TIMECAPS timecaps;
timeGetDevCaps(&timecaps, sizeof(timecaps) );
timeBeginPeriod( timecaps.wPeriodMax );
while(!Get_StopRequest() && !done)
{
DWORD dwEvt = MsgWaitForMultipleObjects(
NUMEVENTS, // How many possible events
rghEvent, // Location of handles
FALSE, // Wait for all? NO!
5, // How long to wait
QS_ALLINPUT); // Any message is an event
// To pause the mixer when the focus is lost.
if(!pAudio->Get_Screen()->Is_Active())
{
if(mPlaying)
{
mPlaying = false;
lpdsb->Stop();
}
}
else
{
if(!mPlaying)
{
mPlaying = true;
lpdsb->Play(0, 0, DSBPLAY_LOOPING);
}
}
if(dwEvt == WAIT_TIMEOUT) continue;
// WAIT_OBJECT_0 == 0 but is properly treated as an arbitrary
// index value assigned to the first event, therefore we subtract
// it from dwEvt to get the zero-based index of the event.
dwEvt -= WAIT_OBJECT_0;
// If the event was set by the buffer, there's input
// to process.
if (dwEvt < NUMEVENTS)
{
int dwStartOfs;
if (dwEvt == 0) dwStartOfs = rgdsbpn[1].dwOffset;
else dwStartOfs = rgdsbpn[0].dwOffset;
void* lpvPtr;
unsigned long dwBytes;
if( lpdsb->Lock(dwStartOfs, mInternalSize, &lpvPtr, &dwBytes, 0, 0, 0) == DSERR_BUFFERLOST)
{
lpdsb->Restore();
if( lpdsb->Lock(dwStartOfs, mInternalSize, &lpvPtr, &dwBytes, 0, 0, 0) == DSERR_BUFFERLOST)
THROW_EXCEPTION("DSound Buffer lost when locking");
}
// fill the DSound internal buffer.
mInternalFormat.Convert(lpvPtr, mMixingBuffer, mInternalSize, mMixingFormat);
if( FAILED(lpdsb->Unlock(lpvPtr, dwBytes, 0, 0)) )
THROW_EXCEPTION("DSound Buffer lost when unlocking");
assert( dwBytes == mInternalSize );
// fill the buffer for the next regeneration
Mix(mMixingBuffer, mMixingSize, mMixingFormat);
}
// If it's the last event, it's a message
// if this really needed?
else if (dwEvt == NUMEVENTS)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT) done = true;
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
} // end message processing
}
timeEndPeriod( timecaps.wPeriodMax );
}
catch( const Exception& e )
{
mException = e;
mIsThereAnException = true;
}
}
while(!done)
{
dt = GetTickCount() - last_tick;
last_tick += dt;
if(dt>0) {
Update(dt);
Draw();
} else Sleep(0);
}
Le sospechaba al Sleep pero no es eso.