mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
[WIP] Rewrite sound engine to support Miniaudio
This commit is contained in:
parent
8e5ed49d3c
commit
07d7871b4f
173
Minecraft.Client/Common/Audio/BinkDecoder.cpp
Normal file
173
Minecraft.Client/Common/Audio/BinkDecoder.cpp
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
#ifdef _WINDOWS64
|
||||
|
||||
#include "BinkDecoder.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
// Heavily referenced from https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/binkaudio.c
|
||||
// and https://wiki.multimedia.cx/index.php?title=Bink_Audio
|
||||
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
static const int critical_freqs[25] = {
|
||||
100, 200, 300, 400, 510, 630, 770, 920,
|
||||
1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150,
|
||||
3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500, 24500
|
||||
};
|
||||
|
||||
static const int rle_lengths[16] = {2,3,4,5,6,8,9,10,11,12,13,14,15,16,32,64};
|
||||
|
||||
BinkDecoder::BinkDecoder()
|
||||
: fileOpen(false), sampleRate(0), channels(0), frameLength(0), windowLength(0),
|
||||
transform(TransformType::DCT)
|
||||
{
|
||||
prevBuffer[0].resize(8192, 0.0f);
|
||||
prevBuffer[1].resize(8192, 0.0f);
|
||||
}
|
||||
|
||||
BinkDecoder::~BinkDecoder() { close(); }
|
||||
|
||||
bool BinkDecoder::open(const std::string& filename) {
|
||||
close();
|
||||
fileStream.open(filename, std::ios::binary);
|
||||
if (!fileStream.is_open()) return false;
|
||||
if (!parseHeader()) { fileStream.close(); return false; }
|
||||
fileOpen = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BinkDecoder::close() {
|
||||
if (fileStream.is_open()) fileStream.close();
|
||||
fileOpen = false;
|
||||
}
|
||||
|
||||
bool BinkDecoder::parseHeader() {
|
||||
uint32_t reportedSize = 0;
|
||||
fileStream.read(reinterpret_cast<char*>(&reportedSize), sizeof(uint32_t));
|
||||
if (fileStream.gcount() != 4 || reportedSize == 0) return false;
|
||||
|
||||
sampleRate = 44100;
|
||||
channels = 2;
|
||||
transform = TransformType::DCT;
|
||||
|
||||
if (sampleRate < 22050) frameLength = 2048;
|
||||
else if (sampleRate < 44100) frameLength = 4096;
|
||||
else frameLength = 8192;
|
||||
|
||||
windowLength = frameLength / 16;
|
||||
return true;
|
||||
}
|
||||
|
||||
float BinkDecoder::readFloat29() {
|
||||
uint32_t raw = 0;
|
||||
fileStream.read(reinterpret_cast<char*>(&raw), 4);
|
||||
if (fileStream.gcount() != 4) return 0.0f;
|
||||
int exponent = (raw >> 23) & 0x1F;
|
||||
int mantissa = raw & 0x7FFFFF;
|
||||
bool sign = (raw >> 31) != 0;
|
||||
float value = ldexpf(static_cast<float>(mantissa), exponent - 23);
|
||||
return sign ? -value : value;
|
||||
}
|
||||
|
||||
bool BinkDecoder::readPacket(std::vector<uint8_t>& packet) {
|
||||
uint32_t packetSize = 0;
|
||||
fileStream.read(reinterpret_cast<char*>(&packetSize), 4);
|
||||
if (fileStream.eof() || packetSize == 0) return false;
|
||||
packet.resize(packetSize);
|
||||
fileStream.read(reinterpret_cast<char*>(packet.data()), packetSize);
|
||||
return fileStream.gcount() == static_cast<std::streamsize>(packetSize);
|
||||
}
|
||||
|
||||
void BinkDecoder::applyDCT(std::vector<float>& coeffs) {
|
||||
size_t N = coeffs.size();
|
||||
std::vector<float> tmp(N, 0.0f);
|
||||
for (size_t k = 0; k < N; k++) {
|
||||
float sum = 0.0f;
|
||||
for (size_t n = 0; n < N; n++)
|
||||
sum += coeffs[n] * cosf(M_PI * (n + 0.5f) * k / N);
|
||||
tmp[k] = sum;
|
||||
}
|
||||
coeffs = tmp;
|
||||
}
|
||||
|
||||
void BinkDecoder::applyRDFT(std::vector<float>& coeffs) {
|
||||
size_t N = coeffs.size();
|
||||
std::vector<float> tmp(N, 0.0f);
|
||||
for (size_t k = 0; k < N; k++) {
|
||||
float sumRe = 0.0f;
|
||||
float sumIm = 0.0f;
|
||||
for (size_t n = 0; n < N; n++) {
|
||||
float angle = 2.0f * M_PI * k * n / N;
|
||||
sumRe += coeffs[n] * cosf(angle);
|
||||
sumIm -= coeffs[n] * sinf(angle);
|
||||
}
|
||||
tmp[k] = sumRe;
|
||||
}
|
||||
coeffs = tmp;
|
||||
}
|
||||
|
||||
void BinkDecoder::decodeBlock(const std::vector<uint8_t>& packet, std::vector<std::vector<float>>& output) {
|
||||
size_t bitPos = 0;
|
||||
auto readBit = [&]() -> bool {
|
||||
if (bitPos / 8 >= packet.size()) return 0;
|
||||
bool b = (packet[bitPos / 8] >> (7 - (bitPos % 8))) & 1;
|
||||
bitPos++;
|
||||
return b;
|
||||
};
|
||||
auto readBits = [&](int n) -> uint32_t {
|
||||
uint32_t val = 0;
|
||||
for (int i = 0; i < n; i++) val = (val << 1) | readBit();
|
||||
return val;
|
||||
};
|
||||
|
||||
std::vector<float> coeffs(frameLength, 0.0f);
|
||||
std::vector<float> quant(25, 0.0f);
|
||||
|
||||
for (uint32_t ch = 0; ch < channels; ch++) {
|
||||
coeffs[0] = readFloat29();
|
||||
coeffs[1] = readFloat29();
|
||||
|
||||
for (int i = 0; i < 25; i++) {
|
||||
int value = readBits(8);
|
||||
quant[i] = powf(10.0f, std::min(value,95) * 0.0664f);
|
||||
}
|
||||
|
||||
int i = 2, k = 0;
|
||||
while (i < static_cast<int>(frameLength)) {
|
||||
int width = readBits(4);
|
||||
if (width == 0) { i++; continue; }
|
||||
while (i < static_cast<int>(frameLength)) {
|
||||
if (i >= critical_freqs[k]) k++;
|
||||
int coeff = readBits(width);
|
||||
coeffs[i] = readBit() ? -coeff * quant[k] : coeff * quant[k];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (transform == TransformType::DCT) applyDCT(coeffs);
|
||||
else applyRDFT(coeffs);
|
||||
|
||||
for (uint32_t w = 0; w < windowLength; w++)
|
||||
output[ch][w] = (prevBuffer[ch][w] * (windowLength - w) + coeffs[w] * w) / windowLength;
|
||||
for (uint32_t s = windowLength; s < frameLength; s++)
|
||||
output[ch][s] = coeffs[s];
|
||||
|
||||
std::copy(coeffs.end() - windowLength, coeffs.end(), prevBuffer[ch].begin());
|
||||
}
|
||||
}
|
||||
|
||||
int BinkDecoder::decodeFrame(std::vector<std::vector<float>>& output) {
|
||||
if (!fileOpen) return -1;
|
||||
std::vector<uint8_t> packet;
|
||||
if (!readPacket(packet)) return -1;
|
||||
|
||||
output.resize(channels);
|
||||
for (auto& buf : output) buf.resize(frameLength, 0.0f);
|
||||
|
||||
decodeBlock(packet, output);
|
||||
return static_cast<int>(frameLength);
|
||||
}
|
||||
|
||||
#endif
|
||||
54
Minecraft.Client/Common/Audio/BinkDecoder.h
Normal file
54
Minecraft.Client/Common/Audio/BinkDecoder.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
|
||||
class BinkDecoder
|
||||
{
|
||||
public:
|
||||
enum class TransformType {
|
||||
DCT,
|
||||
RDFT
|
||||
};
|
||||
|
||||
BinkDecoder();
|
||||
~BinkDecoder();
|
||||
|
||||
bool open(const std::string& filename);
|
||||
void close();
|
||||
|
||||
int decodeFrame(std::vector<std::vector<float>>& output);
|
||||
|
||||
bool isOpen() const { return fileOpen; }
|
||||
uint32_t getSampleRate() const { return sampleRate; }
|
||||
uint32_t getChannels() const { return channels; }
|
||||
uint32_t getFrameLength() const { return frameLength; }
|
||||
TransformType getTransform() const { return transform; }
|
||||
|
||||
private:
|
||||
std::ifstream fileStream;
|
||||
bool fileOpen;
|
||||
|
||||
uint32_t sampleRate;
|
||||
uint32_t channels;
|
||||
uint32_t frameLength;
|
||||
uint32_t windowLength;
|
||||
TransformType transform;
|
||||
|
||||
std::vector<float> prevBuffer[2];
|
||||
|
||||
bool parseHeader();
|
||||
float readFloat29();
|
||||
bool readPacket(std::vector<uint8_t>& packet);
|
||||
void decodeBlock(const std::vector<uint8_t>& packet, std::vector<std::vector<float>>& output);
|
||||
|
||||
void applyDCT(std::vector<float>& coeffs);
|
||||
void applyRDFT(std::vector<float>& coeffs);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -15,7 +15,6 @@
|
|||
#define _SEKRIT
|
||||
#include "..\..\Durango\Miles\include\mss.h"
|
||||
#elif defined _WINDOWS64
|
||||
#include "..\..\windows64\Miles\include\mss.h"
|
||||
#else // PS4
|
||||
// 4J Stu - Temp define to get Miles to link, can likely be removed when we get a new version of Miles
|
||||
#define _SEKRIT2
|
||||
|
|
|
|||
|
|
@ -16,7 +16,12 @@
|
|||
|
||||
#ifdef _WINDOWS64
|
||||
#include "..\..\Minecraft.Client\Windows64\Windows64_App.h"
|
||||
#include "..\..\Minecraft.Client\Windows64\Miles\include\imssapi.h"
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "miniaudio.h"
|
||||
#include "BinkDecoder.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
#ifdef __ORBIS__
|
||||
|
|
@ -95,11 +100,13 @@ char SoundEngine::m_szRedistName[]={"redist"};
|
|||
|
||||
#endif
|
||||
|
||||
#ifndef _WINDOWS64
|
||||
F32 AILCALLBACK custom_falloff_function (HSAMPLE S,
|
||||
F32 distance,
|
||||
F32 rolloff_factor,
|
||||
F32 min_dist,
|
||||
F32 max_dist);
|
||||
#endif
|
||||
|
||||
char *SoundEngine::m_szStreamFileA[eStream_Max]=
|
||||
{
|
||||
|
|
@ -157,6 +164,7 @@ char *SoundEngine::m_szStreamFileA[eStream_Max]=
|
|||
// ErrorCallback
|
||||
//
|
||||
/////////////////////////////////////////////
|
||||
#ifndef _WINDOWS64
|
||||
void AILCALL ErrorCallback(S64 i_Id, char const* i_Details)
|
||||
{
|
||||
char *pchLastError=AIL_last_error();
|
||||
|
|
@ -171,6 +179,9 @@ void AILCALL ErrorCallback(S64 i_Id, char const* i_Details)
|
|||
app.DebugPrintf("ErrorCallback - Details: %s\n", i_Details);
|
||||
}
|
||||
}
|
||||
#else
|
||||
std::vector<MiniAudioSound*> m_activeSounds;
|
||||
#endif
|
||||
|
||||
#ifdef __PSVITA__
|
||||
// AP - this is the callback when the driver is about to mix. At this point the mutex is locked by Miles so we can now call all Miles functions without
|
||||
|
|
@ -201,12 +212,33 @@ void AILCALL MilesMixerCB(HDIGDRIVER dig)
|
|||
// init
|
||||
//
|
||||
/////////////////////////////////////////////
|
||||
void SoundEngine::init(Options *pOptions)
|
||||
void SoundEngine::init(Options* pOptions)
|
||||
{
|
||||
app.DebugPrintf("---SoundEngine::init\n");
|
||||
#ifdef __DISABLE_MILES__
|
||||
return;
|
||||
#endif
|
||||
app.DebugPrintf("---SoundEngine::init\n");
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
m_engineConfig = ma_engine_config_init();
|
||||
m_engineConfig.listenerCount = MAX_LOCAL_PLAYERS;
|
||||
|
||||
if (ma_engine_init(&m_engineConfig, &m_engine) != MA_SUCCESS)
|
||||
{
|
||||
app.DebugPrintf("Failed to initialize miniaudio engine\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ma_engine_set_volume(&m_engine, 1.0f);
|
||||
|
||||
m_MasterMusicVolume = 1.0f;
|
||||
m_MasterEffectsVolume = 1.0f;
|
||||
|
||||
m_validListenerCount = 1;
|
||||
|
||||
m_bSystemMusicPlaying = false;
|
||||
|
||||
app.DebugPrintf("---miniaudio initialized\n");
|
||||
return;
|
||||
|
||||
#else
|
||||
#ifdef __ORBIS__
|
||||
C4JThread::PushAffinityAllCores();
|
||||
#endif
|
||||
|
|
@ -216,7 +248,7 @@ void SoundEngine::init(Options *pOptions)
|
|||
|
||||
char *redistpath;
|
||||
|
||||
#if (defined _WINDOWS64 || defined __PSVITA__)// || defined _DURANGO || defined __ORBIS__ )
|
||||
#if (defined __PSVITA__)// || defined _DURANGO || defined __ORBIS__ )
|
||||
redistpath=AIL_set_redist_directory(m_szRedistName);
|
||||
#endif
|
||||
|
||||
|
|
@ -251,8 +283,6 @@ void SoundEngine::init(Options *pOptions)
|
|||
m_hDriver = AIL_open_digital_driver( 48000, 16, 2, 0 );
|
||||
app.DebugPrintf("---SoundEngine::init - AIL_open_digital_driver\n");
|
||||
|
||||
#else
|
||||
m_hDriver = AIL_open_digital_driver(44100, 16, MSS_MC_USE_SYSTEM_CONFIG, 0);
|
||||
#endif
|
||||
if (m_hDriver == 0)
|
||||
{
|
||||
|
|
@ -372,6 +402,8 @@ void SoundEngine::init(Options *pOptions)
|
|||
// wait for 1 mix...
|
||||
AIL_release_sample_handle(Sample);
|
||||
#endif
|
||||
|
||||
#endif // !_WINDOWS64
|
||||
}
|
||||
|
||||
#ifdef __ORBIS__
|
||||
|
|
@ -401,6 +433,7 @@ void SoundEngine::SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int i
|
|||
}
|
||||
|
||||
// AP - moved to a separate function so it can be called from the mixer callback on Vita
|
||||
#ifndef _WINDOWS64
|
||||
void SoundEngine::updateMiles()
|
||||
{
|
||||
#ifdef __PSVITA__
|
||||
|
|
@ -613,6 +646,105 @@ void SoundEngine::updateMiles()
|
|||
}
|
||||
AIL_complete_event_queue_processing();
|
||||
}
|
||||
#else
|
||||
void SoundEngine::updateMiniAudio()
|
||||
{
|
||||
if (m_validListenerCount == 1)
|
||||
{
|
||||
for (int i = 0; i < MAX_LOCAL_PLAYERS; i++)
|
||||
{
|
||||
if (m_ListenerA[i].bValid)
|
||||
{
|
||||
ma_engine_listener_set_position(
|
||||
&m_engine,
|
||||
0,
|
||||
m_ListenerA[i].vPosition.x,
|
||||
m_ListenerA[i].vPosition.y,
|
||||
m_ListenerA[i].vPosition.z);
|
||||
|
||||
ma_engine_listener_set_direction(
|
||||
&m_engine,
|
||||
0,
|
||||
m_ListenerA[i].vOrientFront.x,
|
||||
m_ListenerA[i].vOrientFront.y,
|
||||
m_ListenerA[i].vOrientFront.z);
|
||||
|
||||
ma_engine_listener_set_world_up(
|
||||
&m_engine,
|
||||
0,
|
||||
0.0f, 1.0f, 0.0f);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ma_engine_listener_set_position(&m_engine, 0, 0.0f, 0.0f, 0.0f);
|
||||
ma_engine_listener_set_direction(&m_engine, 0, 0.0f, 0.0f, 1.0f);
|
||||
ma_engine_listener_set_world_up(&m_engine, 0, 0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
for (auto it = m_activeSounds.begin(); it != m_activeSounds.end(); )
|
||||
{
|
||||
MiniAudioSound* s = *it;
|
||||
|
||||
if (!ma_sound_is_playing(&s->sound))
|
||||
{
|
||||
ma_sound_uninit(&s->sound);
|
||||
delete s;
|
||||
it = m_activeSounds.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
float finalVolume = s->info.volume;
|
||||
if (finalVolume > 1.0f)
|
||||
finalVolume = 1.0f;
|
||||
|
||||
ma_sound_set_volume(&s->sound, finalVolume);
|
||||
|
||||
if (!s->info.bUseSoundsPitchVal)
|
||||
{
|
||||
ma_sound_set_pitch(&s->sound, s->info.pitch);
|
||||
}
|
||||
|
||||
if (s->info.bIs3D)
|
||||
{
|
||||
if (m_validListenerCount > 1)
|
||||
{
|
||||
float closest = 10000.0f;
|
||||
|
||||
for (int i = 0; i < MAX_LOCAL_PLAYERS; i++)
|
||||
{
|
||||
if (m_ListenerA[i].bValid)
|
||||
{
|
||||
float dx = fabs(m_ListenerA[i].vPosition.x - s->info.x);
|
||||
float dy = fabs(m_ListenerA[i].vPosition.y - s->info.y);
|
||||
float dz = fabs(m_ListenerA[i].vPosition.z - s->info.z);
|
||||
|
||||
float dist = dx + dy + dz;
|
||||
if (dist < closest)
|
||||
closest = dist;
|
||||
}
|
||||
}
|
||||
|
||||
float realDist = sqrtf(closest * closest);
|
||||
ma_sound_set_position(&s->sound, 0, 0, realDist);
|
||||
}
|
||||
else
|
||||
{
|
||||
ma_sound_set_position(
|
||||
&s->sound,
|
||||
s->info.x,
|
||||
s->info.y,
|
||||
s->info.z);
|
||||
}
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//#define DISTORTION_TEST
|
||||
#ifdef DISTORTION_TEST
|
||||
|
|
@ -699,7 +831,11 @@ void SoundEngine::tick(shared_ptr<Mob> *players, float a)
|
|||
|
||||
LeaveCriticalSection(&SoundEngine_MixerMutex);
|
||||
#else
|
||||
#ifndef _WINDOWS64
|
||||
updateMiles();
|
||||
#else
|
||||
updateMiniAudio();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -711,7 +847,14 @@ void SoundEngine::tick(shared_ptr<Mob> *players, float a)
|
|||
SoundEngine::SoundEngine()
|
||||
{
|
||||
random = new Random();
|
||||
#ifndef _WINDOWS64
|
||||
m_hStream=0;
|
||||
#else
|
||||
memset(&m_engine, 0, sizeof(ma_engine));
|
||||
memset(&m_engineConfig, 0, sizeof(ma_engine_config));
|
||||
binkaDecoder = nullptr;
|
||||
m_musicStreamActive = false;
|
||||
#endif
|
||||
m_StreamState=eMusicStreamState_Idle;
|
||||
m_iMusicDelay=0;
|
||||
m_validListenerCount=0;
|
||||
|
|
@ -807,9 +950,11 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, floa
|
|||
strncpy(AudioInfo.chName,(char *)szSoundName,64);
|
||||
#endif
|
||||
|
||||
#ifndef _WINDOWS64
|
||||
S32 token = AIL_enqueue_event_start();
|
||||
AIL_enqueue_event_buffer(&token, &AudioInfo, sizeof(AUDIO_INFO), 0);
|
||||
AIL_enqueue_event_end_named(token, (char *)szSoundName);
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
|
@ -817,61 +962,81 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, floa
|
|||
// playUI
|
||||
//
|
||||
/////////////////////////////////////////////
|
||||
void SoundEngine::playUI(int iSound, float volume, float pitch)
|
||||
void SoundEngine::playUI(int iSound, float volume, float pitch)
|
||||
{
|
||||
U8 szSoundName[256];
|
||||
wstring name;
|
||||
// we have some game sounds played as UI sounds...
|
||||
// Not the best way to do this, but it seems to only be the portal sounds
|
||||
U8 szSoundName[256];
|
||||
wstring name;
|
||||
|
||||
if(iSound>=eSFX_MAX)
|
||||
{
|
||||
// AP removed old counting system. Now relying on Miles' Play Count Limit
|
||||
/* // if we are already playing loads of this sounds ignore this one
|
||||
if(CurrentSoundsPlaying[iSound+eSFX_MAX]>MAX_SAME_SOUNDS_PLAYING) return;*/
|
||||
if (iSound >= eSFX_MAX)
|
||||
{
|
||||
strcpy((char*)szSoundName, "Minecraft/");
|
||||
name = wchSoundNames[iSound];
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy((char*)szSoundName, "Minecraft/UI/");
|
||||
name = wchUISoundNames[iSound];
|
||||
}
|
||||
|
||||
// build the name
|
||||
strcpy((char *)szSoundName,"Minecraft/");
|
||||
name = wchSoundNames[iSound];
|
||||
}
|
||||
else
|
||||
{
|
||||
// AP removed old counting system. Now relying on Miles' Play Count Limit
|
||||
/* // if we are already playing loads of this sounds ignore this one
|
||||
if(CurrentSoundsPlaying[iSound]>MAX_SAME_SOUNDS_PLAYING) return;*/
|
||||
char* SoundName = (char*)ConvertSoundPathToName(name);
|
||||
strcat((char*)szSoundName, SoundName);
|
||||
|
||||
// build the name
|
||||
strcpy((char *)szSoundName,"Minecraft/UI/");
|
||||
name = wchUISoundNames[iSound];
|
||||
}
|
||||
#ifdef _WINDOWS64
|
||||
MiniAudioSound* s = new MiniAudioSound();
|
||||
memset(&s->info, 0, sizeof(AUDIO_INFO));
|
||||
|
||||
char *SoundName = (char *)ConvertSoundPathToName(name);
|
||||
strcat((char *)szSoundName,SoundName);
|
||||
// app.DebugPrintf("UI: Playing %s, volume %f, pitch %f\n",SoundName,volume,pitch);
|
||||
s->info.volume = volume;
|
||||
s->info.pitch = pitch;
|
||||
s->info.bIs3D = false;
|
||||
s->info.bUseSoundsPitchVal = true;
|
||||
|
||||
//app.DebugPrintf("PlaySound - %d - %s\n",iSound, SoundName);
|
||||
if (ma_sound_init_from_file(
|
||||
&m_engine,
|
||||
(const char*)szSoundName,
|
||||
MA_SOUND_FLAG_ASYNC,
|
||||
NULL,
|
||||
NULL,
|
||||
&s->sound) != MA_SUCCESS)
|
||||
{
|
||||
delete s;
|
||||
return;
|
||||
}
|
||||
|
||||
ma_sound_set_spatialization_enabled(&s->sound, MA_FALSE);
|
||||
|
||||
float finalVolume = volume * m_MasterEffectsVolume;
|
||||
if (finalVolume > 1.0f)
|
||||
finalVolume = 1.0f;
|
||||
|
||||
ma_sound_set_volume(&s->sound, finalVolume);
|
||||
ma_sound_set_pitch(&s->sound, pitch);
|
||||
|
||||
ma_sound_start(&s->sound);
|
||||
|
||||
m_activeSounds.push_back(s);
|
||||
|
||||
#else
|
||||
AUDIO_INFO AudioInfo;
|
||||
memset(&AudioInfo, 0, sizeof(AUDIO_INFO));
|
||||
|
||||
AudioInfo.volume = volume;
|
||||
AudioInfo.pitch = pitch;
|
||||
AudioInfo.bUseSoundsPitchVal = true;
|
||||
|
||||
if (iSound >= eSFX_MAX)
|
||||
AudioInfo.iSound = iSound + eSFX_MAX;
|
||||
else
|
||||
AudioInfo.iSound = iSound;
|
||||
|
||||
AUDIO_INFO AudioInfo;
|
||||
memset(&AudioInfo,0,sizeof(AUDIO_INFO));
|
||||
AudioInfo.volume=volume; // will be multiplied by the master volume
|
||||
AudioInfo.pitch=pitch;
|
||||
AudioInfo.bUseSoundsPitchVal=true;
|
||||
if(iSound>=eSFX_MAX)
|
||||
{
|
||||
AudioInfo.iSound=iSound+eSFX_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioInfo.iSound=iSound;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
strncpy(AudioInfo.chName,(char *)szSoundName,64);
|
||||
strncpy(AudioInfo.chName, (char*)szSoundName, 64);
|
||||
#endif
|
||||
|
||||
// 4J-PB - not going to stop UI events happening based on the number of currently playing sounds
|
||||
S32 token = AIL_enqueue_event_start();
|
||||
AIL_enqueue_event_buffer(&token, &AudioInfo, sizeof(AUDIO_INFO), 0);
|
||||
AIL_enqueue_event_end_named(token, (char *)szSoundName);
|
||||
S32 token = AIL_enqueue_event_start();
|
||||
AIL_enqueue_event_buffer(&token, &AudioInfo, sizeof(AUDIO_INFO), 0);
|
||||
AIL_enqueue_event_end_named(token, (char*)szSoundName);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
|
@ -1129,19 +1294,76 @@ void SoundEngine::addMusic(const wstring& name, File *file) {}
|
|||
void SoundEngine::addStreaming(const wstring& name, File *file) {}
|
||||
bool SoundEngine::isStreamingWavebankReady() { return true; }
|
||||
|
||||
int SoundEngine::OpenStreamThreadProc( void* lpParameter )
|
||||
int SoundEngine::OpenStreamThreadProc(void* lpParameter)
|
||||
{
|
||||
#ifdef __DISABLE_MILES__
|
||||
return 0;
|
||||
return 0;
|
||||
#endif
|
||||
SoundEngine *soundEngine = (SoundEngine *)lpParameter;
|
||||
soundEngine->m_hStream = AIL_open_stream(soundEngine->m_hDriver,soundEngine->m_szStreamName,0);
|
||||
|
||||
if(soundEngine->m_hStream==0)
|
||||
{
|
||||
app.DebugPrintf("SoundEngine::OpenStreamThreadProc - Could not open - %s\n",soundEngine->m_szStreamName);
|
||||
}
|
||||
return 0;
|
||||
SoundEngine* soundEngine = (SoundEngine*)lpParameter;
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
const char* ext = strrchr(soundEngine->m_szStreamName, '.');
|
||||
bool isBinkaFile = (ext && _stricmp(ext, ".binka") == 0);
|
||||
|
||||
if (isBinkaFile)
|
||||
{
|
||||
if (!soundEngine->binkaDecoder)
|
||||
soundEngine->binkaDecoder = new BinkDecoder();
|
||||
|
||||
if (!soundEngine->binkaDecoder->open(soundEngine->m_szStreamName))
|
||||
{
|
||||
delete soundEngine->binkaDecoder;
|
||||
soundEngine->binkaDecoder = nullptr;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (soundEngine->m_musicStreamActive)
|
||||
{
|
||||
ma_sound_stop(&soundEngine->m_musicStream);
|
||||
ma_sound_uninit(&soundEngine->m_musicStream);
|
||||
soundEngine->m_musicStreamActive = false;
|
||||
}
|
||||
|
||||
ma_result result = ma_sound_init_from_file(
|
||||
&soundEngine->m_engine,
|
||||
soundEngine->m_szStreamName,
|
||||
MA_SOUND_FLAG_STREAM,
|
||||
NULL,
|
||||
NULL,
|
||||
&soundEngine->m_musicStream);
|
||||
|
||||
if (result != MA_SUCCESS)
|
||||
{
|
||||
if (isBinkaFile && soundEngine->binkaDecoder)
|
||||
{
|
||||
delete soundEngine->binkaDecoder;
|
||||
soundEngine->binkaDecoder = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ma_sound_set_spatialization_enabled(&soundEngine->m_musicStream, MA_FALSE);
|
||||
ma_sound_set_looping(&soundEngine->m_musicStream, MA_FALSE);
|
||||
|
||||
soundEngine->m_musicStreamActive = true;
|
||||
|
||||
return 0;
|
||||
|
||||
#else
|
||||
soundEngine->m_hStream = AIL_open_stream(soundEngine->m_hDriver, soundEngine->m_szStreamName, 0);
|
||||
|
||||
if (soundEngine->m_hStream == 0)
|
||||
{
|
||||
app.DebugPrintf(
|
||||
"SoundEngine::OpenStreamThreadProc - Could not open - %s\n",
|
||||
soundEngine->m_szStreamName);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
|
@ -1180,6 +1402,13 @@ void SoundEngine::playMusicUpdate()
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_musicStreamActive)
|
||||
{
|
||||
app.DebugPrintf("WARNING: m_musicStreamActive already true in Idle state, resetting to Playing\n");
|
||||
m_StreamState = eMusicStreamState_Playing;
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_musicID!=-1)
|
||||
{
|
||||
// start playing it
|
||||
|
|
@ -1344,7 +1573,7 @@ void SoundEngine::playMusicUpdate()
|
|||
}
|
||||
else
|
||||
{
|
||||
const char* extensions[] = { ".wav" }; // only wav works outside of binka files to my knowledge, i've only tested ogg, wav, mp3 and only wav worked out of the bunch
|
||||
const char* extensions[] = { ".wav", ".ogg", ".mp3" }; // custom audio formats can be implemented via ma_audio_buffer and whatnot
|
||||
size_t count = sizeof(extensions) / sizeof(extensions[0]);
|
||||
bool found = false;
|
||||
|
||||
|
|
@ -1368,8 +1597,6 @@ void SoundEngine::playMusicUpdate()
|
|||
}
|
||||
|
||||
app.DebugPrintf("Starting streaming - %s\n",m_szStreamName);
|
||||
|
||||
// Don't actually open in this thread, as it can block for ~300ms.
|
||||
m_openStreamThread = new C4JThread(OpenStreamThreadProc, this, "OpenStreamThreadProc");
|
||||
m_openStreamThread->Run();
|
||||
m_StreamState = eMusicStreamState_Opening;
|
||||
|
|
@ -1377,69 +1604,129 @@ void SoundEngine::playMusicUpdate()
|
|||
break;
|
||||
|
||||
case eMusicStreamState_Opening:
|
||||
// If the open stream thread is complete, then we are ready to proceed to actually playing
|
||||
if( !m_openStreamThread->isRunning() )
|
||||
{
|
||||
delete m_openStreamThread;
|
||||
m_openStreamThread = NULL;
|
||||
|
||||
HSAMPLE hSample = AIL_stream_sample_handle( m_hStream);
|
||||
app.DebugPrintf("OpenStreamThreadProc finished. m_musicStreamActive=%d\n", m_musicStreamActive);
|
||||
|
||||
// 4J-PB - causes the falloff to be calculated on the PPU instead of the SPU, and seems to resolve our distorted sound issue
|
||||
AIL_register_falloff_function_callback(hSample,&custom_falloff_function);
|
||||
#ifdef _WINDOWS64
|
||||
if (!m_musicStreamActive)
|
||||
{
|
||||
const char* currentExt = strrchr(reinterpret_cast<char*>(m_szStreamName), '.');
|
||||
if (currentExt && _stricmp(currentExt, ".binka") == 0)
|
||||
{
|
||||
const bool isCD = (m_musicID >= m_iStream_CD_1);
|
||||
const char* folder = isCD ? "cds/" : "music/";
|
||||
|
||||
int n = sprintf_s(reinterpret_cast<char*>(m_szStreamName), 512, "%s%s%s.wav", m_szMusicPath, folder, m_szStreamFileA[m_musicID]);
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
FILE* pFile = nullptr;
|
||||
if (fopen_s(&pFile, reinterpret_cast<char*>(m_szStreamName), "rb") == 0 && pFile)
|
||||
{
|
||||
fclose(pFile);
|
||||
|
||||
m_openStreamThread = new C4JThread(OpenStreamThreadProc, this, "OpenStreamThreadProc");
|
||||
m_openStreamThread->Run();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_StreamState = eMusicStreamState_Idle;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_StreamingAudioInfo.bIs3D)
|
||||
{
|
||||
ma_sound_set_spatialization_enabled(&m_musicStream, MA_TRUE);
|
||||
ma_sound_set_position(&m_musicStream, m_StreamingAudioInfo.x, m_StreamingAudioInfo.y, m_StreamingAudioInfo.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
ma_sound_set_spatialization_enabled(&m_musicStream, MA_FALSE);
|
||||
}
|
||||
|
||||
if(m_StreamingAudioInfo.bIs3D)
|
||||
{
|
||||
AIL_set_sample_3D_distances(hSample,64.0f,1,0); // Larger distance scaler for music discs
|
||||
if(m_validListenerCount>1)
|
||||
{
|
||||
float fClosest=10000.0f;
|
||||
int iClosestListener=0;
|
||||
float fClosestX=0.0f,fClosestY=0.0f,fClosestZ=0.0f,fDist;
|
||||
// need to calculate the distance from the sound to the nearest listener - use Manhattan Distance as the decision
|
||||
for( int i = 0; i < MAX_LOCAL_PLAYERS; i++ )
|
||||
{
|
||||
if( m_ListenerA[i].bValid )
|
||||
{
|
||||
float x,y,z;
|
||||
ma_sound_set_pitch(&m_musicStream, m_StreamingAudioInfo.pitch);
|
||||
|
||||
x=fabs(m_ListenerA[i].vPosition.x-m_StreamingAudioInfo.x);
|
||||
y=fabs(m_ListenerA[i].vPosition.y-m_StreamingAudioInfo.y);
|
||||
z=fabs(m_ListenerA[i].vPosition.z-m_StreamingAudioInfo.z);
|
||||
fDist=x+y+z;
|
||||
float finalVolume = m_StreamingAudioInfo.volume * m_MasterMusicVolume;
|
||||
|
||||
if(fDist<fClosest)
|
||||
{
|
||||
fClosest=fDist;
|
||||
fClosestX=x;
|
||||
fClosestY=y;
|
||||
fClosestZ=z;
|
||||
iClosestListener=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
ma_sound_set_volume(&m_musicStream, finalVolume);
|
||||
ma_result startResult = ma_sound_start(&m_musicStream);
|
||||
app.DebugPrintf("ma_sound_start result: %d\n", startResult);
|
||||
|
||||
// our distances in the world aren't very big, so floats rather than casts to doubles should be fine
|
||||
fDist=sqrtf((fClosestX*fClosestX)+(fClosestY*fClosestY)+(fClosestZ*fClosestZ));
|
||||
AIL_set_sample_3D_position( hSample, 0, 0, fDist );
|
||||
}
|
||||
else
|
||||
{
|
||||
AIL_set_sample_3D_position( hSample, m_StreamingAudioInfo.x, m_StreamingAudioInfo.y, -m_StreamingAudioInfo.z ); // Flipped sign of z as Miles is expecting left handed coord system
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// clear the 3d flag on the stream after a jukebox finishes and streaming music starts
|
||||
AIL_set_sample_is_3D( hSample, 0 );
|
||||
}
|
||||
// set the pitch
|
||||
app.DebugPrintf("Sample rate:%d\n", AIL_sample_playback_rate(hSample));
|
||||
AIL_set_sample_playback_rate_factor(hSample,m_StreamingAudioInfo.pitch);
|
||||
// set the volume
|
||||
AIL_set_sample_volume_levels( hSample, m_StreamingAudioInfo.volume*getMasterMusicVolume(), m_StreamingAudioInfo.volume*getMasterMusicVolume());
|
||||
#else
|
||||
HSAMPLE hSample = AIL_stream_sample_handle(m_hStream);
|
||||
|
||||
AIL_start_stream( m_hStream );
|
||||
AIL_register_falloff_function_callback(
|
||||
hSample,
|
||||
&custom_falloff_function);
|
||||
|
||||
if (m_StreamingAudioInfo.bIs3D)
|
||||
{
|
||||
AIL_set_sample_3D_distances(hSample, 64.0f, 1, 0);
|
||||
|
||||
if (m_validListenerCount > 1)
|
||||
{
|
||||
float fClosest = 10000.0f;
|
||||
int iClosestListener = 0;
|
||||
float fClosestX = 0.0f, fClosestY = 0.0f, fClosestZ = 0.0f, fDist;
|
||||
|
||||
for (int i = 0; i < MAX_LOCAL_PLAYERS; i++)
|
||||
{
|
||||
if (m_ListenerA[i].bValid)
|
||||
{
|
||||
float x = fabs(m_ListenerA[i].vPosition.x - m_StreamingAudioInfo.x);
|
||||
float y = fabs(m_ListenerA[i].vPosition.y - m_StreamingAudioInfo.y);
|
||||
float z = fabs(m_ListenerA[i].vPosition.z - m_StreamingAudioInfo.z);
|
||||
|
||||
fDist = x + y + z;
|
||||
|
||||
if (fDist < fClosest)
|
||||
{
|
||||
fClosest = fDist;
|
||||
fClosestX = x;
|
||||
fClosestY = y;
|
||||
fClosestZ = z;
|
||||
iClosestListener = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fDist = sqrtf((fClosestX * fClosestX) +
|
||||
(fClosestY * fClosestY) +
|
||||
(fClosestZ * fClosestZ));
|
||||
|
||||
AIL_set_sample_3D_position(hSample, 0, 0, fDist);
|
||||
}
|
||||
else
|
||||
{
|
||||
AIL_set_sample_3D_position(
|
||||
hSample,
|
||||
m_StreamingAudioInfo.x,
|
||||
m_StreamingAudioInfo.y,
|
||||
-m_StreamingAudioInfo.z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AIL_set_sample_is_3D(hSample, 0);
|
||||
}
|
||||
|
||||
AIL_set_sample_playback_rate_factor(
|
||||
hSample,
|
||||
m_StreamingAudioInfo.pitch);
|
||||
|
||||
AIL_set_sample_volume_levels(
|
||||
hSample,
|
||||
m_StreamingAudioInfo.volume * getMasterMusicVolume(),
|
||||
m_StreamingAudioInfo.volume * getMasterMusicVolume());
|
||||
|
||||
AIL_start_stream(m_hStream);
|
||||
#endif
|
||||
|
||||
m_StreamState=eMusicStreamState_Playing;
|
||||
}
|
||||
|
|
@ -1453,19 +1740,43 @@ void SoundEngine::playMusicUpdate()
|
|||
}
|
||||
break;
|
||||
case eMusicStreamState_Stop:
|
||||
// should gradually take the volume down in steps
|
||||
AIL_pause_stream(m_hStream,1);
|
||||
#ifdef _WINDOWS64
|
||||
if (m_musicStreamActive)
|
||||
{
|
||||
ma_sound_stop(&m_musicStream);
|
||||
ma_sound_uninit(&m_musicStream);
|
||||
m_musicStreamActive = false;
|
||||
}
|
||||
#else
|
||||
AIL_pause_stream(m_hStream, 1);
|
||||
AIL_close_stream(m_hStream);
|
||||
m_hStream=0;
|
||||
m_hStream = 0;
|
||||
#endif
|
||||
|
||||
SetIsPlayingStreamingCDMusic(false);
|
||||
SetIsPlayingStreamingGameMusic(false);
|
||||
m_StreamState=eMusicStreamState_Idle;
|
||||
break;
|
||||
|
||||
m_StreamState = eMusicStreamState_Idle;
|
||||
break;
|
||||
case eMusicStreamState_Stopping:
|
||||
break;
|
||||
case eMusicStreamState_Play:
|
||||
break;
|
||||
case eMusicStreamState_Playing:
|
||||
#ifdef _WINDOWS64
|
||||
{
|
||||
static int frameCount = 0;
|
||||
if (frameCount++ % 60 == 0)
|
||||
{
|
||||
if (m_musicStreamActive)
|
||||
{
|
||||
bool isPlaying = ma_sound_is_playing(&m_musicStream);
|
||||
float vol = ma_sound_get_volume(&m_musicStream);
|
||||
bool isAtEnd = ma_sound_at_end(&m_musicStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(GetIsPlayingStreamingGameMusic())
|
||||
{
|
||||
//if(m_MusicInfo.pCue!=NULL)
|
||||
|
|
@ -1547,12 +1858,23 @@ void SoundEngine::playMusicUpdate()
|
|||
}
|
||||
|
||||
// volume change required?
|
||||
if(fMusicVol!=getMasterMusicVolume())
|
||||
if (fMusicVol != getMasterMusicVolume())
|
||||
{
|
||||
fMusicVol=getMasterMusicVolume();
|
||||
HSAMPLE hSample = AIL_stream_sample_handle( m_hStream);
|
||||
//AIL_set_sample_3D_position( hSample, m_StreamingAudioInfo.x, m_StreamingAudioInfo.y, m_StreamingAudioInfo.z );
|
||||
AIL_set_sample_volume_levels( hSample, fMusicVol, fMusicVol);
|
||||
#ifdef _WINDOWS64
|
||||
if (m_musicStreamActive)
|
||||
{
|
||||
float finalVolume = m_StreamingAudioInfo.volume * fMusicVol;
|
||||
|
||||
ma_sound_set_volume(&m_musicStream, finalVolume);
|
||||
}
|
||||
|
||||
#else
|
||||
HSAMPLE hSample = AIL_stream_sample_handle(m_hStream);
|
||||
|
||||
float finalVolume = m_StreamingAudioInfo.volume * fMusicVol;
|
||||
AIL_set_sample_volume_levels(hSample, finalVolume, finalVolume);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1592,10 +1914,17 @@ void SoundEngine::playMusicUpdate()
|
|||
}
|
||||
}
|
||||
|
||||
// our distances in the world aren't very big, so floats rather than casts to doubles should be fine
|
||||
HSAMPLE hSample = AIL_stream_sample_handle( m_hStream);
|
||||
fDist=sqrtf((fClosestX*fClosestX)+(fClosestY*fClosestY)+(fClosestZ*fClosestZ));
|
||||
AIL_set_sample_3D_position( hSample, 0, 0, fDist );
|
||||
fDist = sqrtf((fClosestX*fClosestX) + (fClosestY*fClosestY) + (fClosestZ*fClosestZ));
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (m_musicStreamActive)
|
||||
{
|
||||
ma_sound_set_position(&m_musicStream, 0.0f, 0.0f, fDist);
|
||||
}
|
||||
#else
|
||||
HSAMPLE hSample = AIL_stream_sample_handle(m_hStream);
|
||||
AIL_set_sample_3D_position(hSample, 0, 0, fDist);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1651,18 +1980,35 @@ void SoundEngine::playMusicUpdate()
|
|||
|
||||
// check the status of the stream - this is for when a track completes rather than is stopped by the user action
|
||||
|
||||
if(m_hStream!=0)
|
||||
#ifdef _WINDOWS64
|
||||
if (m_musicStreamActive)
|
||||
{
|
||||
if(AIL_stream_status(m_hStream)==SMP_DONE ) // SMP_DONE
|
||||
if (!ma_sound_is_playing(&m_musicStream) && ma_sound_at_end(&m_musicStream))
|
||||
{
|
||||
AIL_close_stream(m_hStream);
|
||||
m_hStream=0;
|
||||
ma_sound_uninit(&m_musicStream);
|
||||
m_musicStreamActive = false;
|
||||
|
||||
SetIsPlayingStreamingCDMusic(false);
|
||||
SetIsPlayingStreamingGameMusic(false);
|
||||
|
||||
m_StreamState=eMusicStreamState_Completed;
|
||||
m_StreamState = eMusicStreamState_Completed;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (m_hStream != 0)
|
||||
{
|
||||
if (AIL_stream_status(m_hStream) == SMP_DONE)
|
||||
{
|
||||
AIL_close_stream(m_hStream);
|
||||
m_hStream = 0;
|
||||
|
||||
SetIsPlayingStreamingCDMusic(false);
|
||||
SetIsPlayingStreamingGameMusic(false);
|
||||
|
||||
m_StreamState = eMusicStreamState_Completed;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1692,6 +2038,7 @@ char *SoundEngine::ConvertSoundPathToName(const wstring& name, bool bConvertSpac
|
|||
#endif
|
||||
|
||||
|
||||
#ifndef _WINDOWS64
|
||||
F32 AILCALLBACK custom_falloff_function (HSAMPLE S,
|
||||
F32 distance,
|
||||
F32 rolloff_factor,
|
||||
|
|
@ -1714,3 +2061,4 @@ F32 AILCALLBACK custom_falloff_function (HSAMPLE S,
|
|||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -4,6 +4,12 @@ class Options;
|
|||
using namespace std;
|
||||
#include "..\..\Minecraft.World\SoundTypes.h"
|
||||
|
||||
#include "miniaudio.h"
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
#include "BinkDecoder.h"
|
||||
#endif
|
||||
|
||||
enum eMUSICFILES
|
||||
{
|
||||
eStream_Overworld_Calm1 = 0,
|
||||
|
|
@ -76,7 +82,11 @@ enum MUSIC_STREAMSTATE
|
|||
|
||||
typedef struct
|
||||
{
|
||||
#ifndef _WINDOWS64
|
||||
F32 x,y,z,volume,pitch;
|
||||
#else
|
||||
float x,y,z,volume,pitch;
|
||||
#endif
|
||||
int iSound;
|
||||
bool bIs3D;
|
||||
bool bUseSoundsPitchVal;
|
||||
|
|
@ -86,6 +96,17 @@ typedef struct
|
|||
}
|
||||
AUDIO_INFO;
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
struct MiniAudioSound
|
||||
{
|
||||
ma_sound sound;
|
||||
AUDIO_INFO info;
|
||||
bool active;
|
||||
};
|
||||
|
||||
extern std::vector<MiniAudioSound*> m_activeSounds;
|
||||
#endif
|
||||
|
||||
class SoundEngine : public ConsoleSoundEngine
|
||||
{
|
||||
static const int MAX_SAME_SOUNDS_PLAYING = 8; // 4J added
|
||||
|
|
@ -112,7 +133,11 @@ public:
|
|||
int getMusicID(int iDomain);
|
||||
int getMusicID(const wstring& name);
|
||||
void SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1);
|
||||
#ifndef _WINDOWS64
|
||||
void updateMiles(); // AP added so Vita can update all the Miles functions during the mixer callback
|
||||
#else
|
||||
void updateMiniAudio();
|
||||
#endif
|
||||
void playMusicUpdate();
|
||||
|
||||
private:
|
||||
|
|
@ -126,10 +151,17 @@ private:
|
|||
|
||||
int GetRandomishTrack(int iStart,int iEnd);
|
||||
|
||||
HMSOUNDBANK m_hBank;
|
||||
HDIGDRIVER m_hDriver;
|
||||
HSTREAM m_hStream;
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
ma_engine m_engine;
|
||||
ma_engine_config m_engineConfig;
|
||||
ma_sound m_musicStream;
|
||||
bool m_musicStreamActive;
|
||||
BinkDecoder *binkaDecoder;
|
||||
#else
|
||||
HMSOUNDBANK m_hBank;
|
||||
HDIGDRIVER m_hDriver;
|
||||
HSTREAM m_hStream;
|
||||
#endif
|
||||
static char m_szSoundPath[];
|
||||
static char m_szMusicPath[];
|
||||
static char m_szRedistName[];
|
||||
|
|
|
|||
95844
Minecraft.Client/Common/Audio/miniaudio.h
Normal file
95844
Minecraft.Client/Common/Audio/miniaudio.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -32,6 +32,7 @@ set(MINECRAFT_CLIENT_SOURCES
|
|||
"Common/Audio/Consoles_SoundEngine.cpp"
|
||||
"Common/Audio/SoundEngine.cpp"
|
||||
"Common/Audio/SoundNames.cpp"
|
||||
"Common/Audio/BinkDecoder.cpp"
|
||||
"Common/Colours/ColourTable.cpp"
|
||||
"Common/ConsoleGameMode.cpp"
|
||||
"Common/Console_Utils.cpp"
|
||||
|
|
@ -476,6 +477,7 @@ set(MINECRAFT_CLIENT_SOURCES
|
|||
"Windows64/Windows64_App.cpp"
|
||||
"Windows64/Windows64_Minecraft.cpp"
|
||||
"Windows64/Windows64_UIController.cpp"
|
||||
"Windows64/Network/WinsockNetLayer.cpp"
|
||||
"WitchModel.cpp"
|
||||
"WitchRenderer.cpp"
|
||||
"WitherBossModel.cpp"
|
||||
|
|
@ -491,4 +493,4 @@ set(MINECRAFT_CLIENT_SOURCES
|
|||
"glWrapper.cpp"
|
||||
"stdafx.cpp"
|
||||
"stubs.cpp"
|
||||
)
|
||||
)
|
||||
Loading…
Reference in a new issue