win32 - added wav recording

This commit is contained in:
gocha 2009-05-18 00:15:48 +00:00
parent 503108cfa1
commit 89df112dd8
15 changed files with 330 additions and 4 deletions

View File

@ -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;

View File

@ -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);

View File

@ -541,6 +541,14 @@
RelativePath=".\tileView.h"
>
</File>
<File
RelativePath=".\wavout.cpp"
>
</File>
<File
RelativePath=".\wavout.h"
>
</File>
<Filter
Name="userconfig"
>

View File

@ -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"
>

View File

@ -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>

View File

@ -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"
>

View File

@ -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);
}

View File

@ -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";

View File

@ -78,7 +78,7 @@ struct SCustomKeys
SCustomKey ToggleRasterizer;
SCustomKey PrintScreen; //Screenshot
SCustomKey RecordAVI;
SCustomKey RecordWAV, RecordAVI;
SCustomKey ToggleFrameCounter;
SCustomKey ToggleFPS;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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"
}

View File

@ -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;
}

View File

@ -0,0 +1,4 @@
bool DRV_WavBegin(const char* fname);
void DRV_WavEnd();
void DRV_WavSoundUpdate(void* soundData, int soundLen);
bool DRV_WavIsRecording();