ASM-accurate Sound.cpp and Organya.cpp (except for one function)
This commit is contained in:
parent
e67c1e3640
commit
470c5d86d5
7 changed files with 1207 additions and 714 deletions
|
@ -34,7 +34,7 @@
|
||||||
Name="VCCustomBuildTool"/>
|
Name="VCCustomBuildTool"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="SDL2/lib/SDL2.lib SDL2/lib/SDL2main.lib freetype/lib/freetype.lib Version.lib"
|
AdditionalDependencies="SDL2/lib/SDL2.lib SDL2/lib/SDL2main.lib freetype/lib/freetype.lib Version.lib DSound.lib WinMM.lib"
|
||||||
OutputFile="$(OutDir)\$(ProjectName).exe"
|
OutputFile="$(OutDir)\$(ProjectName).exe"
|
||||||
LinkIncremental="2"
|
LinkIncremental="2"
|
||||||
AdditionalLibraryDirectories=""
|
AdditionalLibraryDirectories=""
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
Name="VCCustomBuildTool"/>
|
Name="VCCustomBuildTool"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="SDL2/lib/SDL2.lib SDL2/lib/SDL2main.lib freetype/lib/freetype.lib Version.lib"
|
AdditionalDependencies="SDL2/lib/SDL2.lib SDL2/lib/SDL2main.lib freetype/lib/freetype.lib Version.lib DSound.lib WinMM.lib"
|
||||||
OutputFile="$(OutDir)\$(ProjectName).exe"
|
OutputFile="$(OutDir)\$(ProjectName).exe"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
IgnoreAllDefaultLibraries="FALSE"
|
IgnoreAllDefaultLibraries="FALSE"
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
Name="VCCustomBuildTool"/>
|
Name="VCCustomBuildTool"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="SDL2/lib/SDL2.lib SDL2/lib/SDL2main.lib freetype/lib/freetype.lib Version.lib"
|
AdditionalDependencies="SDL2/lib/SDL2.lib SDL2/lib/SDL2main.lib freetype/lib/freetype.lib Version.lib DSound.lib WinMM.lib"
|
||||||
OutputFile="$(OutDir)\$(ProjectName).exe"
|
OutputFile="$(OutDir)\$(ProjectName).exe"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
IgnoreAllDefaultLibraries="FALSE"
|
IgnoreAllDefaultLibraries="FALSE"
|
||||||
|
@ -186,7 +186,7 @@
|
||||||
Name="VCCustomBuildTool"/>
|
Name="VCCustomBuildTool"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="SDL2/lib/SDL2.lib SDL2/lib/SDL2main.lib freetype/lib/freetype.lib Version.lib"
|
AdditionalDependencies="SDL2/lib/SDL2.lib SDL2/lib/SDL2main.lib freetype/lib/freetype.lib Version.lib DSound.lib WinMM.lib"
|
||||||
OutputFile="$(OutDir)\$(ProjectName).exe"
|
OutputFile="$(OutDir)\$(ProjectName).exe"
|
||||||
LinkIncremental="2"
|
LinkIncremental="2"
|
||||||
AdditionalLibraryDirectories=""
|
AdditionalLibraryDirectories=""
|
||||||
|
|
|
@ -963,6 +963,10 @@ addr = 0x41A5D0
|
||||||
name = "LoadTimeCounter"
|
name = "LoadTimeCounter"
|
||||||
addr = 0x41A7C0
|
addr = 0x41A7C0
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "MakeSoundObject8"
|
||||||
|
addr = 0x41A8F0
|
||||||
|
|
||||||
[[func]]
|
[[func]]
|
||||||
name = "ChangeOrganFrequency"
|
name = "ChangeOrganFrequency"
|
||||||
addr = 0x41ABA0
|
addr = 0x41ABA0
|
||||||
|
@ -983,7 +987,7 @@ name = "PlayOrganObject"
|
||||||
addr = 0x41ADC0
|
addr = 0x41ADC0
|
||||||
|
|
||||||
[[func]]
|
[[func]]
|
||||||
name = "ReleaseOrganya"
|
name = "ReleaseOrganyaObject"
|
||||||
addr = 0x41B2A0
|
addr = 0x41B2A0
|
||||||
|
|
||||||
[[func]]
|
[[func]]
|
||||||
|
@ -1010,6 +1014,95 @@ addr = 0x41B4D0
|
||||||
name = "PlayDramObject"
|
name = "PlayDramObject"
|
||||||
addr = 0x41B510
|
addr = 0x41B510
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "OrgData::OrgData"
|
||||||
|
addr = 0x41B600
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "OrgData::InitOrgData"
|
||||||
|
addr = 0x41B650
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "OrgData::SetMusicInfo"
|
||||||
|
addr = 0x41B730
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "OrgData::NoteAlloc"
|
||||||
|
addr = 0x41B890
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "OrgData::ReleaseNote"
|
||||||
|
addr = 0x41BA70
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "OrgData::InitMusicData"
|
||||||
|
addr = 0x41BAD0
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "OrgData::GetMusicInfo"
|
||||||
|
addr = 0x41C0B0
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "InitMMTimer"
|
||||||
|
addr = 0x41C180
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "StartTimer"
|
||||||
|
addr = 0x41C1E0
|
||||||
|
size = 0x4A
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "TimerProc"
|
||||||
|
addr = 0x41C230
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "QuitMMTimer"
|
||||||
|
addr = 0x41C250
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "OrgData::PlayData"
|
||||||
|
addr = 0x41C2B0
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "OrgData::SetPlayPointer"
|
||||||
|
addr = 0x41C630
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "StartOrganya"
|
||||||
|
addr = 0x41C6C0
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "LoadOrganya"
|
||||||
|
addr = 0x41C6F0
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "SetOrganyaPosition"
|
||||||
|
addr = 0x41C730
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "GetOrganyaPosition"
|
||||||
|
addr = 0x41C770
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "PlayOrganyaMusic"
|
||||||
|
addr = 0x41C790
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "ChangeOrganyaVolume"
|
||||||
|
addr = 0x41C7C0
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "StopOrganyaMusic"
|
||||||
|
addr = 0x41C7F0
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "SetOrganyaFadeout"
|
||||||
|
addr = 0x41C880
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "EndOrganya"
|
||||||
|
addr = 0x41C890
|
||||||
|
|
||||||
[[func]]
|
[[func]]
|
||||||
name = "MakeWaveTables"
|
name = "MakeWaveTables"
|
||||||
addr = 0x41C8F0
|
addr = 0x41C8F0
|
||||||
|
@ -1106,6 +1199,22 @@ addr = 0x41FA10
|
||||||
name = "ShootBullet"
|
name = "ShootBullet"
|
||||||
addr = 0x41FE70
|
addr = 0x41FE70
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "InitDirectSound"
|
||||||
|
addr = 0x4200C0
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "EndDirectSound"
|
||||||
|
addr = 0x4201A0
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "InitSoundObject"
|
||||||
|
addr = 0x420240
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "LoadSoundObject"
|
||||||
|
addr = 0x420390
|
||||||
|
|
||||||
[[func]]
|
[[func]]
|
||||||
name = "PlaySoundObject"
|
name = "PlaySoundObject"
|
||||||
addr = 0x420640
|
addr = 0x420640
|
||||||
|
@ -1125,6 +1234,10 @@ name = "ChangeSoundPan"
|
||||||
addr = 0x4207A0
|
addr = 0x4207A0
|
||||||
size = 0x36
|
size = 0x36
|
||||||
|
|
||||||
|
[[func]]
|
||||||
|
name = "MakePixToneObject"
|
||||||
|
addr = 0x4207E0
|
||||||
|
|
||||||
[[func]]
|
[[func]]
|
||||||
name = "TransferStage"
|
name = "TransferStage"
|
||||||
addr = 0x420BE0
|
addr = 0x420BE0
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
#include "SDL_syswm.h"
|
||||||
|
|
||||||
#include "WindowsWrapper.h"
|
#include "WindowsWrapper.h"
|
||||||
|
|
||||||
|
@ -347,11 +348,16 @@ int main(int argc, char *argv[])
|
||||||
CortBox(&clip_rect, 0x000000);
|
CortBox(&clip_rect, 0x000000);
|
||||||
PutBitmap3(&clip_rect, (WINDOW_WIDTH - 64) / 2, (WINDOW_HEIGHT - 8) / 2, &loading_rect, SURFACE_ID_LOADING);
|
PutBitmap3(&clip_rect, (WINDOW_WIDTH - 64) / 2, (WINDOW_HEIGHT - 8) / 2, &loading_rect, SURFACE_ID_LOADING);
|
||||||
|
|
||||||
|
SDL_SysWMinfo wmInfo;
|
||||||
|
SDL_VERSION(&wmInfo.version);
|
||||||
|
SDL_GetWindowWMInfo(gWindow, &wmInfo);
|
||||||
|
ghWnd = wmInfo.info.win.window;
|
||||||
|
|
||||||
// Draw to screen
|
// Draw to screen
|
||||||
if (Flip_SystemTask(ghWnd))
|
if (Flip_SystemTask(ghWnd))
|
||||||
{
|
{
|
||||||
// Initialize sound
|
// Initialize sound
|
||||||
InitDirectSound();
|
InitDirectSound(ghWnd);
|
||||||
|
|
||||||
// Initialize joystick
|
// Initialize joystick
|
||||||
if (config.bJoystick && InitDirectInput())
|
if (config.bJoystick && InitDirectInput())
|
||||||
|
|
1104
src/Organya.cpp
1104
src/Organya.cpp
File diff suppressed because it is too large
Load diff
|
@ -1,57 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <dsound.h>
|
||||||
|
|
||||||
#include "WindowsWrapper.h"
|
#include "WindowsWrapper.h"
|
||||||
|
|
||||||
//Below are Organya song data structures
|
|
||||||
struct NOTELIST
|
|
||||||
{
|
|
||||||
NOTELIST *from; //Previous address
|
|
||||||
NOTELIST *to; //Next address
|
|
||||||
|
|
||||||
long x; //Position
|
|
||||||
unsigned char length; //Sound length
|
|
||||||
unsigned char y; //Sound height
|
|
||||||
unsigned char volume; //Volume
|
|
||||||
unsigned char pan;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Track data * 8
|
|
||||||
struct TRACKDATA
|
|
||||||
{
|
|
||||||
unsigned short freq; //Frequency (1000 is default)
|
|
||||||
unsigned char wave_no; //Waveform No.
|
|
||||||
signed char pipi;
|
|
||||||
unsigned short note_num; //Number of notes
|
|
||||||
|
|
||||||
NOTELIST *note_p;
|
|
||||||
NOTELIST *note_list;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Unique information held in songs
|
|
||||||
struct MUSICINFO
|
|
||||||
{
|
|
||||||
unsigned short wait;
|
|
||||||
BOOL loaded;
|
|
||||||
BOOL playing;
|
|
||||||
unsigned char line; //Number of lines in one measure
|
|
||||||
unsigned char dot; //Number of dots per line
|
|
||||||
unsigned short alloc_note; //Number of allocated notes
|
|
||||||
long repeat_x; //Repeat
|
|
||||||
long end_x; //End of song (Return to repeat)
|
|
||||||
TRACKDATA tdata[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
BOOL MakeOrganyaWave(signed char track, signed char wave_no, signed char pipi);
|
BOOL MakeOrganyaWave(signed char track, signed char wave_no, signed char pipi);
|
||||||
void OrganyaPlayData();
|
void OrganyaPlayData();
|
||||||
void SetPlayPointer(long x);
|
void SetPlayPointer(long x);
|
||||||
void LoadOrganya(const char *name);
|
BOOL LoadOrganya(const char *name);
|
||||||
void SetOrganyaPosition(unsigned int x);
|
void SetOrganyaPosition(unsigned int x);
|
||||||
unsigned int GetOrganyaPosition();
|
unsigned int GetOrganyaPosition();
|
||||||
void PlayOrganyaMusic();
|
void PlayOrganyaMusic();
|
||||||
BOOL ChangeOrganyaVolume(signed int volume);
|
BOOL ChangeOrganyaVolume(signed int volume);
|
||||||
void StopOrganyaMusic();
|
void StopOrganyaMusic();
|
||||||
void SetOrganyaFadeout();
|
void SetOrganyaFadeout();
|
||||||
void OrganyaStartTimer(unsigned int wait);
|
BOOL StartOrganya(LPDIRECTSOUND lpDS, const char *wave_filename);
|
||||||
void OrganyaEndTimer();
|
|
||||||
void StartOrganya();
|
|
||||||
void EndOrganya();
|
void EndOrganya();
|
||||||
|
|
578
src/Sound.cpp
578
src/Sound.cpp
|
@ -1,6 +1,15 @@
|
||||||
// Some of the original source code for this file can be found here:
|
// Some of the original source code for this file can be found here:
|
||||||
// https://github.com/shbow/organya/blob/master/source/Sound.cpp
|
// https://github.com/shbow/organya/blob/master/source/Sound.cpp
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO - Code style
|
||||||
|
Pixel's code was *extremely* Windows-centric, to the point of using
|
||||||
|
things like ZeroMemory and LPCSTR instead of standard things like
|
||||||
|
memset and const char*. For now, the decompilation is accurate despite
|
||||||
|
not using these since they're just macros that evaluate to the portable
|
||||||
|
equivalents.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "Sound.h"
|
#include "Sound.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -8,352 +17,393 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include <dsound.h>
|
||||||
|
|
||||||
#include "WindowsWrapper.h"
|
#include "WindowsWrapper.h"
|
||||||
|
|
||||||
|
#include "CommonDefines.h"
|
||||||
#include "Organya.h"
|
#include "Organya.h"
|
||||||
#include "PixTone.h"
|
#include "PixTone.h"
|
||||||
|
#include "Tags.h"
|
||||||
|
|
||||||
#define FREQUENCY 44100
|
#define FREQUENCY 44100
|
||||||
|
|
||||||
#ifdef RASPBERRY_PI
|
LPDIRECTSOUND lpDS; // DirectSoundオブジェクト (DirectSound object)
|
||||||
#define STREAM_SIZE 0x400 // Larger buffer to prevent stutter
|
LPDIRECTSOUNDBUFFER lpPRIMARYBUFFER; // 一時バッファ (Temporary buffer)
|
||||||
#else
|
LPDIRECTSOUNDBUFFER lpSECONDARYBUFFER[SE_MAX];
|
||||||
#define STREAM_SIZE 0x100 // FREQUENCY/200 rounded to the nearest power of 2 (SDL2 *needs* a power-of-2 buffer size)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define clamp(x, y, z) (((x) > (z)) ? (z) : ((x) < (y)) ? (y) : (x))
|
// DirectSoundの開始 (Starting DirectSound)
|
||||||
|
BOOL InitDirectSound(HWND hwnd)
|
||||||
//Audio device
|
|
||||||
SDL_AudioDeviceID audioDevice;
|
|
||||||
|
|
||||||
//Keep track of all existing sound buffers
|
|
||||||
SOUNDBUFFER *soundBuffers;
|
|
||||||
|
|
||||||
//Sound buffer code
|
|
||||||
SOUNDBUFFER::SOUNDBUFFER(size_t bufSize)
|
|
||||||
{
|
{
|
||||||
//Lock audio buffer
|
int i;
|
||||||
SDL_LockAudioDevice(audioDevice);
|
DSBUFFERDESC1 dsbd;
|
||||||
|
|
||||||
//Set parameters
|
// DirectDrawの初期化 (DirectDraw initialization)
|
||||||
size = bufSize;
|
if (DirectSoundCreate(NULL, &lpDS, NULL) != DS_OK)
|
||||||
|
|
||||||
playing = false;
|
|
||||||
looping = false;
|
|
||||||
looped = false;
|
|
||||||
|
|
||||||
frequency = 0.0;
|
|
||||||
volume = 1.0;
|
|
||||||
volume_l = 1.0;
|
|
||||||
volume_r = 1.0;
|
|
||||||
samplePosition = 0.0;
|
|
||||||
|
|
||||||
//Create waveform buffer
|
|
||||||
data = new unsigned char[bufSize];
|
|
||||||
memset(data, 0x80, bufSize);
|
|
||||||
|
|
||||||
//Add to buffer list
|
|
||||||
this->next = soundBuffers;
|
|
||||||
soundBuffers = this;
|
|
||||||
|
|
||||||
//Unlock audio buffer
|
|
||||||
SDL_UnlockAudioDevice(audioDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
SOUNDBUFFER::~SOUNDBUFFER()
|
|
||||||
{
|
|
||||||
//Lock audio buffer
|
|
||||||
SDL_LockAudioDevice(audioDevice);
|
|
||||||
|
|
||||||
//Free buffer
|
|
||||||
if (data)
|
|
||||||
delete[] data;
|
|
||||||
|
|
||||||
//Remove from buffer list
|
|
||||||
for (SOUNDBUFFER **soundBuffer = &soundBuffers; *soundBuffer != NULL; soundBuffer = &(*soundBuffer)->next)
|
|
||||||
{
|
{
|
||||||
if (*soundBuffer == this)
|
lpDS = NULL;
|
||||||
{
|
StartOrganya(lpDS, "Org\\Wave.dat");
|
||||||
*soundBuffer = this->next;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Unlock audio buffer
|
|
||||||
SDL_UnlockAudioDevice(audioDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SOUNDBUFFER::Release()
|
|
||||||
{
|
|
||||||
//TODO: find a better and more stable(?) way to handle this function
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SOUNDBUFFER::Lock(unsigned char **outBuffer, size_t *outSize)
|
|
||||||
{
|
|
||||||
SDL_LockAudioDevice(audioDevice);
|
|
||||||
|
|
||||||
if (outBuffer != NULL)
|
|
||||||
*outBuffer = data;
|
|
||||||
|
|
||||||
if (outSize != NULL)
|
|
||||||
*outSize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SOUNDBUFFER::Unlock()
|
|
||||||
{
|
|
||||||
SDL_UnlockAudioDevice(audioDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SOUNDBUFFER::SetCurrentPosition(unsigned long dwNewPosition)
|
|
||||||
{
|
|
||||||
SDL_LockAudioDevice(audioDevice);
|
|
||||||
samplePosition = dwNewPosition;
|
|
||||||
SDL_UnlockAudioDevice(audioDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SOUNDBUFFER::SetFrequency(unsigned long dwFrequency)
|
|
||||||
{
|
|
||||||
SDL_LockAudioDevice(audioDevice);
|
|
||||||
frequency = (double)dwFrequency;
|
|
||||||
SDL_UnlockAudioDevice(audioDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
float MillibelToVolume(long lVolume)
|
|
||||||
{
|
|
||||||
//Volume is in hundredths of decibels, from 0 to -10000
|
|
||||||
lVolume = clamp(lVolume, (long)-10000, (long)0);
|
|
||||||
return (float)pow(10.0, lVolume / 2000.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SOUNDBUFFER::SetVolume(long lVolume)
|
|
||||||
{
|
|
||||||
SDL_LockAudioDevice(audioDevice);
|
|
||||||
volume = MillibelToVolume(lVolume);
|
|
||||||
SDL_UnlockAudioDevice(audioDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SOUNDBUFFER::SetPan(long lPan)
|
|
||||||
{
|
|
||||||
SDL_LockAudioDevice(audioDevice);
|
|
||||||
volume_l = MillibelToVolume(-lPan);
|
|
||||||
volume_r = MillibelToVolume(lPan);
|
|
||||||
SDL_UnlockAudioDevice(audioDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SOUNDBUFFER::Play(bool bLooping)
|
|
||||||
{
|
|
||||||
SDL_LockAudioDevice(audioDevice);
|
|
||||||
playing = true;
|
|
||||||
looping = bLooping;
|
|
||||||
SDL_UnlockAudioDevice(audioDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SOUNDBUFFER::Stop()
|
|
||||||
{
|
|
||||||
SDL_LockAudioDevice(audioDevice);
|
|
||||||
playing = false;
|
|
||||||
SDL_UnlockAudioDevice(audioDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SOUNDBUFFER::Mix(float *buffer, size_t frames)
|
|
||||||
{
|
|
||||||
if (!playing) //This sound buffer isn't playing
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < frames; ++i)
|
|
||||||
{
|
|
||||||
const double freqPosition = frequency / FREQUENCY; //This is added to position at the end
|
|
||||||
|
|
||||||
//Get the in-between sample this is (linear interpolation)
|
|
||||||
const float sample1 = ((looped || ((size_t)samplePosition) >= 1) ? data[(size_t)samplePosition] : 128.0f);
|
|
||||||
const float sample2 = ((looping || (((size_t)samplePosition) + 1) < size) ? data[(((size_t)samplePosition) + 1) % size] : 128.0f);
|
|
||||||
|
|
||||||
//Interpolate sample
|
|
||||||
const float subPos = (float)fmod(samplePosition, 1.0);
|
|
||||||
const float sampleA = sample1 + (sample2 - sample1) * subPos;
|
|
||||||
|
|
||||||
//Convert sample to float32
|
|
||||||
const float sampleConvert = (sampleA - 128.0f) / 128.0f;
|
|
||||||
|
|
||||||
//Mix
|
|
||||||
*buffer++ += (float)(sampleConvert * volume * volume_l);
|
|
||||||
*buffer++ += (float)(sampleConvert * volume * volume_r);
|
|
||||||
|
|
||||||
//Increment position
|
|
||||||
samplePosition += freqPosition;
|
|
||||||
|
|
||||||
if (samplePosition >= size)
|
|
||||||
{
|
|
||||||
if (looping)
|
|
||||||
{
|
|
||||||
samplePosition = fmod(samplePosition, size);
|
|
||||||
looped = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
samplePosition = 0.0;
|
|
||||||
playing = false;
|
|
||||||
looped = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Sound mixer
|
|
||||||
void AudioCallback(void *userdata, Uint8 *stream, int len)
|
|
||||||
{
|
|
||||||
(void)userdata;
|
|
||||||
|
|
||||||
float *buffer = (float*)stream;
|
|
||||||
const size_t frames = len / (sizeof(float) * 2);
|
|
||||||
|
|
||||||
//Clear stream
|
|
||||||
for (size_t i = 0; i < frames * 2; ++i)
|
|
||||||
buffer[i] = 0.0f;
|
|
||||||
|
|
||||||
//Mix sounds to primary buffer
|
|
||||||
for (SOUNDBUFFER *sound = soundBuffers; sound != NULL; sound = sound->next)
|
|
||||||
sound->Mix(buffer, frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Sound things
|
|
||||||
SOUNDBUFFER* lpSECONDARYBUFFER[SE_MAX];
|
|
||||||
|
|
||||||
BOOL InitDirectSound()
|
|
||||||
{
|
|
||||||
//Init sound
|
|
||||||
SDL_InitSubSystem(SDL_INIT_AUDIO);
|
|
||||||
|
|
||||||
//Open audio device
|
|
||||||
SDL_AudioSpec want, have;
|
|
||||||
|
|
||||||
//Set specifications we want
|
|
||||||
SDL_memset(&want, 0, sizeof(want));
|
|
||||||
want.freq = FREQUENCY;
|
|
||||||
want.format = AUDIO_F32;
|
|
||||||
want.channels = 2;
|
|
||||||
want.samples = STREAM_SIZE;
|
|
||||||
want.callback = AudioCallback;
|
|
||||||
|
|
||||||
audioDevice = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
|
|
||||||
|
|
||||||
if (audioDevice == 0)
|
|
||||||
{
|
|
||||||
printf("Failed to open audio device\nSDL Error: %s\n", SDL_GetError());
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Unpause audio device
|
lpDS->SetCooperativeLevel(hwnd, DSSCL_EXCLUSIVE);
|
||||||
SDL_PauseAudioDevice(audioDevice, 0);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < SE_MAX; ++i)
|
// 一次バッファの初期化 (Initializing the primary buffer)
|
||||||
|
ZeroMemory(&dsbd, sizeof(DSBUFFERDESC1));
|
||||||
|
dsbd.dwSize = sizeof(DSBUFFERDESC1);
|
||||||
|
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME;
|
||||||
|
lpDS->CreateSoundBuffer((DSBUFFERDESC*)&dsbd, &lpPRIMARYBUFFER, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < SE_MAX; i++)
|
||||||
lpSECONDARYBUFFER[i] = NULL;
|
lpSECONDARYBUFFER[i] = NULL;
|
||||||
|
|
||||||
//Start organya
|
StartOrganya(lpDS, "Org\\Wave.dat");
|
||||||
StartOrganya();
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EndDirectSound()
|
// DirectSoundの終了 (Exit DirectSound)
|
||||||
|
void EndDirectSound(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (lpDS == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
EndOrganya();
|
EndOrganya();
|
||||||
|
|
||||||
for (unsigned int i = 0; i < SE_MAX; ++i)
|
for (i = 0; i < SE_MAX; i++)
|
||||||
if (lpSECONDARYBUFFER[i])
|
if (lpSECONDARYBUFFER[i] != NULL)
|
||||||
lpSECONDARYBUFFER[i]->Release();
|
lpSECONDARYBUFFER[i]->Release();
|
||||||
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
if (lpPRIMARYBUFFER != NULL)
|
||||||
|
lpPRIMARYBUFFER->Release();
|
||||||
|
|
||||||
SDL_CloseAudioDevice(audioDevice);
|
if (lpDS != NULL)
|
||||||
|
lpDS->Release();
|
||||||
|
|
||||||
|
lpDS = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// サウンドの設定 (Sound settings)
|
||||||
|
BOOL InitSoundObject(LPCSTR resname, int no)
|
||||||
|
{
|
||||||
|
HRSRC hrscr;
|
||||||
|
DSBUFFERDESC1 dsbd;
|
||||||
|
DWORD *lpdword; // リソースのアドレス (Resource address)
|
||||||
|
|
||||||
|
if (lpDS == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
// リソースの検索 (Search for resources)
|
||||||
|
if ((hrscr = FindResourceA(NULL, resname, "WAVE")) == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// リソースのアドレスを取得 (Get resource address)
|
||||||
|
lpdword = (DWORD*)LockResource(LoadResource(NULL, hrscr));
|
||||||
|
|
||||||
|
// 二次バッファの生成 (Create secondary buffer)
|
||||||
|
ZeroMemory(&dsbd, sizeof(DSBUFFERDESC1));
|
||||||
|
dsbd.dwSize = sizeof(DSBUFFERDESC1);
|
||||||
|
dsbd.dwFlags = DSBCAPS_STATIC | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
|
||||||
|
dsbd.dwBufferBytes = *(DWORD*)((BYTE*)lpdword+0x36); // WAVEデータのサイズ (WAVE data size)
|
||||||
|
dsbd.lpwfxFormat = (LPWAVEFORMATEX)(lpdword+5);
|
||||||
|
|
||||||
|
if (lpDS->CreateSoundBuffer((DSBUFFERDESC*)&dsbd, &lpSECONDARYBUFFER[no], NULL) != DS_OK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
LPVOID lpbuf1, lpbuf2;
|
||||||
|
DWORD dwbuf1, dwbuf2;
|
||||||
|
|
||||||
|
// 二次バッファのロック (Secondary buffer lock)
|
||||||
|
lpSECONDARYBUFFER[no]->Lock(0, *(DWORD*)((BYTE*)lpdword+0x36), &lpbuf1, &dwbuf1, &lpbuf2, &dwbuf2, 0);
|
||||||
|
|
||||||
|
// 音源データの設定 (Sound source data settings)
|
||||||
|
CopyMemory(lpbuf1, (BYTE*)lpdword+0x3A, dwbuf1);
|
||||||
|
|
||||||
|
if (dwbuf2 != 0)
|
||||||
|
CopyMemory(lpbuf2, (BYTE*)lpdword+0x3A+dwbuf1, dwbuf2);
|
||||||
|
|
||||||
|
// 二次バッファのロック解除 (Unlock secondary buffer)
|
||||||
|
lpSECONDARYBUFFER[no]->Unlock(lpbuf1, dwbuf1, lpbuf2, dwbuf2);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL LoadSoundObject(LPCSTR file_name, int no)
|
||||||
|
{
|
||||||
|
char path[PATH_LENGTH];
|
||||||
|
DWORD i;
|
||||||
|
DWORD file_size = 0;
|
||||||
|
char check_box[58];
|
||||||
|
FILE *fp;
|
||||||
|
HANDLE hFile;
|
||||||
|
|
||||||
|
sprintf(path, "%s\\%s", gModulePath, file_name);
|
||||||
|
|
||||||
|
if (lpDS == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
hFile = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
file_size = GetFileSize(hFile, NULL);
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
if ((fp = fopen(path, "rb")) == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < 58; i++)
|
||||||
|
fread(&check_box[i], sizeof(char), 1, fp);
|
||||||
|
|
||||||
|
if (check_box[0] != 'R')
|
||||||
|
return FALSE;
|
||||||
|
if (check_box[1] != 'I')
|
||||||
|
return FALSE;
|
||||||
|
if (check_box[2] != 'F')
|
||||||
|
return FALSE;
|
||||||
|
if (check_box[3] != 'F')
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
DWORD *wp;
|
||||||
|
wp = (DWORD*)malloc(file_size); // ファイルのワークスペースを作る (Create a file workspace)
|
||||||
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
|
||||||
|
for (i = 0; i < file_size; i++)
|
||||||
|
fread((BYTE*)wp+i, sizeof(BYTE), 1, fp);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
// セカンダリバッファの生成 (Create secondary buffer)
|
||||||
|
DSBUFFERDESC1 dsbd;
|
||||||
|
ZeroMemory(&dsbd, sizeof(DSBUFFERDESC1));
|
||||||
|
dsbd.dwSize = sizeof(DSBUFFERDESC1);
|
||||||
|
dsbd.dwFlags = DSBCAPS_STATIC | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
|
||||||
|
dsbd.dwBufferBytes = *(DWORD*)((BYTE*)wp+0x36); // WAVEデータのサイズ (WAVE data size)
|
||||||
|
dsbd.lpwfxFormat = (LPWAVEFORMATEX)(wp+5);
|
||||||
|
|
||||||
|
if (lpDS->CreateSoundBuffer((DSBUFFERDESC*)&dsbd, &lpSECONDARYBUFFER[no], NULL) != DS_OK)
|
||||||
|
{
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
free(wp); // The updated Organya source code includes this fix
|
||||||
|
#endif
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID lpbuf1, lpbuf2;
|
||||||
|
DWORD dwbuf1, dwbuf2;
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
hr = lpSECONDARYBUFFER[no]->Lock(0, *(DWORD*)((BYTE*)wp+0x36), &lpbuf1, &dwbuf1, &lpbuf2, &dwbuf2, 0);
|
||||||
|
|
||||||
|
if (hr != DS_OK)
|
||||||
|
{
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
free(wp); // The updated Organya source code includes this fix
|
||||||
|
#endif
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMemory(lpbuf1, (BYTE*)wp+0x3A, dwbuf1); // +3aはデータの頭 (+ 3a is the head of the data)
|
||||||
|
|
||||||
|
if (dwbuf2 != 0)
|
||||||
|
CopyMemory(lpbuf2, (BYTE*)wp+0x3A+dwbuf1, dwbuf2);
|
||||||
|
|
||||||
|
lpSECONDARYBUFFER[no]->Unlock(lpbuf1, dwbuf1, lpbuf2, dwbuf2);
|
||||||
|
|
||||||
|
free(wp);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Sound effects playing
|
|
||||||
void PlaySoundObject(int no, int mode)
|
void PlaySoundObject(int no, int mode)
|
||||||
{
|
{
|
||||||
if (lpSECONDARYBUFFER[no])
|
if (lpDS == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (lpSECONDARYBUFFER[no] != NULL)
|
||||||
{
|
{
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0: // 停止 (Stop)
|
||||||
lpSECONDARYBUFFER[no]->Stop();
|
lpSECONDARYBUFFER[no]->Stop();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1: // 再生 (Playback)
|
||||||
lpSECONDARYBUFFER[no]->Stop();
|
lpSECONDARYBUFFER[no]->Stop();
|
||||||
lpSECONDARYBUFFER[no]->SetCurrentPosition(0);
|
lpSECONDARYBUFFER[no]->SetCurrentPosition(0);
|
||||||
lpSECONDARYBUFFER[no]->Play(false);
|
lpSECONDARYBUFFER[no]->Play(0, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case -1:
|
case -1:// ループ再生 (Loop playback)
|
||||||
lpSECONDARYBUFFER[no]->Play(true);
|
lpSECONDARYBUFFER[no]->Play(0, 0, DSBPLAY_LOOPING);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChangeSoundFrequency(int no, unsigned long rate)
|
void ChangeSoundFrequency(int no, DWORD rate) // 100がMIN9999がMAXで2195?がノーマル (100 is MIN, 9999 is MAX, and 2195 is normal)
|
||||||
{
|
{
|
||||||
|
if (lpDS == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
lpSECONDARYBUFFER[no]->SetFrequency((rate * 10) + 100);
|
lpSECONDARYBUFFER[no]->SetFrequency((rate * 10) + 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChangeSoundVolume(int no, long volume)
|
void ChangeSoundVolume(int no, long volume) // 300がMAXで300がノーマル (300 is MAX and 300 is normal)
|
||||||
{
|
{
|
||||||
|
if (lpDS == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
lpSECONDARYBUFFER[no]->SetVolume((volume - 300) * 8);
|
lpSECONDARYBUFFER[no]->SetVolume((volume - 300) * 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChangeSoundPan(int no, long pan)
|
void ChangeSoundPan(int no, long pan) // 512がMAXで256がノーマル (512 is MAX and 256 is normal)
|
||||||
{
|
{
|
||||||
|
if (lpDS == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
lpSECONDARYBUFFER[no]->SetPan((pan - 256) * 10);
|
lpSECONDARYBUFFER[no]->SetPan((pan - 256) * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MakePixToneObject(const PIXTONEPARAMETER *ptp, int ptp_num, int no)
|
int MakePixToneObject(const PIXTONEPARAMETER *ptp, int ptp_num, int no)
|
||||||
{
|
{
|
||||||
int sample_count = 0;
|
typedef struct WavHeader
|
||||||
for (int i = 0; i < ptp_num; ++i)
|
|
||||||
{
|
{
|
||||||
if (ptp[i].size > sample_count)
|
char riff_header[4];
|
||||||
sample_count = ptp[i].size;
|
unsigned long wav_size;
|
||||||
|
char wav_header[4];
|
||||||
|
char fmt_header[4];
|
||||||
|
unsigned long fmt_chunk_size;
|
||||||
|
unsigned short audio_format;
|
||||||
|
unsigned short num_channels;
|
||||||
|
unsigned long sample_rate;
|
||||||
|
unsigned long byte_rate;
|
||||||
|
unsigned short sample_alignment;
|
||||||
|
unsigned short bit_depth;
|
||||||
|
char data_header[4];
|
||||||
|
unsigned long data_bytes;
|
||||||
|
} WavHeader;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
DSBUFFERDESC1 dsbd;
|
||||||
|
WavHeader wav_header;
|
||||||
|
const PIXTONEPARAMETER *ptp_pointer;
|
||||||
|
int sample_count;
|
||||||
|
unsigned char *pcm_buffer;
|
||||||
|
unsigned char *mixed_pcm_buffer;
|
||||||
|
|
||||||
|
if (lpDS == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const char *riff = "RIFF";
|
||||||
|
const char *fmt = "fmt ";
|
||||||
|
const char *wave = "WAVE";
|
||||||
|
const char *data = "data";
|
||||||
|
|
||||||
|
wav_header.bit_depth = 8;
|
||||||
|
wav_header.sample_rate = 22050;
|
||||||
|
wav_header.num_channels = 1;
|
||||||
|
wav_header.audio_format = WAVE_FORMAT_PCM;
|
||||||
|
wav_header.fmt_chunk_size = 16;
|
||||||
|
memcpy(wav_header.riff_header, riff, 4);
|
||||||
|
memcpy(wav_header.fmt_header, fmt, 4);
|
||||||
|
memcpy(wav_header.wav_header, wave, 4);
|
||||||
|
memcpy(wav_header.data_header, data, 4);
|
||||||
|
wav_header.sample_alignment = (wav_header.bit_depth / 8) * wav_header.num_channels;
|
||||||
|
wav_header.byte_rate = (wav_header.bit_depth / 8) * wav_header.num_channels * wav_header.sample_rate;
|
||||||
|
wav_header.data_bytes = wav_header.sample_alignment * ptp->size;
|
||||||
|
wav_header.wav_size = wav_header.data_bytes + 36;
|
||||||
|
|
||||||
|
ptp_pointer = ptp;
|
||||||
|
sample_count = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ptp_num; i++)
|
||||||
|
{
|
||||||
|
if (ptp_pointer->size > sample_count)
|
||||||
|
sample_count = ptp_pointer->size;
|
||||||
|
|
||||||
|
++ptp_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *pcm_buffer = (unsigned char*)malloc(sample_count);
|
ZeroMemory(&dsbd, sizeof(DSBUFFERDESC1));
|
||||||
unsigned char *mixed_pcm_buffer = (unsigned char*)malloc(sample_count);
|
dsbd.dwSize = sizeof(DSBUFFERDESC1);
|
||||||
memset(pcm_buffer, 0x80, sample_count);
|
dsbd.dwFlags = DSBCAPS_STATIC | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
|
||||||
memset(mixed_pcm_buffer, 0x80, sample_count);
|
dsbd.dwBufferBytes = sample_count;
|
||||||
|
dsbd.lpwfxFormat = (WAVEFORMATEX*)&wav_header.audio_format;
|
||||||
|
|
||||||
for (int i = 0; i < ptp_num; ++i)
|
if (lpDS->CreateSoundBuffer((DSBUFFERDESC*)&dsbd, &lpSECONDARYBUFFER[no], 0) != DS_OK)
|
||||||
{
|
return -1;
|
||||||
if (!MakePixelWaveData(&ptp[i], pcm_buffer))
|
|
||||||
|
pcm_buffer = mixed_pcm_buffer = NULL;
|
||||||
|
|
||||||
|
pcm_buffer = (unsigned char*)malloc(sample_count);
|
||||||
|
mixed_pcm_buffer = (unsigned char*)malloc(sample_count);
|
||||||
|
|
||||||
|
if (pcm_buffer == NULL || mixed_pcm_buffer == NULL)
|
||||||
{
|
{
|
||||||
|
if (pcm_buffer != NULL)
|
||||||
free(pcm_buffer);
|
free(pcm_buffer);
|
||||||
|
|
||||||
|
if (mixed_pcm_buffer != NULL)
|
||||||
free(mixed_pcm_buffer);
|
free(mixed_pcm_buffer);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < ptp[i].size; ++j)
|
memset(pcm_buffer, 0x80, sample_count);
|
||||||
|
memset(mixed_pcm_buffer, 0x80, sample_count);
|
||||||
|
|
||||||
|
ptp_pointer = ptp;
|
||||||
|
|
||||||
|
for (i = 0; i < ptp_num; i++)
|
||||||
|
{
|
||||||
|
if (!MakePixelWaveData(ptp_pointer, pcm_buffer))
|
||||||
|
{
|
||||||
|
if (pcm_buffer)
|
||||||
|
free(pcm_buffer);
|
||||||
|
|
||||||
|
if (mixed_pcm_buffer)
|
||||||
|
free(mixed_pcm_buffer);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < ptp_pointer->size; j++)
|
||||||
{
|
{
|
||||||
if (pcm_buffer[j] + mixed_pcm_buffer[j] - 0x100 < -0x7F)
|
if (pcm_buffer[j] + mixed_pcm_buffer[j] - 0x100 < -0x7F)
|
||||||
mixed_pcm_buffer[j] = 0;
|
mixed_pcm_buffer[j] = 0;
|
||||||
else if (pcm_buffer[j] + mixed_pcm_buffer[j] - 0x100 > 0x7F)
|
else if (pcm_buffer[j] + mixed_pcm_buffer[j] - 0x100 > 0x7F)
|
||||||
mixed_pcm_buffer[j] = 0xFF;
|
mixed_pcm_buffer[j] = 0xFF;
|
||||||
else
|
else
|
||||||
mixed_pcm_buffer[j] += pcm_buffer[j] + -0x80;
|
mixed_pcm_buffer[j] = mixed_pcm_buffer[j] + pcm_buffer[j] - 0x80;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lpSECONDARYBUFFER[no] = new SOUNDBUFFER(sample_count);
|
++ptp_pointer;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char *buf;
|
// Maybe this used to be something to prevent audio popping?
|
||||||
lpSECONDARYBUFFER[no]->Lock(&buf, NULL);
|
mixed_pcm_buffer[0] = mixed_pcm_buffer[0];
|
||||||
memcpy(buf, mixed_pcm_buffer, sample_count);
|
mixed_pcm_buffer[sample_count - 1] = mixed_pcm_buffer[sample_count - 1];
|
||||||
lpSECONDARYBUFFER[no]->Unlock();
|
|
||||||
lpSECONDARYBUFFER[no]->SetFrequency(22050);
|
|
||||||
|
|
||||||
|
LPVOID lpbuf1, lpbuf2;
|
||||||
|
DWORD dwbuf1, dwbuf2;
|
||||||
|
|
||||||
|
lpSECONDARYBUFFER[no]->Lock(0, sample_count, &lpbuf1, &dwbuf1, &lpbuf2, &dwbuf2, 0);
|
||||||
|
|
||||||
|
CopyMemory(lpbuf1, mixed_pcm_buffer, dwbuf1);
|
||||||
|
|
||||||
|
if (dwbuf2 != 0)
|
||||||
|
CopyMemory(lpbuf2, mixed_pcm_buffer + dwbuf1, dwbuf2);
|
||||||
|
|
||||||
|
lpSECONDARYBUFFER[no]->Unlock(lpbuf1, dwbuf1, lpbuf2, dwbuf2);
|
||||||
|
|
||||||
|
if (pcm_buffer != NULL)
|
||||||
free(pcm_buffer);
|
free(pcm_buffer);
|
||||||
|
|
||||||
|
if (mixed_pcm_buffer != NULL)
|
||||||
free(mixed_pcm_buffer);
|
free(mixed_pcm_buffer);
|
||||||
|
|
||||||
return sample_count;
|
return sample_count;
|
||||||
|
|
47
src/Sound.h
47
src/Sound.h
|
@ -2,52 +2,19 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <dsound.h>
|
||||||
|
|
||||||
#include "WindowsWrapper.h"
|
#include "WindowsWrapper.h"
|
||||||
|
|
||||||
#include "PixTone.h"
|
#include "PixTone.h"
|
||||||
|
|
||||||
class SOUNDBUFFER
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SOUNDBUFFER(size_t bufSize);
|
|
||||||
~SOUNDBUFFER();
|
|
||||||
|
|
||||||
void Release();
|
|
||||||
|
|
||||||
void Lock(unsigned char **buffer, size_t *size);
|
|
||||||
void Unlock();
|
|
||||||
|
|
||||||
void SetCurrentPosition(unsigned long dwNewPosition);
|
|
||||||
void SetFrequency(unsigned long dwFrequency);
|
|
||||||
void SetVolume(long lVolume);
|
|
||||||
void SetPan(long lPan);
|
|
||||||
void Play(bool bLooping);
|
|
||||||
void Stop();
|
|
||||||
|
|
||||||
void Mix(float *buffer, size_t frames);
|
|
||||||
|
|
||||||
SOUNDBUFFER *next;
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned char *data;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
bool playing;
|
|
||||||
bool looping;
|
|
||||||
bool looped;
|
|
||||||
|
|
||||||
double frequency;
|
|
||||||
double volume;
|
|
||||||
double volume_l;
|
|
||||||
double volume_r;
|
|
||||||
double samplePosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SE_MAX 160 // According to the Organya source code release, this is the real name for this constant
|
#define SE_MAX 160 // According to the Organya source code release, this is the real name for this constant
|
||||||
extern SOUNDBUFFER* lpSECONDARYBUFFER[SE_MAX];
|
|
||||||
|
|
||||||
BOOL InitDirectSound();
|
extern LPDIRECTSOUND lpDS;
|
||||||
void EndDirectSound();
|
extern LPDIRECTSOUNDBUFFER lpSECONDARYBUFFER[SE_MAX];
|
||||||
|
|
||||||
|
BOOL InitDirectSound(HWND hwnd);
|
||||||
|
void EndDirectSound(void);
|
||||||
void PlaySoundObject(int no, int mode);
|
void PlaySoundObject(int no, int mode);
|
||||||
void ChangeSoundFrequency(int no, unsigned long rate);
|
void ChangeSoundFrequency(int no, unsigned long rate);
|
||||||
void ChangeSoundVolume(int no, long volume);
|
void ChangeSoundVolume(int no, long volume);
|
||||||
|
|
Loading…
Add table
Reference in a new issue