win32 - added wav recording
This commit is contained in:
parent
503108cfa1
commit
89df112dd8
|
@ -390,6 +390,7 @@ public:
|
|||
virtual BOOL WIFI_Host_InitSystem() { return FALSE; }
|
||||
virtual void WIFI_Host_ShutdownSystem() {}
|
||||
virtual BOOL AVI_IsRecording() { return FALSE; }
|
||||
virtual BOOL WAV_IsRecording() { return FALSE; }
|
||||
virtual void USR_InfoMessage(const char *message) { printf("%s\n", message); }
|
||||
};
|
||||
extern Driver* driver;
|
||||
|
|
|
@ -998,7 +998,7 @@ void SPU_Emulate_core()
|
|||
spu_core_samples = (int)(samples);
|
||||
samples -= spu_core_samples;
|
||||
|
||||
if(driver->AVI_IsRecording())
|
||||
if(driver->AVI_IsRecording() || driver->WAV_IsRecording())
|
||||
SPU_MixAudio<true>(SPU_core,spu_core_samples);
|
||||
else
|
||||
SPU_MixAudio<false>(SPU_core,spu_core_samples);
|
||||
|
|
|
@ -541,6 +541,14 @@
|
|||
RelativePath=".\tileView.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wavout.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wavout.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="userconfig"
|
||||
>
|
||||
|
|
|
@ -664,6 +664,10 @@
|
|||
RelativePath=".\tileView.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wavout.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
|
@ -794,6 +798,10 @@
|
|||
RelativePath=".\tileView.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wavout.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="userconfig"
|
||||
>
|
||||
|
|
|
@ -281,6 +281,8 @@
|
|||
RelativePath=".\throttle.h"/>
|
||||
<File
|
||||
RelativePath=".\tileView.h"/>
|
||||
<File
|
||||
RelativePath=".\wavout.h"/>
|
||||
<File
|
||||
RelativePath="..\font_eng.inc"/>
|
||||
<File
|
||||
|
@ -477,6 +479,8 @@
|
|||
RelativePath=".\throttle.cpp"/>
|
||||
<File
|
||||
RelativePath=".\tileView.cpp"/>
|
||||
<File
|
||||
RelativePath=".\wavout.cpp"/>
|
||||
</Files>
|
||||
</VisualStudioProject>
|
||||
|
||||
|
|
|
@ -664,6 +664,10 @@
|
|||
RelativePath=".\tileView.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wavout.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
|
@ -794,6 +798,10 @@
|
|||
RelativePath=".\tileView.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wavout.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="userconfig"
|
||||
>
|
||||
|
|
|
@ -30,11 +30,11 @@
|
|||
|
||||
#include "debug.h"
|
||||
|
||||
void EMU_PrintError(const char* msg) {
|
||||
static void EMU_PrintError(const char* msg) {
|
||||
LOG(msg);
|
||||
}
|
||||
|
||||
void EMU_PrintMessage(const char* msg) {
|
||||
static void EMU_PrintMessage(const char* msg) {
|
||||
LOG(msg);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "ram_search.h" //In order to call UpdateRamSearch (for loadstate functions)
|
||||
#include "replay.h"
|
||||
#include "aviout.h"
|
||||
#include "wavout.h"
|
||||
|
||||
extern LRESULT OpenFile(); //adelikat: Made this an extern here instead of main.h Seemed icky not to limit the scope of this function
|
||||
|
||||
|
@ -169,6 +170,7 @@ void HK_AutoHoldClearKeyDown(int) {
|
|||
void HK_Reset(int) {ResetGame();}
|
||||
|
||||
void HK_RecordAVI(int) { if (DRV_AviIsRecording()) AviEnd(); else AviRecordTo(); }
|
||||
void HK_RecordWAV(int) { if (DRV_WavIsRecording()) WavEnd(); else WavRecordTo(); }
|
||||
|
||||
void HK_ToggleFrame(int) {frameCounterDisplay ^= true;}
|
||||
void HK_ToggleFPS(int) {FpsDisplay ^= true;}
|
||||
|
@ -435,6 +437,12 @@ void InitCustomKeys (SCustomKeys *keys)
|
|||
keys->StopMovie.page = HOTKEY_PAGE_MOVIE;
|
||||
keys->StopMovie.key = NULL;
|
||||
|
||||
keys->RecordWAV.handleKeyDown = HK_RecordWAV;
|
||||
keys->RecordWAV.code = "RecordWAV";
|
||||
keys->RecordWAV.name = L"Record WAV";
|
||||
keys->RecordWAV.page = HOTKEY_PAGE_MAIN;
|
||||
keys->RecordWAV.key = NULL;
|
||||
|
||||
keys->RecordAVI.handleKeyDown = HK_RecordAVI;
|
||||
keys->RecordAVI.code = "RecordAVI";
|
||||
keys->RecordAVI.name = L"Record AVI";
|
||||
|
|
|
@ -78,7 +78,7 @@ struct SCustomKeys
|
|||
SCustomKey ToggleRasterizer;
|
||||
SCustomKey PrintScreen; //Screenshot
|
||||
|
||||
SCustomKey RecordAVI;
|
||||
SCustomKey RecordWAV, RecordAVI;
|
||||
|
||||
SCustomKey ToggleFrameCounter;
|
||||
SCustomKey ToggleFPS;
|
||||
|
|
|
@ -80,6 +80,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "ramwatch.h"
|
||||
#include "ram_search.h"
|
||||
#include "aviout.h"
|
||||
#include "wavout.h"
|
||||
|
||||
#include "directx/ddraw.h"
|
||||
|
||||
|
@ -1128,6 +1129,8 @@ DWORD WINAPI run()
|
|||
//avi writing
|
||||
DRV_AviSoundUpdate(SPU_core->outbuf,spu_core_samples);
|
||||
DRV_AviVideoUpdate((u16*)GPU_screen);
|
||||
//wav writing
|
||||
DRV_WavSoundUpdate(SPU_core->outbuf,spu_core_samples);
|
||||
|
||||
// if (!skipnextframe)
|
||||
// {
|
||||
|
@ -1524,6 +1527,7 @@ static void ExitRunLoop()
|
|||
}
|
||||
|
||||
BOOL AVI_IsRecording();
|
||||
BOOL WAV_IsRecording();
|
||||
class WinDriver : public Driver
|
||||
{
|
||||
virtual BOOL WIFI_Host_InitSystem() {
|
||||
|
@ -1559,6 +1563,11 @@ class WinDriver : public Driver
|
|||
return ::AVI_IsRecording();
|
||||
}
|
||||
|
||||
virtual BOOL WAV_IsRecording()
|
||||
{
|
||||
return ::WAV_IsRecording();
|
||||
}
|
||||
|
||||
virtual void USR_InfoMessage(const char *message)
|
||||
{
|
||||
SetMessageToDisplay(message);
|
||||
|
@ -1912,6 +1921,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
|||
SaveRecentRoms();
|
||||
NDS_DeInit();
|
||||
DRV_AviEnd();
|
||||
DRV_WavEnd();
|
||||
|
||||
//------SHUTDOWN
|
||||
|
||||
|
@ -2265,6 +2275,62 @@ void AviRecordTo()
|
|||
NDS_UnPause();
|
||||
}
|
||||
|
||||
void WavEnd()
|
||||
{
|
||||
NDS_Pause();
|
||||
DRV_WavEnd();
|
||||
NDS_UnPause();
|
||||
}
|
||||
|
||||
//Shows an Open File menu and starts recording an WAV
|
||||
void WavRecordTo()
|
||||
{
|
||||
NDS_Pause();
|
||||
|
||||
OPENFILENAME ofn;
|
||||
char szChoice[MAX_PATH] = {0};
|
||||
|
||||
////if we are playing a movie, construct the filename from the current movie.
|
||||
////else construct it from the filename.
|
||||
//if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD))
|
||||
//{
|
||||
// extern char curMovieFilename[];
|
||||
// strcpy(szChoice, curMovieFilename);
|
||||
// char* dot = strrchr(szChoice,'.');
|
||||
|
||||
// if (dot)
|
||||
// {
|
||||
// *dot='\0';
|
||||
// }
|
||||
|
||||
// strcat(szChoice, ".wav");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// extern char FileBase[];
|
||||
// sprintf(szChoice, "%s.wav", FileBase);
|
||||
//}
|
||||
|
||||
// wav record file browser
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = MainWindow->getHWnd();
|
||||
ofn.lpstrFilter = "WAV Files (*.wav)\0*.wav\0\0";
|
||||
ofn.lpstrFile = szChoice;
|
||||
ofn.lpstrDefExt = "wav";
|
||||
ofn.lpstrTitle = "Save WAV as";
|
||||
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
|
||||
|
||||
if(GetSaveFileName(&ofn))
|
||||
{
|
||||
DRV_WavBegin(szChoice);
|
||||
}
|
||||
|
||||
NDS_UnPause();
|
||||
}
|
||||
|
||||
void OpenRecentROM(int listNum)
|
||||
{
|
||||
if (listNum > MAX_RECENT_ROMS) return; //Just in case
|
||||
|
@ -2523,6 +2589,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
LoadString(hAppInst, !DRV_AviIsRecording() ? IDM_FILE_RECORDAVI : IDM_FILE_STOPAVI, menuItemString, 256);
|
||||
mii.dwTypeData = menuItemString;
|
||||
SetMenuItemInfo(mainMenu, IDM_FILE_RECORDAVI, FALSE, &mii);
|
||||
//Check if WAV is recording
|
||||
LoadString(hAppInst, !DRV_WavIsRecording() ? IDM_FILE_RECORDWAV : IDM_FILE_STOPWAV, menuItemString, 256);
|
||||
SetMenuItemInfo(mainMenu, IDM_FILE_RECORDWAV, FALSE, &mii);
|
||||
|
||||
//Menu items dependent on a ROM loaded
|
||||
EnableMenuItem(mainMenu, IDM_GAME_INFO, MF_BYCOMMAND | (romloaded) ? MF_ENABLED : MF_GRAYED);
|
||||
|
@ -2532,6 +2601,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
EnableMenuItem(mainMenu, IDM_PRINTSCREEN, MF_BYCOMMAND | (romloaded) ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(mainMenu, IDM_QUICK_PRINTSCREEN, MF_BYCOMMAND | (romloaded) ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(mainMenu, IDM_FILE_RECORDAVI, MF_BYCOMMAND | (romloaded) ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(mainMenu, IDM_FILE_RECORDWAV, MF_BYCOMMAND | (romloaded) ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(mainMenu, IDM_RESET, MF_BYCOMMAND | (romloaded) ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(mainMenu, IDM_SHUT_UP, MF_BYCOMMAND | (romloaded) ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(mainMenu, IDM_CHEATS_LIST, MF_BYCOMMAND | (romloaded) ? MF_ENABLED : MF_GRAYED);
|
||||
|
@ -2867,6 +2937,12 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
else
|
||||
AviRecordTo();
|
||||
break;
|
||||
case IDM_FILE_RECORDWAV:
|
||||
if (DRV_WavIsRecording())
|
||||
WavEnd();
|
||||
else
|
||||
WavRecordTo();
|
||||
break;
|
||||
case IDM_STATE_LOAD:
|
||||
{
|
||||
OPENFILENAME ofn;
|
||||
|
|
|
@ -16,6 +16,8 @@ void FrameAdvance(bool state);
|
|||
void ResetGame(); //Resets game (for the menu item & hotkey
|
||||
void AviRecordTo();
|
||||
void AviEnd();
|
||||
void WavRecordTo();
|
||||
void WavEnd();
|
||||
void SetMessageToDisplay(const char *message); //For sending output to the main screen
|
||||
|
||||
extern bool ShowInputDisplay;
|
||||
|
|
|
@ -510,6 +510,8 @@
|
|||
#define ID_VIEW_DISPLAYMICROPHONE 40014
|
||||
#define IDM_FILE_RECORDAVI 40015
|
||||
#define IDM_FILE_STOPAVI 40016
|
||||
#define IDM_FILE_RECORDWAV 40017
|
||||
#define IDM_FILE_STOPWAV 40018
|
||||
#define IDM_STOPMOVIE 40019
|
||||
#define ID_FILE_RECENTROM 40034
|
||||
#define IDC_SAVETYPE7 40037
|
||||
|
|
|
@ -239,6 +239,7 @@ MENU_PRINCIPAL MENU
|
|||
MENUITEM "Save Screenshot &As...", IDM_PRINTSCREEN
|
||||
MENUITEM "&Quick Screenshot", IDM_QUICK_PRINTSCREEN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Record WAV", IDM_FILE_RECORDWAV
|
||||
MENUITEM "Record AVI", IDM_FILE_RECORDAVI
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Record Movie...", IDM_RECORD_MOVIE
|
||||
|
@ -3685,6 +3686,8 @@ STRINGTABLE
|
|||
{
|
||||
IDM_FILE_RECORDAVI "Record AVI"
|
||||
IDM_FILE_STOPAVI "Stop AVI"
|
||||
IDM_FILE_RECORDWAV "Record WAV"
|
||||
IDM_FILE_STOPWAV "Stop WAV"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
/* wavout.cpp
|
||||
*
|
||||
* Copyright (C) 2006-2008 Zeromus
|
||||
*
|
||||
* This file is part of DeSmuME
|
||||
*
|
||||
* DeSmuME is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DeSmuME is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DeSmuME; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "main.h" //I added this so that this file could gain access to SetMessageToDisplay.
|
||||
#include "types.h"
|
||||
#include "windriver.h"
|
||||
#include "console.h"
|
||||
#include "gfx3d.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <vfw.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
static void EMU_PrintError(const char* msg) {
|
||||
LOG(msg);
|
||||
}
|
||||
|
||||
static void EMU_PrintMessage(const char* msg) {
|
||||
LOG(msg);
|
||||
}
|
||||
|
||||
bool DRV_WavBegin(const char* fname);
|
||||
void DRV_WavEnd();
|
||||
void DRV_WavSoundUpdate(void* soundData, int soundLen);
|
||||
bool DRV_WavIsRecording();
|
||||
|
||||
static struct WAVFile
|
||||
{
|
||||
bool valid;
|
||||
|
||||
WAVEFORMATEX wav_format_master;
|
||||
WAVEFORMATEX wav_format;
|
||||
HMMIO wav_file;
|
||||
|
||||
MMCKINFO waveChunk;
|
||||
MMCKINFO fmtChunk;
|
||||
MMCKINFO dataChunk;
|
||||
} *wav_file = NULL;
|
||||
|
||||
static void wav_create(struct WAVFile** wav_out)
|
||||
{
|
||||
*wav_out = (struct WAVFile*)malloc(sizeof(struct WAVFile));
|
||||
memset(*wav_out, 0, sizeof(struct WAVFile));
|
||||
}
|
||||
|
||||
static void wav_destroy(struct WAVFile** wav_out)
|
||||
{
|
||||
if(!(*wav_out))
|
||||
return;
|
||||
|
||||
if((*wav_out)->wav_file)
|
||||
{
|
||||
mmioAscend((*wav_out)->wav_file, &(*wav_out)->dataChunk, 0);
|
||||
mmioAscend((*wav_out)->wav_file, &(*wav_out)->waveChunk, 0);
|
||||
// mmioFlush((*wav_out)->wav_file, 0);
|
||||
mmioClose((*wav_out)->wav_file, 0);
|
||||
(*wav_out)->wav_file = NULL;
|
||||
}
|
||||
|
||||
free(*wav_out);
|
||||
*wav_out = NULL;
|
||||
}
|
||||
|
||||
static void set_sound_format(const WAVEFORMATEX* wave_format, struct WAVFile* wav_out)
|
||||
{
|
||||
memcpy(&((*wav_out).wav_format_master), wave_format, sizeof(WAVEFORMATEX));
|
||||
}
|
||||
|
||||
static int wav_open(const char* filename, const WAVEFORMATEX* pwfex)
|
||||
{
|
||||
int error = 1;
|
||||
int result = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// close existing first
|
||||
DRV_WavEnd();
|
||||
|
||||
// create the object
|
||||
wav_create(&wav_file);
|
||||
if(!wav_file)
|
||||
break;
|
||||
|
||||
// add audio format
|
||||
set_sound_format(pwfex, wav_file);
|
||||
|
||||
// open the file
|
||||
if(!(wav_file->wav_file = mmioOpen((LPSTR)filename, NULL, MMIO_CREATE|MMIO_WRITE)))
|
||||
break;
|
||||
|
||||
// create WAVE chunk
|
||||
wav_file->waveChunk.fccType = mmioFOURCC('W', 'A', 'V', 'E');
|
||||
mmioCreateChunk(wav_file->wav_file, &wav_file->waveChunk, MMIO_CREATERIFF);
|
||||
|
||||
// create Format chunk
|
||||
wav_file->fmtChunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
|
||||
mmioCreateChunk(wav_file->wav_file, &wav_file->fmtChunk, 0);
|
||||
// then write header
|
||||
memcpy(&wav_file->wav_format, &wav_file->wav_format_master, sizeof(WAVEFORMATEX));
|
||||
wav_file->wav_format.cbSize = 0;
|
||||
mmioWrite(wav_file->wav_file, (HPSTR) &wav_file->wav_format, sizeof(WAVEFORMATEX));
|
||||
mmioAscend(wav_file->wav_file, &wav_file->fmtChunk, 0);
|
||||
|
||||
// create Data chunk
|
||||
wav_file->dataChunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
|
||||
mmioCreateChunk(wav_file->wav_file, &wav_file->dataChunk, 0);
|
||||
|
||||
// success
|
||||
error = 0;
|
||||
result = 1;
|
||||
wav_file->valid = true;
|
||||
|
||||
} while(false);
|
||||
|
||||
if(!result)
|
||||
{
|
||||
wav_destroy(&wav_file);
|
||||
if(error)
|
||||
EMU_PrintError("Error writing WAV file");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool DRV_WavBegin(const char* fname)
|
||||
{
|
||||
DRV_WavEnd();
|
||||
|
||||
WAVEFORMATEX wf;
|
||||
wf.cbSize = sizeof(WAVEFORMATEX);
|
||||
wf.nAvgBytesPerSec = 44100 * 4;
|
||||
wf.nBlockAlign = 4;
|
||||
wf.nChannels = 2;
|
||||
wf.nSamplesPerSec = 44100;
|
||||
wf.wBitsPerSample = 16;
|
||||
wf.wFormatTag = WAVE_FORMAT_PCM;
|
||||
WAVEFORMATEX* pwf = &wf;
|
||||
|
||||
if(!wav_open(fname, pwf))
|
||||
return 0;
|
||||
|
||||
EMU_PrintMessage("WAV recording started.");
|
||||
SetMessageToDisplay("WAV recording started.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL WAV_IsRecording()
|
||||
{
|
||||
return wav_file && wav_file->valid;
|
||||
}
|
||||
void DRV_WavSoundUpdate(void* soundData, int soundLen)
|
||||
{
|
||||
int nBytes;
|
||||
|
||||
if(!WAV_IsRecording())
|
||||
return;
|
||||
|
||||
nBytes = soundLen * wav_file->wav_format.nBlockAlign;
|
||||
// assumes mmio system has been opened data chunk
|
||||
mmioWrite(wav_file->wav_file, (HPSTR) soundData, nBytes);
|
||||
// mmioFlush(wav_file->wav_file, 0);
|
||||
}
|
||||
|
||||
void DRV_WavEnd()
|
||||
{
|
||||
if(!wav_file)
|
||||
return;
|
||||
|
||||
EMU_PrintMessage("WAV recording ended.");
|
||||
SetMessageToDisplay("WAV recording ended.");
|
||||
|
||||
wav_destroy(&wav_file);
|
||||
}
|
||||
|
||||
bool DRV_WavIsRecording()
|
||||
{
|
||||
if(wav_file)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
bool DRV_WavBegin(const char* fname);
|
||||
void DRV_WavEnd();
|
||||
void DRV_WavSoundUpdate(void* soundData, int soundLen);
|
||||
bool DRV_WavIsRecording();
|
Loading…
Reference in New Issue