mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 08:09:19 +02:00
audio subsystem replacement: openal audio renderer and buffer class, removed deprecated files
This commit is contained in:
176
old/AdvSound.cpp
Normal file
176
old/AdvSound.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "AdvSound.h"
|
||||
#include "Timer.h"
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
TAdvancedSound::~TAdvancedSound()
|
||||
{ // Ra: stopowanie się sypie
|
||||
// SoundStart.Stop();
|
||||
// SoundCommencing.Stop();
|
||||
// SoundShut.Stop();
|
||||
}
|
||||
|
||||
void TAdvancedSound::Init( std::string const &NameOn, std::string const &Name, std::string const &NameOff, double DistanceAttenuation, Math3D::vector3 const &pPosition)
|
||||
{
|
||||
SoundStart.Init(NameOn, DistanceAttenuation, pPosition.x, pPosition.y, pPosition.z, true);
|
||||
SoundCommencing.Init(Name, DistanceAttenuation, pPosition.x, pPosition.y, pPosition.z, true);
|
||||
SoundShut.Init(NameOff, DistanceAttenuation, pPosition.x, pPosition.y, pPosition.z, true);
|
||||
fStartLength = SoundStart.GetWaveTime();
|
||||
fShutLength = SoundShut.GetWaveTime();
|
||||
SoundStart.AM = 1.0;
|
||||
SoundStart.AA = 0.0;
|
||||
SoundStart.FM = 1.0;
|
||||
SoundStart.FA = 0.0;
|
||||
SoundCommencing.AM = 1.0;
|
||||
SoundCommencing.AA = 0.0;
|
||||
SoundCommencing.FM = 1.0;
|
||||
SoundCommencing.FA = 0.0;
|
||||
defAM = 1.0;
|
||||
defFM = 1.0;
|
||||
SoundShut.AM = 1.0;
|
||||
SoundShut.AA = 0.0;
|
||||
SoundShut.FM = 1.0;
|
||||
SoundShut.FA = 0.0;
|
||||
}
|
||||
|
||||
void TAdvancedSound::Load(cParser &Parser, Math3D::vector3 const &pPosition)
|
||||
{
|
||||
std::string nameon, name, nameoff;
|
||||
double attenuation;
|
||||
Parser.getTokens( 3, true, "\n\t ;," ); // samples separated with commas
|
||||
Parser
|
||||
>> nameon
|
||||
>> name
|
||||
>> nameoff;
|
||||
Parser.getTokens( 1, false );
|
||||
Parser
|
||||
>> attenuation;
|
||||
Init( nameon, name, nameoff, attenuation, pPosition );
|
||||
}
|
||||
|
||||
void TAdvancedSound::TurnOn(bool ListenerInside, Math3D::vector3 NewPosition)
|
||||
{
|
||||
// hunter-311211: nie trzeba czekac na ponowne odtworzenie dzwieku, az sie wylaczy
|
||||
if ((State == ss_Off || State == ss_ShuttingDown) && (SoundStart.AM > 0))
|
||||
{
|
||||
SoundStart.ResetPosition();
|
||||
SoundCommencing.ResetPosition();
|
||||
SoundStart.Play(1, 0, ListenerInside, NewPosition);
|
||||
// SoundStart->SetVolume(-10000);
|
||||
State = ss_Starting;
|
||||
fTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TAdvancedSound::TurnOff(bool ListenerInside, Math3D::vector3 NewPosition)
|
||||
{
|
||||
if ((State == ss_Commencing || State == ss_Starting) && (SoundShut.AM > 0))
|
||||
{
|
||||
SoundStart.Stop();
|
||||
SoundCommencing.Stop();
|
||||
SoundShut.ResetPosition();
|
||||
SoundShut.Play(1, 0, ListenerInside, NewPosition);
|
||||
State = ss_ShuttingDown;
|
||||
fTime = fShutLength;
|
||||
// SoundShut->SetVolume(0);
|
||||
}
|
||||
}
|
||||
|
||||
void TAdvancedSound::Update(bool ListenerInside, Math3D::vector3 NewPosition)
|
||||
{
|
||||
if ((State == ss_Commencing) && (SoundCommencing.AM > 0))
|
||||
{
|
||||
// SoundCommencing->SetFrequency();
|
||||
SoundShut.Stop(); // hunter-311211
|
||||
SoundCommencing.Play(1, DSBPLAY_LOOPING, ListenerInside, NewPosition);
|
||||
}
|
||||
else if (State == ss_Starting)
|
||||
{
|
||||
fTime += Timer::GetDeltaTime();
|
||||
// SoundStart->SetVolume(-1000*(4-fTime)/4);
|
||||
if (fTime >= fStartLength)
|
||||
{
|
||||
State = ss_Commencing;
|
||||
SoundCommencing.ResetPosition();
|
||||
SoundCommencing.Play(1, DSBPLAY_LOOPING, ListenerInside, NewPosition);
|
||||
SoundStart.Stop();
|
||||
}
|
||||
else
|
||||
SoundStart.Play(1, 0, ListenerInside, NewPosition);
|
||||
}
|
||||
else if (State == ss_ShuttingDown)
|
||||
{
|
||||
fTime -= Timer::GetDeltaTime();
|
||||
// SoundShut->SetVolume(-1000*(4-fTime)/4);
|
||||
if (fTime <= 0)
|
||||
{
|
||||
State = ss_Off;
|
||||
SoundShut.Stop();
|
||||
}
|
||||
else
|
||||
SoundShut.Play(1, 0, ListenerInside, NewPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void TAdvancedSound::UpdateAF(double A, double F, bool ListenerInside, Math3D::vector3 NewPosition)
|
||||
{ // update, ale z amplituda i czestotliwoscia
|
||||
if( State == ss_Off ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((State == ss_Commencing) && (SoundCommencing.AM > 0))
|
||||
{
|
||||
SoundShut.Stop(); // hunter-311211
|
||||
SoundCommencing.Play(A, DSBPLAY_LOOPING, ListenerInside, NewPosition);
|
||||
}
|
||||
else if (State == ss_Starting)
|
||||
{
|
||||
fTime += Timer::GetDeltaTime();
|
||||
// SoundStart->SetVolume(-1000*(4-fTime)/4);
|
||||
if (fTime >= fStartLength)
|
||||
{
|
||||
State = ss_Commencing;
|
||||
SoundCommencing.ResetPosition();
|
||||
SoundCommencing.Play(A, DSBPLAY_LOOPING, ListenerInside, NewPosition);
|
||||
SoundStart.Stop();
|
||||
}
|
||||
else
|
||||
SoundStart.Play(A, 0, ListenerInside, NewPosition);
|
||||
}
|
||||
else if (State == ss_ShuttingDown)
|
||||
{
|
||||
fTime -= Timer::GetDeltaTime();
|
||||
// SoundShut->SetVolume(-1000*(4-fTime)/4);
|
||||
if (fTime <= 0)
|
||||
{
|
||||
State = ss_Off;
|
||||
SoundShut.Stop();
|
||||
}
|
||||
else
|
||||
SoundShut.Play(A, 0, ListenerInside, NewPosition);
|
||||
}
|
||||
SoundCommencing.AdjFreq(F, Timer::GetDeltaTime());
|
||||
}
|
||||
|
||||
void TAdvancedSound::CopyIfEmpty(TAdvancedSound &s)
|
||||
{ // skopiowanie, gdyby był potrzebny, a nie został wczytany
|
||||
if ((fStartLength > 0.0) || (fShutLength > 0.0))
|
||||
return; // coś jest
|
||||
SoundStart = s.SoundStart;
|
||||
SoundCommencing = s.SoundCommencing;
|
||||
SoundShut = s.SoundShut;
|
||||
State = s.State;
|
||||
fStartLength = s.fStartLength;
|
||||
fShutLength = s.fShutLength;
|
||||
defAM = s.defAM;
|
||||
defFM = s.defFM;
|
||||
};
|
||||
49
old/AdvSound.h
Normal file
49
old/AdvSound.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef AdvSoundH
|
||||
#define AdvSoundH
|
||||
|
||||
#include "RealSound.h"
|
||||
#include "parser.h"
|
||||
|
||||
enum TSoundState {
|
||||
|
||||
ss_Off,
|
||||
ss_Starting,
|
||||
ss_Commencing,
|
||||
ss_ShuttingDown
|
||||
};
|
||||
|
||||
class TAdvancedSound
|
||||
{ // klasa dźwięków mających początek, dowolnie długi środek oraz zakończenie (np. Rp1)
|
||||
TRealSound SoundStart;
|
||||
TRealSound SoundCommencing;
|
||||
TRealSound SoundShut;
|
||||
TSoundState State = ss_Off;
|
||||
double fTime = 0.0;
|
||||
double fStartLength = 0.0;
|
||||
double fShutLength = 0.0;
|
||||
double defAM = 0.0;
|
||||
double defFM = 0.0;
|
||||
|
||||
public:
|
||||
TAdvancedSound() = default;
|
||||
~TAdvancedSound();
|
||||
void Init( std::string const &NameOn, std::string const &Name, std::string const &NameOff, double DistanceAttenuation, Math3D::vector3 const &pPosition);
|
||||
void Load(cParser &Parser, Math3D::vector3 const &pPosition);
|
||||
void TurnOn(bool ListenerInside, Math3D::vector3 NewPosition);
|
||||
void TurnOff(bool ListenerInside, Math3D::vector3 NewPosition);
|
||||
void Update(bool ListenerInside, Math3D::vector3 NewPosition);
|
||||
void UpdateAF(double A, double F, bool ListenerInside, Math3D::vector3 NewPosition);
|
||||
void CopyIfEmpty(TAdvancedSound &s);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
260
old/RealSound.cpp
Normal file
260
old/RealSound.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
||||
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "RealSound.h"
|
||||
#include "Globals.h"
|
||||
#include "Logs.h"
|
||||
//#include "math.h"
|
||||
#include "Timer.h"
|
||||
#include "mczapkie/mctools.h"
|
||||
#include "usefull.h"
|
||||
|
||||
TRealSound::TRealSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod, double rmin)
|
||||
{
|
||||
Init(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin);
|
||||
}
|
||||
|
||||
TRealSound::~TRealSound()
|
||||
{
|
||||
// if (this) if (pSound) pSound->Stop();
|
||||
}
|
||||
|
||||
void TRealSound::Init(std::string const &SoundName, double DistanceAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod, double rmin)
|
||||
{
|
||||
// Nazwa=SoundName; //to tak raczej nie zadziała, (SoundName) jest tymczasowe
|
||||
pSound = TSoundsManager::GetFromName(SoundName, Dynamic, &fFrequency);
|
||||
if (pSound)
|
||||
{
|
||||
if (freqmod)
|
||||
if (fFrequency != 22050.0)
|
||||
{ // dla modulowanych nie może być zmiany mnożnika, bo częstotliwość w nagłówku byłą
|
||||
// ignorowana, a mogła być inna niż 22050
|
||||
fFrequency = 22050.0;
|
||||
ErrorLog("Bad sound: " + SoundName + ", as modulated, should have 22.05kHz in header");
|
||||
}
|
||||
AM = 1.0;
|
||||
pSound->SetVolume(DSBVOLUME_MIN);
|
||||
}
|
||||
else
|
||||
{ // nie ma dźwięku, to jest wysyp
|
||||
AM = 0;
|
||||
ErrorLog("Missed sound: " + SoundName);
|
||||
}
|
||||
if (DistanceAttenuation > 0.0)
|
||||
{
|
||||
dSoundAtt = DistanceAttenuation * DistanceAttenuation;
|
||||
vSoundPosition.x = X;
|
||||
vSoundPosition.y = Y;
|
||||
vSoundPosition.z = Z;
|
||||
if (rmin < 0)
|
||||
iDoppler = 1; // wyłączenie efektu Dopplera, np. dla dźwięku ptaków
|
||||
}
|
||||
else
|
||||
dSoundAtt = -1;
|
||||
};
|
||||
|
||||
double TRealSound::ListenerDistance( Math3D::vector3 ListenerPosition)
|
||||
{
|
||||
if (dSoundAtt == -1)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SquareMagnitude(ListenerPosition - vSoundPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void TRealSound::Play(double Volume, int Looping, bool ListenerInside, Math3D::vector3 NewPosition)
|
||||
{
|
||||
if (!pSound)
|
||||
return;
|
||||
long int vol;
|
||||
double dS = 0.0;
|
||||
// double Distance;
|
||||
DWORD stat;
|
||||
if ((Global::bSoundEnabled) && (AM != 0))
|
||||
{
|
||||
if (Volume > 1.0)
|
||||
Volume = 1.0;
|
||||
fPreviousDistance = fDistance;
|
||||
fDistance = 0.0; //??
|
||||
if (dSoundAtt > 0.0)
|
||||
{
|
||||
vSoundPosition = NewPosition;
|
||||
dS = dSoundAtt; //*dSoundAtt; //bo odleglosc podawana w kwadracie
|
||||
fDistance = ListenerDistance(Global::pCameraPosition);
|
||||
if (ListenerInside) // osłabianie dźwięków z odległością
|
||||
Volume = Volume * dS / (dS + fDistance);
|
||||
else
|
||||
Volume = Volume * dS / (dS + 2 * fDistance); // podwójne dla ListenerInside=false
|
||||
}
|
||||
if (iDoppler) //
|
||||
{ // Ra 2014-07: efekt Dopplera nie zawsze jest wskazany
|
||||
// if (FreeFlyModeFlag) //gdy swobodne latanie - nie sprawdza się to
|
||||
fPreviousDistance = fDistance; // to efektu Dopplera nie będzie
|
||||
}
|
||||
if (Looping) // dźwięk zapętlony można wyłączyć i zostanie włączony w miarę potrzeby
|
||||
bLoopPlay = true; // dźwięk wyłączony
|
||||
// McZapkie-010302 - babranie tylko z niezbyt odleglymi dźwiękami
|
||||
if ((dSoundAtt == -1) || (fDistance < 20.0 * dS))
|
||||
{
|
||||
// vol=2*Volume+1;
|
||||
// if (vol<1) vol=1;
|
||||
// vol=10000*(log(vol)-1);
|
||||
// vol=10000*(vol-1);
|
||||
// int glos=1;
|
||||
// Volume=Volume*glos; //Ra: whatta hella is this
|
||||
if (Volume < 0.0)
|
||||
Volume = 0.0;
|
||||
vol = -5000.0 + 5000.0 * Volume;
|
||||
if (vol >= 0)
|
||||
vol = -1;
|
||||
if (Timer::GetSoundTimer() || !Looping) // Ra: po co to jest?
|
||||
pSound->SetVolume(vol); // Attenuation, in hundredths of a decibel (dB).
|
||||
pSound->GetStatus(&stat);
|
||||
if (!(stat & DSBSTATUS_PLAYING))
|
||||
pSound->Play(0, 0, Looping);
|
||||
}
|
||||
else // wylacz dzwiek bo daleko
|
||||
{ // Ra 2014-09: oddalanie się nie może być powodem do wyłączenie dźwięku
|
||||
/*
|
||||
// Ra: stara wersja, ale podobno lepsza
|
||||
pSound->GetStatus(&stat);
|
||||
if (bLoopPlay) //jeśli zapętlony, to zostanie ponownie włączony, o ile znajdzie się
|
||||
bliżej
|
||||
if (stat&DSBSTATUS_PLAYING)
|
||||
pSound->Stop();
|
||||
// Ra: wyłączyłem, bo podobno jest gorzej niż wcześniej
|
||||
//ZiomalCl: dźwięk po wyłączeniu sam się nie włączy, gdy wrócimy w rejon odtwarzania
|
||||
pSound->SetVolume(DSBVOLUME_MIN); //dlatego lepiej go wyciszyć na czas oddalenia się
|
||||
pSound->GetStatus(&stat);
|
||||
if (!(stat&DSBSTATUS_PLAYING))
|
||||
pSound->Play(0,0,Looping); //ZiomalCl: włączenie odtwarzania rownież i tu, gdyż
|
||||
jesli uruchamiamy dźwięk poza promieniem, nie uruchomi się on w ogóle
|
||||
*/
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void TRealSound::Stop()
|
||||
{
|
||||
DWORD stat;
|
||||
if (pSound)
|
||||
if ((Global::bSoundEnabled) && (AM != 0))
|
||||
{
|
||||
bLoopPlay = false; // dźwięk wyłączony
|
||||
pSound->GetStatus(&stat);
|
||||
if (stat & DSBSTATUS_PLAYING)
|
||||
pSound->Stop();
|
||||
}
|
||||
};
|
||||
|
||||
void TRealSound::AdjFreq(double Freq, double dt) // McZapkie TODO: dorobic tu efekt Dopplera
|
||||
// Freq moze byc liczba dodatnia mniejsza od 1 lub wieksza od 1
|
||||
{
|
||||
float df, Vlist;
|
||||
if ((Global::bSoundEnabled) && (AM != 0) && (pSound != nullptr))
|
||||
{
|
||||
if (dt > 0)
|
||||
// efekt Dopplera
|
||||
{
|
||||
Vlist = (sqrt(fPreviousDistance) - sqrt(fDistance)) / dt;
|
||||
df = Freq * (1 + Vlist / 299.8);
|
||||
}
|
||||
else
|
||||
df = Freq;
|
||||
if (Timer::GetSoundTimer())
|
||||
{
|
||||
df = fFrequency * df; // TODO - brac czestotliwosc probkowania z wav
|
||||
pSound->SetFrequency( clamp( df, static_cast<float>(DSBFREQUENCY_MIN), static_cast<float>(DSBFREQUENCY_MAX) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double TRealSound::GetWaveTime() // McZapkie: na razie tylko dla 22KHz/8bps
|
||||
{ // używana do pomiaru czasu dla dźwięków z początkiem i końcem
|
||||
if (!pSound)
|
||||
return 0.0;
|
||||
double WaveTime;
|
||||
DSBCAPS caps;
|
||||
caps.dwSize = sizeof(caps);
|
||||
pSound->GetCaps(&caps);
|
||||
WaveTime = caps.dwBufferBytes;
|
||||
return WaveTime /
|
||||
fFrequency; //(pSound->); // wielkosc w bajtach przez czestotliwosc probkowania
|
||||
}
|
||||
|
||||
void TRealSound::SetPan(int Pan)
|
||||
{
|
||||
pSound->SetPan(Pan);
|
||||
}
|
||||
|
||||
int TRealSound::GetStatus()
|
||||
{
|
||||
DWORD stat;
|
||||
if ((Global::bSoundEnabled) && (AM != 0))
|
||||
{
|
||||
pSound->GetStatus(&stat);
|
||||
return stat;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TRealSound::ResetPosition()
|
||||
{
|
||||
if (pSound) // Ra: znowu jakiś badziew!
|
||||
pSound->SetCurrentPosition(0);
|
||||
}
|
||||
|
||||
TTextSound::TTextSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod, double rmin) :
|
||||
TRealSound(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin)
|
||||
{
|
||||
Init(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin);
|
||||
}
|
||||
|
||||
void TTextSound::Init(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod, double rmin)
|
||||
{ // dodatkowo doczytuje plik tekstowy
|
||||
fTime = GetWaveTime();
|
||||
std::string txt(SoundName);
|
||||
txt.erase( txt.rfind( '.' ) ); // obcięcie rozszerzenia
|
||||
for (size_t i = txt.length(); i > 0; --i)
|
||||
if (txt[i] == '/')
|
||||
txt[i] = '\\'; // bo nie rozumi
|
||||
txt += "-" + Global::asLang + ".txt"; // już może być w różnych językach
|
||||
if (!FileExists(txt))
|
||||
txt = "sounds\\" + txt; //ścieżka może nie być podana
|
||||
if (FileExists(txt))
|
||||
{ // wczytanie
|
||||
std::ifstream inputfile( txt );
|
||||
asText.assign( std::istreambuf_iterator<char>( inputfile ), std::istreambuf_iterator<char>() );
|
||||
}
|
||||
};
|
||||
void TTextSound::Play(double Volume, int Looping, bool ListenerInside, Math3D::vector3 NewPosition)
|
||||
{
|
||||
if (false == asText.empty())
|
||||
{ // jeśli ma powiązany tekst
|
||||
DWORD stat;
|
||||
pSound->GetStatus(&stat);
|
||||
if (!(stat & DSBSTATUS_PLAYING)) {
|
||||
// jeśli nie jest aktualnie odgrywany
|
||||
Global::tranTexts.Add( asText, fTime, true );
|
||||
}
|
||||
}
|
||||
TRealSound::Play(Volume, Looping, ListenerInside, NewPosition);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
96
old/RealSound.h
Normal file
96
old/RealSound.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Sound.h"
|
||||
#include "dumb3d.h"
|
||||
#include "names.h"
|
||||
|
||||
class TRealSound {
|
||||
|
||||
protected:
|
||||
PSound pSound = nullptr;
|
||||
double fDistance = 0.0;
|
||||
double fPreviousDistance = 0.0; // dla liczenia Dopplera
|
||||
float fFrequency = 22050.0; // częstotliwość samplowania pliku
|
||||
int iDoppler = 0; // Ra 2014-07: możliwość wyłączenia efektu Dopplera np. dla śpiewu ptaków
|
||||
public:
|
||||
std::string m_name;
|
||||
Math3D::vector3 vSoundPosition; // polozenie zrodla dzwieku
|
||||
double dSoundAtt = -1.0; // odleglosc polowicznego zaniku dzwieku
|
||||
double AM = 0.0; // mnoznik amplitudy
|
||||
double AA = 0.0; // offset amplitudy
|
||||
double FM = 0.0; // mnoznik czestotliwosci
|
||||
double FA = 0.0; // offset czestotliwosci
|
||||
bool bLoopPlay = false; // czy zapętlony dźwięk jest odtwarzany
|
||||
TRealSound() = default;
|
||||
TRealSound( std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod = false, double rmin = 0.0 );
|
||||
~TRealSound();
|
||||
void Init( std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod = false, double rmin = 0.0 );
|
||||
double ListenerDistance( Math3D::vector3 ListenerPosition);
|
||||
void Play(double Volume, int Looping, bool ListenerInside, Math3D::vector3 NewPosition);
|
||||
void Stop();
|
||||
void AdjFreq(double Freq, double dt);
|
||||
void SetPan(int Pan);
|
||||
double GetWaveTime(); // McZapkie TODO: dorobic dla roznych bps
|
||||
int GetStatus();
|
||||
void ResetPosition();
|
||||
bool Empty() { return ( pSound == nullptr ); }
|
||||
void
|
||||
name( std::string Name ) {
|
||||
m_name = Name; }
|
||||
std::string const &
|
||||
name() const {
|
||||
return m_name; }
|
||||
glm::dvec3
|
||||
location() const {
|
||||
return vSoundPosition; };
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TTextSound : public TRealSound {
|
||||
// dźwięk ze stenogramem
|
||||
std::string asText;
|
||||
float fTime; // czas trwania
|
||||
public:
|
||||
TTextSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod = false, double rmin = 0.0);
|
||||
void Init(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod = false, double rmin = 0.0);
|
||||
void Play(double Volume, int Looping, bool ListenerInside, Math3D::vector3 NewPosition);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TSynthSound
|
||||
{ // klasa generująca sygnał odjazdu (Rp12, Rp13), potem rozbudować o pracę manewrowego...
|
||||
int iIndex[44]; // indeksy początkowe, gdy mamy kilka wariantów dźwięków składowych
|
||||
// 0..9 - cyfry 0..9
|
||||
// 10..19 - liczby 10..19
|
||||
// 21..29 - dziesiątki (*21==*10?)
|
||||
// 31..39 - setki 100,200,...,800,900
|
||||
// 40 - "tysiąc"
|
||||
// 41 - "tysiące"
|
||||
// 42 - indeksy początkowe dla "odjazd"
|
||||
// 43 - indeksy początkowe dla "gotów"
|
||||
PSound sSound; // posortowana tablica dźwięków, rozmiar zależny od liczby znalezionych plików
|
||||
// a może zamiast wielu plików/dźwięków zrobić jeden połączony plik i posługiwać się czasem
|
||||
// od..do?
|
||||
};
|
||||
|
||||
|
||||
|
||||
// collection of generators for power grid present in the scene
|
||||
class sound_table : public basic_table<TTextSound> {
|
||||
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
257
old/Sound.cpp
Normal file
257
old/Sound.cpp
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Sound.h"
|
||||
#include "Globals.h"
|
||||
#include "Logs.h"
|
||||
#include "Usefull.h"
|
||||
#include "mczapkie/mctools.h"
|
||||
#include "WavRead.h"
|
||||
|
||||
#define SAFE_RELEASE(p) \
|
||||
{ \
|
||||
if (p) \
|
||||
{ \
|
||||
(p)->Release(); \
|
||||
(p) = NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
LPDIRECTSOUND TSoundsManager::pDS;
|
||||
LPDIRECTSOUNDNOTIFY TSoundsManager::pDSNotify;
|
||||
|
||||
int TSoundsManager::Count = 0;
|
||||
TSoundContainer *TSoundsManager::First = NULL;
|
||||
|
||||
TSoundContainer::TSoundContainer(LPDIRECTSOUND pDS, std::string const &Directory, std::string const &Filename, int NConcurrent)
|
||||
{ // wczytanie pliku dźwiękowego
|
||||
int hr = 111;
|
||||
DSBuffer = nullptr; // na początek, gdyby uruchomić dźwięków się nie udało
|
||||
Concurrent = NConcurrent;
|
||||
Oldest = 0;
|
||||
m_name = Directory + Filename;
|
||||
|
||||
// Create a new wave file class
|
||||
std::shared_ptr<CWaveSoundRead> pWaveSoundRead = std::make_shared<CWaveSoundRead>();
|
||||
|
||||
// Load the wave file
|
||||
if( ( FAILED( pWaveSoundRead->Open( m_name ) ) )
|
||||
&& ( FAILED( pWaveSoundRead->Open( Filename ) ) ) ) {
|
||||
ErrorLog( "Missed sound: " + Filename );
|
||||
return;
|
||||
}
|
||||
|
||||
m_name = ToLower( Filename );
|
||||
|
||||
// Set up the direct sound buffer, and only request the flags needed
|
||||
// since each requires some overhead and limits if the buffer can
|
||||
// be hardware accelerated
|
||||
DSBUFFERDESC dsbd;
|
||||
ZeroMemory(&dsbd, sizeof(DSBUFFERDESC));
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
|
||||
if (!Global::bInactivePause) // jeśli przełączony w tło ma nadal działać
|
||||
dsbd.dwFlags |= DSBCAPS_GLOBALFOCUS; // to dźwięki mają być również słyszalne
|
||||
dsbd.dwBufferBytes = pWaveSoundRead->m_ckIn.cksize;
|
||||
dsbd.lpwfxFormat = pWaveSoundRead->m_pwfx;
|
||||
fSamplingRate = pWaveSoundRead->m_pwfx->nSamplesPerSec;
|
||||
iBitsPerSample = pWaveSoundRead->m_pwfx->wBitsPerSample;
|
||||
|
||||
// pDSBuffer= (LPDIRECTSOUNDBUFFER*) malloc(Concurrent*sizeof(LPDIRECTSOUNDBUFFER));
|
||||
// for (int i=0; i<Concurrent; i++)
|
||||
// pDSBuffer[i]= NULL;
|
||||
|
||||
// Create the static DirectSound buffer
|
||||
if (FAILED(hr = pDS->CreateSoundBuffer(&dsbd, &(DSBuffer), NULL)))
|
||||
// if (FAILED(pDS->CreateSoundBuffer(&dsbd,&(DSBuffer),NULL)))
|
||||
return;
|
||||
|
||||
// Remember how big the buffer is
|
||||
DWORD dwBufferBytes;
|
||||
|
||||
dwBufferBytes = dsbd.dwBufferBytes;
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
BYTE *pbWavData; // Pointer to actual wav data
|
||||
UINT cbWavSize; // Size of data
|
||||
VOID *pbData = NULL;
|
||||
VOID *pbData2 = NULL;
|
||||
DWORD dwLength;
|
||||
DWORD dwLength2;
|
||||
|
||||
// The size of wave data is in pWaveFileSound->m_ckIn
|
||||
INT nWaveFileSize = pWaveSoundRead->m_ckIn.cksize;
|
||||
|
||||
// Allocate that buffer.
|
||||
pbWavData = new BYTE[nWaveFileSize];
|
||||
if (NULL == pbWavData)
|
||||
return; // E_OUTOFMEMORY;
|
||||
|
||||
// if (FAILED(hr=pWaveSoundRead->Read( nWaveFileSize,pbWavData,&cbWavSize)))
|
||||
if( FAILED( hr = pWaveSoundRead->Read( nWaveFileSize, pbWavData, &cbWavSize ) ) ) {
|
||||
delete[] pbWavData;
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset the file to the beginning
|
||||
pWaveSoundRead->Reset();
|
||||
|
||||
// Lock the buffer down
|
||||
// if (FAILED(hr=DSBuffer->Lock(0,dwBufferBytes,&pbData,&dwLength,&pbData2,&dwLength2,0)))
|
||||
if( FAILED( hr = DSBuffer->Lock( 0, dwBufferBytes, &pbData, &dwLength, &pbData2, &dwLength2, 0L ) ) ) {
|
||||
delete[] pbWavData;
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy the memory to it.
|
||||
memcpy(pbData, pbWavData, dwBufferBytes);
|
||||
|
||||
// Unlock the buffer, we don't need it anymore.
|
||||
DSBuffer->Unlock(pbData, dwBufferBytes, NULL, 0);
|
||||
pbData = NULL;
|
||||
|
||||
// We dont need the wav file data buffer anymore, so delete it
|
||||
delete[] pbWavData;
|
||||
|
||||
DSBuffers.push(DSBuffer);
|
||||
};
|
||||
TSoundContainer::~TSoundContainer()
|
||||
{
|
||||
while (!DSBuffers.empty())
|
||||
{
|
||||
SAFE_RELEASE(DSBuffers.top());
|
||||
DSBuffers.pop();
|
||||
}
|
||||
SafeDelete(Next);
|
||||
};
|
||||
|
||||
LPDIRECTSOUNDBUFFER TSoundContainer::GetUnique(LPDIRECTSOUND pDS)
|
||||
{
|
||||
if (!DSBuffer)
|
||||
return NULL;
|
||||
// jeśli się dobrze zainicjowało
|
||||
LPDIRECTSOUNDBUFFER buff = nullptr;
|
||||
pDS->DuplicateSoundBuffer(DSBuffer, &buff);
|
||||
if (buff)
|
||||
DSBuffers.push(buff);
|
||||
return DSBuffers.top();
|
||||
};
|
||||
|
||||
TSoundsManager::~TSoundsManager()
|
||||
{
|
||||
Free();
|
||||
};
|
||||
|
||||
void TSoundsManager::Free()
|
||||
{
|
||||
SafeDelete(First);
|
||||
SAFE_RELEASE(pDS);
|
||||
};
|
||||
|
||||
TSoundContainer * TSoundsManager::LoadFromFile( std::string const &Dir, std::string const &Filename, int Concurrent)
|
||||
{
|
||||
TSoundContainer *tmp = First;
|
||||
First = new TSoundContainer(pDS, Dir, Filename, Concurrent);
|
||||
First->Next = tmp;
|
||||
Count++;
|
||||
return First; // albo NULL, jak nie wyjdzie (na razie zawsze wychodzi)
|
||||
};
|
||||
|
||||
LPDIRECTSOUNDBUFFER TSoundsManager::GetFromName(std::string const &Name, bool Dynamic, float *fSamplingRate)
|
||||
{ // wyszukanie dźwięku w pamięci albo wczytanie z pliku
|
||||
std::string name{ ToLower(Name) };
|
||||
std::string file;
|
||||
if (Dynamic)
|
||||
{ // próba wczytania z katalogu pojazdu
|
||||
file = Global::asCurrentDynamicPath + name;
|
||||
if (FileExists(file))
|
||||
name = file; // nowa nazwa
|
||||
else
|
||||
Dynamic = false; // wczytanie z "sounds/"
|
||||
}
|
||||
TSoundContainer *Next = First;
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
if( name == Next->m_name ) {
|
||||
|
||||
if (fSamplingRate)
|
||||
*fSamplingRate = Next->fSamplingRate; // częstotliwość
|
||||
return (Next->GetUnique(pDS));
|
||||
}
|
||||
else
|
||||
Next = Next->Next;
|
||||
};
|
||||
if (Dynamic) // wczytanie z katalogu pojazdu
|
||||
Next = LoadFromFile("", name, 1);
|
||||
else
|
||||
Next = LoadFromFile(szSoundPath, name, 1);
|
||||
if (Next)
|
||||
{ //
|
||||
if (fSamplingRate)
|
||||
*fSamplingRate = Next->fSamplingRate; // częstotliwość
|
||||
return Next->GetUnique(pDS);
|
||||
}
|
||||
ErrorLog("Missed sound: " + Name );
|
||||
return (nullptr);
|
||||
};
|
||||
|
||||
void TSoundsManager::RestoreAll()
|
||||
{
|
||||
TSoundContainer *Next = First;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
DWORD dwStatus = 0;
|
||||
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
if (dwStatus & DSBSTATUS_BUFFERLOST)
|
||||
{
|
||||
// Since the app could have just been activated, then
|
||||
// DirectSound may not be giving us control yet, so
|
||||
// the restoring the buffer may fail.
|
||||
// If it does, sleep until DirectSound gives us control.
|
||||
do
|
||||
{
|
||||
hr = Next->DSBuffer->Restore();
|
||||
if (hr == DSERR_BUFFERLOST)
|
||||
Sleep(10);
|
||||
} while ((hr = Next->DSBuffer->Restore()) != 0);
|
||||
|
||||
// char *Name= Next->Name;
|
||||
// int cc= Next->Concurrent;
|
||||
// delete Next;
|
||||
// Next= new TSoundContainer(pDS, Directory, Name, cc);
|
||||
// if( FAILED( hr = FillBuffer() ) );
|
||||
// return hr;
|
||||
};
|
||||
Next = Next->Next;
|
||||
};
|
||||
};
|
||||
|
||||
bool TSoundsManager::Init(HWND hWnd) {
|
||||
|
||||
First = nullptr;
|
||||
Count = 0;
|
||||
pDS = nullptr;
|
||||
pDSNotify = nullptr;
|
||||
|
||||
// Create IDirectSound using the primary sound device
|
||||
auto hr = ::DirectSoundCreate(NULL, &pDS, NULL);
|
||||
if (hr != DS_OK) {
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
pDS->SetCooperativeLevel(hWnd, DSSCL_NORMAL);
|
||||
|
||||
return true;
|
||||
};
|
||||
50
old/Sound.h
Normal file
50
old/Sound.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stack>
|
||||
#include <dsound.h>
|
||||
|
||||
typedef LPDIRECTSOUNDBUFFER PSound;
|
||||
|
||||
class TSoundContainer
|
||||
{
|
||||
public:
|
||||
int Concurrent;
|
||||
int Oldest;
|
||||
std::string m_name;
|
||||
LPDIRECTSOUNDBUFFER DSBuffer;
|
||||
float fSamplingRate; // częstotliwość odczytana z pliku
|
||||
int iBitsPerSample; // ile bitów na próbkę
|
||||
TSoundContainer *Next;
|
||||
std::stack<LPDIRECTSOUNDBUFFER> DSBuffers;
|
||||
|
||||
TSoundContainer(LPDIRECTSOUND pDS, std::string const &Directory, std::string const &Filename, int NConcurrent);
|
||||
~TSoundContainer();
|
||||
LPDIRECTSOUNDBUFFER GetUnique( LPDIRECTSOUND pDS );
|
||||
};
|
||||
|
||||
class TSoundsManager
|
||||
{
|
||||
private:
|
||||
static LPDIRECTSOUND pDS;
|
||||
static LPDIRECTSOUNDNOTIFY pDSNotify;
|
||||
static TSoundContainer *First;
|
||||
static int Count;
|
||||
|
||||
static TSoundContainer * LoadFromFile( std::string const &Directory, std::string const &FileName, int Concurrent);
|
||||
|
||||
public:
|
||||
~TSoundsManager();
|
||||
static bool Init( HWND hWnd );
|
||||
static void Free();
|
||||
static LPDIRECTSOUNDBUFFER GetFromName( std::string const &Name, bool Dynamic, float *fSamplingRate = NULL );
|
||||
static void RestoreAll();
|
||||
};
|
||||
11
old/VBO.cpp
Normal file
11
old/VBO.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "VBO.h"
|
||||
19
old/VBO.h
Normal file
19
old/VBO.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openglgeometrybank.h"
|
||||
|
||||
class CMesh
|
||||
{
|
||||
public:
|
||||
geometrybank_handle m_geometrybank;
|
||||
bool m_geometrycreated { false };
|
||||
};
|
||||
264
old/wavread.cpp
Normal file
264
old/wavread.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: WavRead.cpp
|
||||
//
|
||||
// Desc: Wave file support for loading and playing Wave files using DirectSound
|
||||
// buffers.
|
||||
//
|
||||
// Copyright (c) 1999 Microsoft Corp. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "WavRead.h"
|
||||
#include "usefull.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: ReadMMIO()
|
||||
// Desc: Support function for reading from a multimedia I/O stream
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT ReadMMIO(HMMIO hmmioIn, MMCKINFO *pckInRIFF, WAVEFORMATEX **ppwfxInfo)
|
||||
{
|
||||
MMCKINFO ckIn; // chunk info. for general use.
|
||||
PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in.
|
||||
|
||||
*ppwfxInfo = NULL;
|
||||
|
||||
if ((0 != mmioDescend(hmmioIn, pckInRIFF, NULL, 0)))
|
||||
return E_FAIL;
|
||||
|
||||
if ((pckInRIFF->ckid != FOURCC_RIFF) || (pckInRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E')))
|
||||
return E_FAIL;
|
||||
|
||||
// Search the input file for for the 'fmt ' chunk.
|
||||
ckIn.ckid = mmioFOURCC('f', 'm', 't', ' ');
|
||||
if (0 != mmioDescend(hmmioIn, &ckIn, pckInRIFF, MMIO_FINDCHUNK))
|
||||
return E_FAIL;
|
||||
|
||||
// Expect the 'fmt' chunk to be at least as large as <PCMWAVEFORMAT>;
|
||||
// if there are extra parameters at the end, we'll ignore them
|
||||
if (ckIn.cksize < (LONG)sizeof(PCMWAVEFORMAT))
|
||||
return E_FAIL;
|
||||
|
||||
// Read the 'fmt ' chunk into <pcmWaveFormat>.
|
||||
if (mmioRead(hmmioIn, (HPSTR)&pcmWaveFormat, sizeof(pcmWaveFormat)) != sizeof(pcmWaveFormat))
|
||||
return E_FAIL;
|
||||
|
||||
// Allocate the waveformatex, but if its not pcm format, read the next
|
||||
// word, and thats how many extra bytes to allocate.
|
||||
if (pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
if (NULL == (*ppwfxInfo = new WAVEFORMATEX))
|
||||
return E_FAIL;
|
||||
|
||||
// Copy the bytes from the pcm structure to the waveformatex structure
|
||||
memcpy(*ppwfxInfo, &pcmWaveFormat, sizeof(pcmWaveFormat));
|
||||
(*ppwfxInfo)->cbSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read in length of extra bytes.
|
||||
WORD cbExtraBytes = 0L;
|
||||
if (mmioRead(hmmioIn, (CHAR *)&cbExtraBytes, sizeof(WORD)) != sizeof(WORD))
|
||||
return E_FAIL;
|
||||
|
||||
*ppwfxInfo = (WAVEFORMATEX *)new CHAR[sizeof(WAVEFORMATEX) + cbExtraBytes];
|
||||
if (NULL == *ppwfxInfo)
|
||||
return E_FAIL;
|
||||
|
||||
// Copy the bytes from the pcm structure to the waveformatex structure
|
||||
memcpy(*ppwfxInfo, &pcmWaveFormat, sizeof(pcmWaveFormat));
|
||||
(*ppwfxInfo)->cbSize = cbExtraBytes;
|
||||
|
||||
// Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
|
||||
if (mmioRead(hmmioIn, (CHAR *)(((BYTE *)&((*ppwfxInfo)->cbSize)) + sizeof(WORD)),
|
||||
cbExtraBytes) != cbExtraBytes)
|
||||
{
|
||||
delete *ppwfxInfo;
|
||||
*ppwfxInfo = NULL;
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// Ascend the input file out of the 'fmt ' chunk.
|
||||
if (0 != mmioAscend(hmmioIn, &ckIn, 0))
|
||||
{
|
||||
delete *ppwfxInfo;
|
||||
*ppwfxInfo = NULL;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: WaveOpenFile()
|
||||
// Desc: This function will open a wave input file and prepare it for reading,
|
||||
// so the data can be easily read with WaveReadFile. Returns 0 if
|
||||
// successful, the error code if not.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT WaveOpenFile( std::string const &Filename, HMMIO *phmmioIn, WAVEFORMATEX **ppwfxInfo,
|
||||
MMCKINFO *pckInRIFF)
|
||||
{
|
||||
HRESULT hr;
|
||||
HMMIO hmmioIn = NULL;
|
||||
|
||||
if (NULL == (hmmioIn = mmioOpen(const_cast<char*>(Filename.c_str()), NULL, MMIO_ALLOCBUF | MMIO_READ)))
|
||||
return E_FAIL;
|
||||
|
||||
if (FAILED(hr = ReadMMIO(hmmioIn, pckInRIFF, ppwfxInfo)))
|
||||
{
|
||||
mmioClose(hmmioIn, 0);
|
||||
return hr;
|
||||
}
|
||||
|
||||
*phmmioIn = hmmioIn;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: WaveStartDataRead()
|
||||
// Desc: Routine has to be called before WaveReadFile as it searches for the
|
||||
// chunk to descend into for reading, that is, the 'data' chunk. For
|
||||
// simplicity, this used to be in the open routine, but was taken out and
|
||||
// moved to a separate routine so there was more control on the chunks
|
||||
// that are before the data chunk, such as 'fact', etc...
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT WaveStartDataRead(HMMIO *phmmioIn, MMCKINFO *pckIn, MMCKINFO *pckInRIFF)
|
||||
{
|
||||
// Seek to the data
|
||||
if (-1 == mmioSeek(*phmmioIn, pckInRIFF->dwDataOffset + sizeof(FOURCC), SEEK_SET))
|
||||
return E_FAIL;
|
||||
|
||||
// Search the input file for for the 'data' chunk.
|
||||
pckIn->ckid = mmioFOURCC('d', 'a', 't', 'a');
|
||||
if (0 != mmioDescend(*phmmioIn, pckIn, pckInRIFF, MMIO_FINDCHUNK))
|
||||
return E_FAIL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: WaveReadFile()
|
||||
// Desc: Reads wave data from the wave file. Make sure we're descended into
|
||||
// the data chunk before calling this function.
|
||||
// hmmioIn - Handle to mmio.
|
||||
// cbRead - # of bytes to read.
|
||||
// pbDest - Destination buffer to put bytes.
|
||||
// cbActualRead - # of bytes actually read.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT WaveReadFile(HMMIO hmmioIn, UINT cbRead, BYTE *pbDest, MMCKINFO *pckIn, UINT *cbActualRead)
|
||||
{
|
||||
MMIOINFO mmioinfoIn; // current status of <hmmioIn>
|
||||
|
||||
*cbActualRead = 0;
|
||||
|
||||
if (0 != mmioGetInfo(hmmioIn, &mmioinfoIn, 0))
|
||||
return E_FAIL;
|
||||
|
||||
UINT cbDataIn = cbRead;
|
||||
if (cbDataIn > pckIn->cksize)
|
||||
cbDataIn = pckIn->cksize;
|
||||
|
||||
pckIn->cksize -= cbDataIn;
|
||||
|
||||
for (DWORD cT = 0; cT < cbDataIn; cT++)
|
||||
{
|
||||
// Copy the bytes from the io to the buffer.
|
||||
if (mmioinfoIn.pchNext == mmioinfoIn.pchEndRead)
|
||||
{
|
||||
if (0 != mmioAdvance(hmmioIn, &mmioinfoIn, MMIO_READ))
|
||||
return E_FAIL;
|
||||
|
||||
if (mmioinfoIn.pchNext == mmioinfoIn.pchEndRead)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Actual copy.
|
||||
*((BYTE *)pbDest + cT) = *((BYTE *)mmioinfoIn.pchNext);
|
||||
mmioinfoIn.pchNext++;
|
||||
}
|
||||
|
||||
if (0 != mmioSetInfo(hmmioIn, &mmioinfoIn, 0))
|
||||
return E_FAIL;
|
||||
|
||||
*cbActualRead = cbDataIn;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CWaveSoundRead()
|
||||
// Desc: Constructs the class
|
||||
//-----------------------------------------------------------------------------
|
||||
CWaveSoundRead::CWaveSoundRead()
|
||||
{
|
||||
m_pwfx = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: ~CWaveSoundRead()
|
||||
// Desc: Destructs the class
|
||||
//-----------------------------------------------------------------------------
|
||||
CWaveSoundRead::~CWaveSoundRead()
|
||||
{
|
||||
Close();
|
||||
SafeDelete(m_pwfx);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Open()
|
||||
// Desc: Opens a wave file for reading
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveSoundRead::Open(std::string const &Filename)
|
||||
{
|
||||
SafeDelete(m_pwfx);
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = WaveOpenFile(Filename, &m_hmmioIn, &m_pwfx, &m_ckInRiff)))
|
||||
return hr;
|
||||
|
||||
if (FAILED(hr = Reset()))
|
||||
return hr;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Reset()
|
||||
// Desc: Resets the internal m_ckIn pointer so reading starts from the
|
||||
// beginning of the file again
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveSoundRead::Reset()
|
||||
{
|
||||
return WaveStartDataRead(&m_hmmioIn, &m_ckIn, &m_ckInRiff);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Read()
|
||||
// Desc: Reads a wave file into a pointer and returns how much read
|
||||
// using m_ckIn to determine where to start reading from
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveSoundRead::Read(UINT nSizeToRead, BYTE *pbData, UINT *pnSizeRead)
|
||||
{
|
||||
return WaveReadFile(m_hmmioIn, nSizeToRead, pbData, &m_ckIn, pnSizeRead);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Close()
|
||||
// Desc: Closes an open wave file
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveSoundRead::Close()
|
||||
{
|
||||
if( m_hmmioIn != NULL ) {
|
||||
mmioClose( m_hmmioIn, 0 );
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
48
old/wavread.h
Normal file
48
old/wavread.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: WavRead.h
|
||||
//
|
||||
// Desc: Support for loading and playing Wave files using DirectSound sound
|
||||
// buffers.
|
||||
//
|
||||
// Copyright (c) 1999 Microsoft Corp. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include <mmsystem.h>
|
||||
#include <string>
|
||||
|
||||
HRESULT WaveOpenFile(std::string const &Filename, HMMIO *phmmioIn, WAVEFORMATEX **ppwfxInfo,
|
||||
MMCKINFO *pckInRIFF);
|
||||
HRESULT WaveStartDataRead(HMMIO *phmmioIn, MMCKINFO *pckIn, MMCKINFO *pckInRIFF);
|
||||
HRESULT WaveReadFile(HMMIO hmmioIn, UINT cbRead, BYTE *pbDest, MMCKINFO *pckIn, UINT *cbActualRead);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: class CWaveSoundRead
|
||||
// Desc: A class to read in sound data from a Wave file
|
||||
//-----------------------------------------------------------------------------
|
||||
class CWaveSoundRead
|
||||
{
|
||||
public:
|
||||
WAVEFORMATEX *m_pwfx; // Pointer to WAVEFORMATEX structure
|
||||
HMMIO m_hmmioIn{ NULL }; // MM I/O handle for the WAVE
|
||||
MMCKINFO m_ckIn; // Multimedia RIFF chunk
|
||||
MMCKINFO m_ckInRiff; // Use in opening a WAVE file
|
||||
|
||||
public:
|
||||
CWaveSoundRead();
|
||||
~CWaveSoundRead();
|
||||
|
||||
HRESULT Open(std::string const &Filename);
|
||||
HRESULT Reset();
|
||||
HRESULT Read(UINT nSizeToRead, BYTE *pbData, UINT *pnSizeRead);
|
||||
HRESULT Close();
|
||||
};
|
||||
Reference in New Issue
Block a user