mirror of https://github.com/PCSX2/pcsx2.git
Capture: Share filename between GSdx and Spu2-x
Shares a single filename between the two capture functions so that the .avi and .wav will match. Default wavdump filename changed to "audio_recording.wav"
This commit is contained in:
parent
bd91a571a6
commit
1ff67c6c1b
|
@ -410,7 +410,7 @@ typedef void(CALLBACK *_GSsetGameCRC)(int, int);
|
|||
typedef void(CALLBACK *_GSsetFrameSkip)(int frameskip);
|
||||
typedef void(CALLBACK *_GSsetVsync)(int enabled);
|
||||
typedef void(CALLBACK *_GSsetExclusive)(int isExclusive);
|
||||
typedef int(CALLBACK *_GSsetupRecording)(int, void *);
|
||||
typedef std::wstring*(CALLBACK *_GSsetupRecording)(int);
|
||||
typedef void(CALLBACK *_GSreset)();
|
||||
typedef void(CALLBACK *_GSwriteCSR)(u32 value);
|
||||
typedef void(CALLBACK *_GSmakeSnapshot)(const char *path);
|
||||
|
@ -445,7 +445,7 @@ typedef void(CALLBACK *_SPU2irqCallback)(void (*SPU2callback)(), void (*DMA4call
|
|||
typedef u32(CALLBACK *_SPU2ReadMemAddr)(int core);
|
||||
typedef void(CALLBACK *_SPU2WriteMemAddr)(int core, u32 value);
|
||||
|
||||
typedef int(CALLBACK *_SPU2setupRecording)(int, void *);
|
||||
typedef int(CALLBACK *_SPU2setupRecording)(int, std::wstring*);
|
||||
|
||||
typedef void(CALLBACK *_SPU2setClockPtr)(u32 *ptr);
|
||||
typedef void(CALLBACK *_SPU2setTimeStretcher)(short int enable);
|
||||
|
|
|
@ -421,37 +421,52 @@ namespace Implementations
|
|||
g_Pcsx2Recording ^= 1;
|
||||
|
||||
GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start.
|
||||
if (g_Pcsx2Recording) {
|
||||
if (g_Pcsx2Recording)
|
||||
{
|
||||
// start recording
|
||||
|
||||
// make the recording setup dialog[s] pseudo-modal also for the main PCSX2 window
|
||||
// (the GSdx dialog is already properly modal for the GS window)
|
||||
bool needsMainFrameEnable = false;
|
||||
if (GetMainFramePtr() && GetMainFramePtr()->IsEnabled()) {
|
||||
if (GetMainFramePtr() && GetMainFramePtr()->IsEnabled())
|
||||
{
|
||||
needsMainFrameEnable = true;
|
||||
GetMainFramePtr()->Disable();
|
||||
}
|
||||
|
||||
if (GSsetupRecording) {
|
||||
if (GSsetupRecording)
|
||||
{
|
||||
// GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens.
|
||||
if (GSsetupRecording(g_Pcsx2Recording, NULL)) {
|
||||
if (SPU2setupRecording) SPU2setupRecording(g_Pcsx2Recording, NULL);
|
||||
} else {
|
||||
std::wstring* filename = nullptr;
|
||||
if (filename = GSsetupRecording(g_Pcsx2Recording))
|
||||
{
|
||||
if (SPU2setupRecording)
|
||||
SPU2setupRecording(g_Pcsx2Recording, filename);
|
||||
delete filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
// recording dialog canceled by the user. align our state
|
||||
g_Pcsx2Recording ^= 1;
|
||||
}
|
||||
} else {
|
||||
// the GS doesn't support recording.
|
||||
if (SPU2setupRecording) SPU2setupRecording(g_Pcsx2Recording, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the GS doesn't support recording
|
||||
if (SPU2setupRecording)
|
||||
SPU2setupRecording(g_Pcsx2Recording, NULL);
|
||||
}
|
||||
|
||||
if (GetMainFramePtr() && needsMainFrameEnable)
|
||||
GetMainFramePtr()->Enable();
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// stop recording
|
||||
if (GSsetupRecording) GSsetupRecording(g_Pcsx2Recording, NULL);
|
||||
if (SPU2setupRecording) SPU2setupRecording(g_Pcsx2Recording, NULL);
|
||||
if (GSsetupRecording)
|
||||
GSsetupRecording(g_Pcsx2Recording);
|
||||
if (SPU2setupRecording)
|
||||
SPU2setupRecording(g_Pcsx2Recording, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -851,13 +851,13 @@ void MainEmuFrame::VideoCaptureUpdate()
|
|||
|
||||
if (GSsetupRecording)
|
||||
{
|
||||
// GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens.
|
||||
if (GSsetupRecording(m_capturingVideo, NULL))
|
||||
// GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens
|
||||
std::wstring* filename = nullptr;
|
||||
if (filename = GSsetupRecording(m_capturingVideo))
|
||||
{
|
||||
if (SPU2setupRecording)
|
||||
{
|
||||
SPU2setupRecording(m_capturingVideo, NULL);
|
||||
}
|
||||
SPU2setupRecording(m_capturingVideo, filename);
|
||||
delete filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -870,27 +870,21 @@ void MainEmuFrame::VideoCaptureUpdate()
|
|||
// the GS doesn't support recording.
|
||||
if (SPU2setupRecording)
|
||||
{
|
||||
SPU2setupRecording(m_capturingVideo, NULL);
|
||||
SPU2setupRecording(m_capturingVideo, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetMainFramePtr() && needsMainFrameEnable)
|
||||
{
|
||||
GetMainFramePtr()->Enable();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// stop recording
|
||||
if (GSsetupRecording)
|
||||
{
|
||||
GSsetupRecording(m_capturingVideo, NULL);
|
||||
}
|
||||
GSsetupRecording(m_capturingVideo);
|
||||
if (SPU2setupRecording)
|
||||
{
|
||||
SPU2setupRecording(m_capturingVideo, NULL);
|
||||
}
|
||||
SPU2setupRecording(m_capturingVideo, nullptr);
|
||||
}
|
||||
|
||||
if (m_capturingVideo)
|
||||
|
|
|
@ -811,27 +811,31 @@ void pt(const char* str){
|
|||
printf("%02i:%02i:%02i%s", current->tm_hour, current->tm_min, current->tm_sec, str);
|
||||
}
|
||||
|
||||
EXPORT_C_(int) GSsetupRecording(int start, void* data)
|
||||
EXPORT_C_(std::wstring*) GSsetupRecording(int start)
|
||||
{
|
||||
if (s_gs == NULL) {
|
||||
printf("GSdx: no s_gs for recording\n");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
#if defined(__unix__)
|
||||
if (!theApp.GetConfigB("capture_enabled")) {
|
||||
printf("GSdx: Recording is disabled\n");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::wstring* filename = nullptr;
|
||||
if(start & 1)
|
||||
{
|
||||
printf("GSdx: Recording start command\n");
|
||||
if (s_gs->BeginCapture()) {
|
||||
filename = s_gs->BeginCapture();
|
||||
if (filename)
|
||||
{
|
||||
pt(" - Capture started\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
pt(" - Capture cancelled\n");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -841,7 +845,7 @@ EXPORT_C_(int) GSsetupRecording(int start, void* data)
|
|||
pt(" - Capture ended\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
return filename;
|
||||
}
|
||||
|
||||
EXPORT_C GSsetGameCRC(uint32 crc, int options)
|
||||
|
|
|
@ -404,7 +404,7 @@ GSCapture::~GSCapture()
|
|||
EndCapture();
|
||||
}
|
||||
|
||||
bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float aspect)
|
||||
std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float aspect)
|
||||
{
|
||||
printf("Recommended resolution: %d x %d, DAR for muxing: %.4f\n", recommendedResolution.x, recommendedResolution.y, aspect);
|
||||
std::lock_guard<std::recursive_mutex> lock(m_lock);
|
||||
|
@ -418,7 +418,7 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float
|
|||
GSCaptureDlg dlg;
|
||||
|
||||
if (IDOK != dlg.DoModal())
|
||||
return false;
|
||||
return nullptr;
|
||||
|
||||
m_size.x = (dlg.m_width + 7) & ~7;
|
||||
m_size.y = (dlg.m_height + 7) & ~7;
|
||||
|
@ -428,7 +428,7 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float
|
|||
if (start > 0)
|
||||
{
|
||||
std::string test = dlg.m_filename.substr(start);
|
||||
std::transform(test.begin(), test.end(), test.begin(), tolower);
|
||||
std::transform(test.begin(), test.end(), test.begin(), (char(_cdecl*)(int))tolower);
|
||||
if (test.compare(".avi") != 0)
|
||||
dlg.m_filename += ".avi";
|
||||
}
|
||||
|
@ -449,7 +449,7 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float
|
|||
|| FAILED(hr = cgb->SetFiltergraph(m_graph))
|
||||
|| FAILED(hr = cgb->SetOutputFileName(&MEDIASUBTYPE_Avi, fn.c_str(), &mux, NULL)))
|
||||
{
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_src = new GSSource(m_size.x, m_size.y, fps, NULL, hr, dlg.m_colorspace);
|
||||
|
@ -457,31 +457,30 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float
|
|||
if (dlg.m_enc==0)
|
||||
{
|
||||
if (FAILED(hr = m_graph->AddFilter(m_src, L"Source")))
|
||||
return false;
|
||||
return nullptr;
|
||||
if (FAILED(hr = m_graph->ConnectDirect(GetFirstPin(m_src, PINDIR_OUTPUT), GetFirstPin(mux, PINDIR_INPUT), NULL)))
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(FAILED(hr = m_graph->AddFilter(m_src, L"Source"))
|
||||
|| FAILED(hr = m_graph->AddFilter(dlg.m_enc, L"Encoder")))
|
||||
{
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(FAILED(hr = m_graph->ConnectDirect(GetFirstPin(m_src, PINDIR_OUTPUT), GetFirstPin(dlg.m_enc, PINDIR_INPUT), NULL))
|
||||
|| FAILED(hr = m_graph->ConnectDirect(GetFirstPin(dlg.m_enc, PINDIR_OUTPUT), GetFirstPin(mux, PINDIR_INPUT), NULL)))
|
||||
{
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
BeginEnumFilters(m_graph, pEF, pBF)
|
||||
{
|
||||
CFilterInfo fi;
|
||||
pBF->QueryFilterInfo(&fi);
|
||||
std::wstring s{fi.achName};
|
||||
printf("Filter [%p]: %s\n", pBF.p, std::string{s.begin(), s.end()}.c_str());
|
||||
CFilterInfo filter;
|
||||
pBF->QueryFilterInfo(&filter);
|
||||
printf("Filter [%p]: %ls\n", pBF.p, &(*filter.achName));
|
||||
|
||||
BeginEnumPins(pBF, pEP, pPin)
|
||||
{
|
||||
|
@ -490,8 +489,7 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float
|
|||
|
||||
CPinInfo pi;
|
||||
pPin->QueryPinInfo(&pi);
|
||||
std::wstring s{pi.achName};
|
||||
printf("- Pin [%p - %p]: %s (%s)\n", pPin.p, pPinTo.p, std::string{s.begin(), s.end()}.c_str(), pi.dir ? "out" : "in");
|
||||
printf("- Pin [%p - %p]: %ls (%s)\n", pPin.p, pPinTo.p, &(*filter.achName), pi.dir ? "out" : "in");
|
||||
}
|
||||
EndEnumPins
|
||||
}
|
||||
|
@ -501,6 +499,8 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float
|
|||
|
||||
CComQIPtr<IGSSource>(m_src)->DeliverNewSegment();
|
||||
|
||||
m_capturing = true;
|
||||
return new std::wstring(dlg.m_filename.begin(), dlg.m_filename.end() - 3);
|
||||
#elif defined(__unix__)
|
||||
// Note I think it doesn't support multiple depth creation
|
||||
GSmkdir(m_out_dir.c_str());
|
||||
|
@ -514,11 +514,10 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float
|
|||
for(int i = 0; i < m_threads; i++) {
|
||||
m_workers.push_back(std::unique_ptr<GSPng::Worker>(new GSPng::Worker(&GSPng::Process)));
|
||||
}
|
||||
#endif
|
||||
|
||||
m_capturing = true;
|
||||
|
||||
return true;
|
||||
return new std::wstring();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GSCapture::DeliverFrame(const void* bits, int pitch, bool rgba)
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
GSCapture();
|
||||
virtual ~GSCapture();
|
||||
|
||||
bool BeginCapture(float fps, GSVector2i recommendedResolution, float aspect);
|
||||
std::wstring* BeginCapture(float fps, GSVector2i recommendedResolution, float aspect);
|
||||
bool DeliverFrame(const void* bits, int pitch, bool rgba);
|
||||
bool EndCapture();
|
||||
|
||||
|
|
|
@ -529,7 +529,7 @@ bool GSRenderer::MakeSnapshot(const std::string& path)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSRenderer::BeginCapture()
|
||||
std::wstring* GSRenderer::BeginCapture()
|
||||
{
|
||||
GSVector4i disp = m_wnd->GetClientRect().fit(m_aspectratio);
|
||||
float aspect = (float)disp.width() / std::max(1, disp.height());
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
void SetAspectRatio(int aspect) {m_aspectratio = aspect;}
|
||||
void SetVSync(int vsync);
|
||||
|
||||
virtual bool BeginCapture();
|
||||
virtual std::wstring* BeginCapture();
|
||||
virtual void EndCapture();
|
||||
|
||||
void PurgePool();
|
||||
|
|
|
@ -627,12 +627,12 @@ SPU2write(u32 rmem, u16 value)
|
|||
// returns a non zero value if successful
|
||||
// for now, pData is not used
|
||||
EXPORT_C_(int)
|
||||
SPU2setupRecording(int start, void *pData)
|
||||
SPU2setupRecording(int start, std::wstring* filename)
|
||||
{
|
||||
if (start == 0)
|
||||
RecordStop();
|
||||
else if (start == 1)
|
||||
RecordStart();
|
||||
RecordStart(filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ SPU2irqCallback(void (*SPU2callback)(), void (*DMA4callback)(), void (*DMA7callb
|
|||
// returns a non zero value if successful
|
||||
// for now, pData is not used
|
||||
EXPORT_C_(int)
|
||||
SPU2setupRecording(int start, void *pData);
|
||||
SPU2setupRecording(int start, std::wstring* filename);
|
||||
|
||||
EXPORT_C_(void)
|
||||
SPU2setClockPtr(u32 *ptr);
|
||||
|
|
|
@ -688,7 +688,7 @@ extern SndOutModule *mods[];
|
|||
|
||||
extern bool WavRecordEnabled;
|
||||
|
||||
extern void RecordStart();
|
||||
extern void RecordStart(std::wstring* filename);
|
||||
extern void RecordStop();
|
||||
extern void RecordWrite(const StereoOut16 &sample);
|
||||
|
||||
|
|
|
@ -104,18 +104,25 @@ bool WavRecordEnabled = false;
|
|||
static WavOutFile *m_wavrecord = NULL;
|
||||
static Mutex WavRecordMutex;
|
||||
|
||||
void RecordStart()
|
||||
void RecordStart(std::wstring* filename)
|
||||
{
|
||||
WavRecordEnabled = false;
|
||||
|
||||
try {
|
||||
ScopedLock lock(WavRecordMutex);
|
||||
safe_delete(m_wavrecord);
|
||||
m_wavrecord = new WavOutFile("recording.wav", 48000, 16, 2);
|
||||
#ifdef _WIN32
|
||||
if (filename)
|
||||
m_wavrecord = new WavOutFile((*filename) + "wav", 48000, 16, 2);
|
||||
else
|
||||
m_wavrecord = new WavOutFile("audio_recording.wav", 48000, 16, 2);
|
||||
#elif defined(__unix__)
|
||||
m_wavrecord = new WavOutFile("audio_recording.wav", 48000, 16, 2);
|
||||
#endif
|
||||
WavRecordEnabled = true;
|
||||
} catch (std::runtime_error &) {
|
||||
m_wavrecord = NULL; // not needed, but what the heck. :)
|
||||
SysMessage("SPU2-X couldn't open file for recording: %s.\nRecording to wavfile disabled.", "recording.wav");
|
||||
SysMessage("SPU2-X couldn't open file for recording: %s.\nRecording to wavfile disabled.", "audio_recording.wav");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue