winport - support multiple mic samples, selected with new hotkeys
This commit is contained in:
parent
ec351f3015
commit
9805fe3de4
|
@ -99,6 +99,8 @@ int lagframecounter;
|
|||
int LagFrameFlag;
|
||||
int lastLag;
|
||||
int TotalLagFrames;
|
||||
u8 MicSampleSelection = 0;
|
||||
|
||||
|
||||
TSCalInfo TSCal;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2017 DeSmuME team
|
||||
Copyright (C) 2008-2019 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -416,6 +416,7 @@ struct UserTouch
|
|||
struct UserMicrophone
|
||||
{
|
||||
u32 micButtonPressed;
|
||||
u8 micSample;
|
||||
};
|
||||
struct UserInput
|
||||
{
|
||||
|
@ -683,6 +684,7 @@ void NDS_RunAdvansceneAutoImport();
|
|||
extern std::string InputDisplayString;
|
||||
extern int LagFrameFlag;
|
||||
extern int lastLag, TotalLagFrames;
|
||||
extern u8 MicSampleSelection;
|
||||
|
||||
void MovieSRAM();
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
licensed under the terms supplied at the end of this file (for the terms are very long!)
|
||||
Differences from that baseline version are:
|
||||
|
||||
Copyright (C) 2009-2017 DeSmuME team
|
||||
Copyright (C) 2009-2019 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -339,6 +339,21 @@ void HK_StateQuickLoadSlot(int, bool justPressed)
|
|||
void HK_MicrophoneKeyDown(int, bool justPressed) { NDS_setMic(1); }
|
||||
void HK_MicrophoneKeyUp(int) { NDS_setMic(0); }
|
||||
|
||||
void Mic_NextSample();
|
||||
void Mic_PrevSample();
|
||||
|
||||
void HK_NextSampleKeyDown(int, bool justPressed)
|
||||
{
|
||||
Mic_NextSample();
|
||||
driver->AddLine("Mic sample %d selected", MicSampleSelection);
|
||||
}
|
||||
|
||||
void HK_PrevSampleKeyDown(int, bool justPressed)
|
||||
{
|
||||
Mic_PrevSample();
|
||||
driver->AddLine("Mic sample %d selected", MicSampleSelection);
|
||||
}
|
||||
|
||||
void HK_AutoHoldKeyDown(int, bool justPressed) {AutoHoldPressed = true;}
|
||||
void HK_AutoHoldKeyUp(int) {AutoHoldPressed = false;}
|
||||
|
||||
|
@ -702,6 +717,18 @@ void InitCustomKeys (SCustomKeys *keys)
|
|||
keys->Microphone.page = HOTKEY_PAGE_MAIN;
|
||||
keys->Microphone.key = NULL;
|
||||
|
||||
keys->PrevSample.handleKeyDown = HK_PrevSampleKeyDown;
|
||||
keys->PrevSample.code = "Mic Prev Sample";
|
||||
keys->PrevSample.name = L"Mic Prev Sample";
|
||||
keys->PrevSample.page = HOTKEY_PAGE_MAIN;
|
||||
keys->PrevSample.key = NULL;
|
||||
|
||||
keys->NextSample.handleKeyDown = HK_NextSampleKeyDown;
|
||||
keys->NextSample.code = "Mic Next Sample";
|
||||
keys->NextSample.name = L"Mic Next Sample";
|
||||
keys->NextSample.page = HOTKEY_PAGE_MAIN;
|
||||
keys->NextSample.key = NULL;
|
||||
|
||||
keys->AutoHold.handleKeyDown = HK_AutoHoldKeyDown;
|
||||
keys->AutoHold.handleKeyUp = HK_AutoHoldKeyUp;
|
||||
keys->AutoHold.code = "AutoHold";
|
||||
|
@ -715,11 +742,7 @@ void InitCustomKeys (SCustomKeys *keys)
|
|||
keys->AutoHoldClear.page = HOTKEY_PAGE_MAIN;
|
||||
keys->AutoHoldClear.key = NULL;
|
||||
|
||||
keys->ToggleRasterizer.handleKeyDown = HK_ToggleRasterizer;
|
||||
keys->ToggleRasterizer.code = "ToggleRasterizer";
|
||||
keys->ToggleRasterizer.name = STRW(ID_LABEL_HK12);
|
||||
keys->ToggleRasterizer.page = HOTKEY_PAGE_MAIN;
|
||||
keys->ToggleRasterizer.key = VK_SUBTRACT;
|
||||
|
||||
|
||||
//Tools Page ----------------------------------------------------------
|
||||
keys->PrintScreen.handleKeyDown = HK_PrintScreen;
|
||||
|
@ -1059,6 +1082,12 @@ void InitCustomKeys (SCustomKeys *keys)
|
|||
keys->ToggleSubOBJLayer.page = HOTKEY_PAGE_OTHER;
|
||||
keys->ToggleSubOBJLayer.key = NULL;
|
||||
|
||||
keys->ToggleRasterizer.handleKeyDown = HK_ToggleRasterizer;
|
||||
keys->ToggleRasterizer.code = "ToggleRasterizer";
|
||||
keys->ToggleRasterizer.name = STRW(ID_LABEL_HK12);
|
||||
keys->ToggleRasterizer.page = HOTKEY_PAGE_OTHER;
|
||||
keys->ToggleRasterizer.key = VK_SUBTRACT;
|
||||
|
||||
//State/Slots Pages ------------------------------------------------
|
||||
keys->NextSaveSlot.handleKeyDown = HK_NextSaveSlot;
|
||||
keys->NextSaveSlot.code = "NextSaveSlot";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2017 DeSmuME team
|
||||
Copyright (C) 2008-2019 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -78,7 +78,7 @@ struct SCustomKeys
|
|||
#ifdef HAVE_JIT
|
||||
SCustomKey CpuMode, JitBlockSizeDec, JitBlockSizeInc;
|
||||
#endif
|
||||
SCustomKey FrameAdvance, FastForward, FastForwardToggle, IncreaseSpeed, DecreaseSpeed, FrameLimitToggle, Microphone, IncreasePressure, DecreasePressure;
|
||||
SCustomKey FrameAdvance, FastForward, FastForwardToggle, IncreaseSpeed, DecreaseSpeed, FrameLimitToggle, Microphone, PrevSample, NextSample, IncreasePressure, DecreasePressure;
|
||||
|
||||
SCustomKey PlayMovie, RecordMovie, StopMovie, ToggleReadOnly;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2006 Theo Berkau
|
||||
Copyright (C) 2006-2018 DeSmuME team
|
||||
Copyright (C) 2006-2019 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -1854,14 +1854,18 @@ static void RefreshMicSettings()
|
|||
Mic_DeInit_Physical();
|
||||
if(CommonSettings.micMode == TCommonSettings::Sample)
|
||||
{
|
||||
if(!LoadSample(MicSampleName))
|
||||
if(!LoadSamples(MicSampleName))
|
||||
{
|
||||
MessageBox(NULL, "Unable to read the mic sample", "DeSmuME", (MB_OK | MB_ICONEXCLAMATION));
|
||||
}
|
||||
else
|
||||
{
|
||||
driver->AddLine("Mic sample %d selected", MicSampleSelection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadSample(NULL);
|
||||
LoadSamples(nullptr);
|
||||
if(CommonSettings.micMode == TCommonSettings::Physical)
|
||||
{
|
||||
Mic_Init_Physical();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2008-2017 DeSmuME team
|
||||
Copyright (C) 2008-2019 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -40,7 +40,6 @@
|
|||
#include "readwrite.h"
|
||||
|
||||
int MicDisplay;
|
||||
int SampleLoaded=0;
|
||||
|
||||
#define MIC_CHECKERR(hr) if(hr != MMSYSERR_NOERROR) return FALSE;
|
||||
|
||||
|
@ -82,11 +81,9 @@ static int CALLBACK waveInProc(HWAVEIN wavein, UINT msg, DWORD instance, DWORD_P
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char* samplebuffer = NULL;
|
||||
static int samplebuffersize = 0;
|
||||
static FILE* fp = NULL;
|
||||
|
||||
EMUFILE_MEMORY newWavData;
|
||||
std::vector<std::vector<char>> micSamples;
|
||||
|
||||
static bool dataChunk(EMUFILE &inf)
|
||||
{
|
||||
|
@ -110,12 +107,15 @@ static bool dataChunk(EMUFILE &inf)
|
|||
{
|
||||
found = true;
|
||||
u8 *temp = new u8[chunk_length];
|
||||
if (inf.fread(temp,chunk_length) != chunk_length)
|
||||
if (inf.fread(temp,chunk_length) != chunk_length || chunk_length == 0)
|
||||
{
|
||||
delete[] temp;
|
||||
return false;
|
||||
}
|
||||
newWavData.fwrite(temp,chunk_length);
|
||||
micSamples.resize(micSamples.size()+1);
|
||||
std::vector<char>& thisSample = micSamples[micSamples.size()-1];
|
||||
thisSample.resize(chunk_length);
|
||||
memcpy(&thisSample[0], temp, chunk_length);
|
||||
delete[] temp;
|
||||
chunk_length = 0;
|
||||
}
|
||||
|
@ -178,53 +178,109 @@ static bool formatChunk(EMUFILE &inf)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool LoadSample(const char *name)
|
||||
void Mic_PrevSample()
|
||||
{
|
||||
if(MicSampleSelection==0) return;
|
||||
MicSampleSelection--;
|
||||
}
|
||||
|
||||
void Mic_NextSample()
|
||||
{
|
||||
if(MicSampleSelection==255) return;
|
||||
MicSampleSelection++;
|
||||
if(MicSampleSelection >= micSamples.size())
|
||||
{
|
||||
if(micSamples.size()==0)
|
||||
MicSampleSelection = 0;
|
||||
else
|
||||
MicSampleSelection = micSamples.size()-1;
|
||||
}
|
||||
}
|
||||
|
||||
bool LoadSample(const char* name)
|
||||
{
|
||||
SampleLoaded = 0;
|
||||
if (!name) return true;
|
||||
|
||||
EMUFILE_FILE inf(name,"rb");
|
||||
if (inf.fail()) return false;
|
||||
|
||||
//wav reading code adapted from AUDIERE (LGPL)
|
||||
|
||||
// read the RIFF header
|
||||
u8 riff_id[4];
|
||||
u32 riff_length;
|
||||
u8 riff_datatype[4];
|
||||
// read the RIFF header
|
||||
u8 riff_id[4];
|
||||
u32 riff_length;
|
||||
u8 riff_datatype[4];
|
||||
|
||||
inf.fread(riff_id, 4);
|
||||
inf.read_32LE(riff_length);
|
||||
inf.fread(riff_datatype, 4);
|
||||
inf.fread(riff_id, 4);
|
||||
inf.read_32LE(riff_length);
|
||||
inf.fread(riff_datatype, 4);
|
||||
|
||||
if (inf.size() < 12 ||
|
||||
memcmp(riff_id, "RIFF", 4) != 0 ||
|
||||
riff_length == 0 ||
|
||||
memcmp(riff_datatype, "WAVE", 4) != 0) {
|
||||
MessageBox(0,"not a valid RIFF WAVE file",0,0);
|
||||
return false;
|
||||
memcmp(riff_id, "RIFF", 4) != 0 ||
|
||||
riff_length == 0 ||
|
||||
memcmp(riff_datatype, "WAVE", 4) != 0) {
|
||||
MessageBox(0,"not a valid RIFF WAVE file",0,0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!formatChunk(inf))
|
||||
return false;
|
||||
|
||||
if (!dataChunk(inf))
|
||||
{
|
||||
MessageBox(0,"not a valid WAVE file. some unknown problem.",0,0);
|
||||
return false;
|
||||
}
|
||||
|
||||
delete[] samplebuffer;
|
||||
samplebuffersize = (int)newWavData.size();
|
||||
samplebuffer = new char[samplebuffersize];
|
||||
memcpy(samplebuffer,newWavData.buf(),samplebuffersize);
|
||||
new(&newWavData) EMUFILE_MEMORY();
|
||||
if (!formatChunk(inf))
|
||||
return false;
|
||||
|
||||
SampleLoaded=1;
|
||||
if (!dataChunk(inf))
|
||||
{
|
||||
MessageBox(0,"not a valid WAVE file. some unknown problem.",0,0);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadSamples(const char *name)
|
||||
{
|
||||
//unload any existing mic samples
|
||||
micSamples.resize(0);
|
||||
|
||||
//select NO mic sample
|
||||
micReadSamplePos = 0;
|
||||
MicSampleSelection = 0;
|
||||
|
||||
//if we're disabling the mic samples system, just bail now
|
||||
if (!name || !*name) return true;
|
||||
|
||||
//analyze the filename for 0 at the end. anything with 0 at the end is assumed to be the beginning of a series of files
|
||||
//(and if not, it can still be loaded just fine)
|
||||
const char* ext = strchr(name,'.');
|
||||
|
||||
//in case the filename had no extension... it's an error.
|
||||
if(!ext) return false;
|
||||
|
||||
const char* maybe0 = ext-1;
|
||||
|
||||
//if it was not a 0, just load it
|
||||
if(*maybe0 != '0')
|
||||
return LoadSample(name);
|
||||
|
||||
//otherwise replace it with increasing numbers and load all those
|
||||
std::string prefix = name;
|
||||
prefix.resize(maybe0-name);
|
||||
|
||||
//if found, it's a wildcard. load all those samples
|
||||
for(int i=0;;i++)
|
||||
{
|
||||
char tmp[32];
|
||||
sprintf(tmp,"%d",i);
|
||||
std::string trial = prefix + tmp + ".wav";
|
||||
printf("Trying sample %s\n",trial.c_str());
|
||||
bool ok = LoadSample(trial.c_str());
|
||||
if(!ok)
|
||||
{
|
||||
if(i==0) return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//OK, we loaded some samples. that's all we have to do
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL Mic_DeInit_Physical()
|
||||
{
|
||||
if(!Mic_Inited)
|
||||
|
@ -345,17 +401,30 @@ u8 Mic_ReadSample()
|
|||
{
|
||||
if (NDS_getFinalUserInput().mic.micButtonPressed)
|
||||
{
|
||||
if (SampleLoaded)
|
||||
if (micSamples.size() > 0)
|
||||
{
|
||||
//use a sample
|
||||
//TODO: what if a movie is active?
|
||||
// for now I'm going to hope that if anybody records a movie with a sample loaded,
|
||||
// either they know what they're doing and plan to distribute the sample,
|
||||
// or they're playing a game where it doesn't even matter or they never press the mic button.
|
||||
tmp = samplebuffer[micReadSamplePos >> 1];
|
||||
micReadSamplePos++;
|
||||
if (micReadSamplePos == samplebuffersize*2)
|
||||
micReadSamplePos=0;
|
||||
//why is this reading every sample twice? I did this for some reason in 57dbe9128d0f8cbb4bd79154fb9cda3ab6fab386
|
||||
//maybe the game reads two samples in succession to check them or something. stuff definitely works better with the two-in-a-row
|
||||
if (micReadSamplePos == micSamples[MicSampleSelection].size()*2)
|
||||
{
|
||||
tmp = 0x80; //silence, with 8 bit signed values
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = micSamples[MicSampleSelection][micReadSamplePos >> 1];
|
||||
|
||||
//nintendogs seems sensitive to clipped samples, at least.
|
||||
//by clamping these, we get better sounds on playback
|
||||
//I don't know how important it is, but I like nintendogs to sound good at least..
|
||||
if(tmp == 0) tmp = 1;
|
||||
if(tmp == 255) tmp = 254;
|
||||
|
||||
micReadSamplePos++;
|
||||
if(micReadSamplePos == micSamples[MicSampleSelection].size()*2)
|
||||
{
|
||||
printf("Ended mic sample MicSampleSelection\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -844,7 +844,7 @@ BEGIN
|
|||
LTEXT "Sample:",IDC_STATIC,15,83,110,8
|
||||
EDITTEXT IDC_MICSAMPLE,15,93,190,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "...",IDC_MICSAMPLEBROWSE,210,94,20,14
|
||||
CONTROL "Use Microphone Sample",IDC_USEMICSAMPLE,"Button",BS_AUTORADIOBUTTON,18,70,93,10
|
||||
CONTROL "Use Microphone Samples",IDC_USEMICSAMPLE,"Button",BS_AUTORADIOBUTTON,18,70,93,10
|
||||
CONTROL "Use rand() whitenoise (NOT suitable for TAS)",IDC_USEMICRAND,
|
||||
"Button",BS_AUTORADIOBUTTON,18,56,157,10
|
||||
CONTROL "Use internal noise sample",IDC_USENOISE,"Button",BS_AUTORADIOBUTTON,18,43,96,10
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2009-2017 DeSmuME Team
|
||||
Copyright (C) 2009-2019 DeSmuME Team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -24,7 +24,7 @@ class EMUFILE;
|
|||
|
||||
#ifdef WIN32
|
||||
static char MicSampleName[256];
|
||||
bool LoadSample(const char *name);
|
||||
bool LoadSamples(const char *name);
|
||||
#endif
|
||||
|
||||
extern int MicDisplay;
|
||||
|
|
Loading…
Reference in New Issue