Audio: Added sound recorder
This commit is contained in:
parent
033469ff01
commit
92d915b585
11 changed files with 207 additions and 4 deletions
|
@ -125,6 +125,7 @@
|
||||||
<ClInclude Include="TraceLogger.h" />
|
<ClInclude Include="TraceLogger.h" />
|
||||||
<ClInclude Include="VideoDecoder.h" />
|
<ClInclude Include="VideoDecoder.h" />
|
||||||
<ClInclude Include="VideoRenderer.h" />
|
<ClInclude Include="VideoRenderer.h" />
|
||||||
|
<ClInclude Include="WaveRecorder.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="AviRecorder.cpp" />
|
<ClCompile Include="AviRecorder.cpp" />
|
||||||
|
@ -189,6 +190,7 @@
|
||||||
<ClCompile Include="TraceLogger.cpp" />
|
<ClCompile Include="TraceLogger.cpp" />
|
||||||
<ClCompile Include="VideoDecoder.cpp" />
|
<ClCompile Include="VideoDecoder.cpp" />
|
||||||
<ClCompile Include="VideoRenderer.cpp" />
|
<ClCompile Include="VideoRenderer.cpp" />
|
||||||
|
<ClCompile Include="WaveRecorder.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0}</ProjectGuid>
|
<ProjectGuid>{78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0}</ProjectGuid>
|
||||||
|
|
|
@ -245,6 +245,9 @@
|
||||||
<ClInclude Include="AviRecorder.h">
|
<ClInclude Include="AviRecorder.h">
|
||||||
<Filter>Misc</Filter>
|
<Filter>Misc</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="WaveRecorder.h">
|
||||||
|
<Filter>Misc</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="stdafx.cpp" />
|
<ClCompile Include="stdafx.cpp" />
|
||||||
|
@ -396,6 +399,9 @@
|
||||||
<ClCompile Include="AviRecorder.cpp">
|
<ClCompile Include="AviRecorder.cpp">
|
||||||
<Filter>Misc</Filter>
|
<Filter>Misc</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="WaveRecorder.cpp">
|
||||||
|
<Filter>Misc</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="SNES">
|
<Filter Include="SNES">
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "SoundResampler.h"
|
#include "SoundResampler.h"
|
||||||
#include "RewindManager.h"
|
#include "RewindManager.h"
|
||||||
#include "VideoRenderer.h"
|
#include "VideoRenderer.h"
|
||||||
|
#include "WaveRecorder.h"
|
||||||
#include "../Utilities/Equalizer.h"
|
#include "../Utilities/Equalizer.h"
|
||||||
#include "../Utilities/blip_buf.h"
|
#include "../Utilities/blip_buf.h"
|
||||||
|
|
||||||
|
@ -73,8 +74,11 @@ void SoundMixer::PlayAudioBuffer(int16_t* samples, uint32_t sampleCount)
|
||||||
out = _sampleBuffer;
|
out = _sampleBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRecording = _console->GetVideoRenderer()->IsRecording() /* TODO || _waveRecorder*/;
|
bool isRecording = _waveRecorder || _console->GetVideoRenderer()->IsRecording();
|
||||||
if(isRecording) {
|
if(isRecording) {
|
||||||
|
if(_waveRecorder) {
|
||||||
|
_waveRecorder->WriteSamples(out, count, cfg.SampleRate, true);
|
||||||
|
}
|
||||||
_console->GetVideoRenderer()->AddRecordingSound(out, count, cfg.SampleRate);
|
_console->GetVideoRenderer()->AddRecordingSound(out, count, cfg.SampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,3 +114,18 @@ double SoundMixer::GetRateAdjustment()
|
||||||
{
|
{
|
||||||
return _resampler->GetRateAdjustment();
|
return _resampler->GetRateAdjustment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundMixer::StartRecording(string filepath)
|
||||||
|
{
|
||||||
|
_waveRecorder.reset(new WaveRecorder(filepath, _console->GetSettings()->GetAudioConfig().SampleRate, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundMixer::StopRecording()
|
||||||
|
{
|
||||||
|
_waveRecorder.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoundMixer::IsRecording()
|
||||||
|
{
|
||||||
|
return _waveRecorder.get() != nullptr;
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
class Console;
|
class Console;
|
||||||
class Equalizer;
|
class Equalizer;
|
||||||
class SoundResampler;
|
class SoundResampler;
|
||||||
|
class WaveRecorder;
|
||||||
|
|
||||||
class SoundMixer
|
class SoundMixer
|
||||||
{
|
{
|
||||||
|
@ -13,6 +14,7 @@ private:
|
||||||
Console *_console;
|
Console *_console;
|
||||||
unique_ptr<Equalizer> _equalizer;
|
unique_ptr<Equalizer> _equalizer;
|
||||||
unique_ptr<SoundResampler> _resampler;
|
unique_ptr<SoundResampler> _resampler;
|
||||||
|
shared_ptr<WaveRecorder> _waveRecorder;
|
||||||
int16_t *_sampleBuffer = nullptr;
|
int16_t *_sampleBuffer = nullptr;
|
||||||
|
|
||||||
void ProcessEqualizer(int16_t *samples, uint32_t sampleCount);
|
void ProcessEqualizer(int16_t *samples, uint32_t sampleCount);
|
||||||
|
@ -27,4 +29,8 @@ public:
|
||||||
void RegisterAudioDevice(IAudioDevice *audioDevice);
|
void RegisterAudioDevice(IAudioDevice *audioDevice);
|
||||||
AudioStatistics GetStatistics();
|
AudioStatistics GetStatistics();
|
||||||
double GetRateAdjustment();
|
double GetRateAdjustment();
|
||||||
|
|
||||||
|
void StartRecording(string filepath);
|
||||||
|
void StopRecording();
|
||||||
|
bool IsRecording();
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,7 +27,7 @@ double SoundResampler::GetRateAdjustment()
|
||||||
double SoundResampler::GetTargetRateAdjustment()
|
double SoundResampler::GetTargetRateAdjustment()
|
||||||
{
|
{
|
||||||
AudioConfig cfg = _console->GetSettings()->GetAudioConfig();
|
AudioConfig cfg = _console->GetSettings()->GetAudioConfig();
|
||||||
bool isRecording = _console->GetVideoRenderer()->IsRecording() /* TODO || _waveRecorder */;
|
bool isRecording = _console->GetSoundMixer()->IsRecording() || _console->GetVideoRenderer()->IsRecording();
|
||||||
if(!isRecording && !cfg.DisableDynamicSampleRate) {
|
if(!isRecording && !cfg.DisableDynamicSampleRate) {
|
||||||
//Don't deviate from selected sample rate while recording
|
//Don't deviate from selected sample rate while recording
|
||||||
//TODO: Have 2 output streams (one for recording, one for the speakers)
|
//TODO: Have 2 output streams (one for recording, one for the speakers)
|
||||||
|
|
85
Core/WaveRecorder.cpp
Normal file
85
Core/WaveRecorder.cpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "WaveRecorder.h"
|
||||||
|
#include "MessageManager.h"
|
||||||
|
|
||||||
|
WaveRecorder::WaveRecorder(string outputFile, uint32_t sampleRate, bool isStereo)
|
||||||
|
{
|
||||||
|
_stream = ofstream(outputFile, ios::out | ios::binary);
|
||||||
|
_outputFile = outputFile;
|
||||||
|
_streamSize = 0;
|
||||||
|
_sampleRate = sampleRate;
|
||||||
|
_isStereo = isStereo;
|
||||||
|
WriteHeader();
|
||||||
|
|
||||||
|
MessageManager::DisplayMessage("SoundRecorder", "SoundRecorderStarted", _outputFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
WaveRecorder::~WaveRecorder()
|
||||||
|
{
|
||||||
|
CloseFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveRecorder::WriteHeader()
|
||||||
|
{
|
||||||
|
_stream << "RIFF";
|
||||||
|
uint32_t size = 0;
|
||||||
|
_stream.write((char*)&size, sizeof(size));
|
||||||
|
|
||||||
|
_stream << "WAVE";
|
||||||
|
_stream << "fmt ";
|
||||||
|
|
||||||
|
uint32_t chunkSize = 16;
|
||||||
|
_stream.write((char*)&chunkSize, sizeof(chunkSize));
|
||||||
|
|
||||||
|
uint16_t format = 1; //PCM
|
||||||
|
uint16_t channelCount = _isStereo ? 2 : 1;
|
||||||
|
uint16_t bytesPerSample = 2;
|
||||||
|
uint16_t blockAlign = channelCount * bytesPerSample;
|
||||||
|
uint32_t byteRate = _sampleRate * channelCount * bytesPerSample;
|
||||||
|
uint16_t bitsPerSample = bytesPerSample * 8;
|
||||||
|
|
||||||
|
_stream.write((char*)&format, sizeof(format));
|
||||||
|
_stream.write((char*)&channelCount, sizeof(channelCount));
|
||||||
|
_stream.write((char*)&_sampleRate, sizeof(_sampleRate));
|
||||||
|
_stream.write((char*)&byteRate, sizeof(byteRate));
|
||||||
|
|
||||||
|
_stream.write((char*)&blockAlign, sizeof(blockAlign));
|
||||||
|
_stream.write((char*)&bitsPerSample, sizeof(bitsPerSample));
|
||||||
|
|
||||||
|
_stream << "data";
|
||||||
|
_stream.write((char*)&size, sizeof(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaveRecorder::WriteSamples(int16_t * samples, uint32_t sampleCount, uint32_t sampleRate, bool isStereo)
|
||||||
|
{
|
||||||
|
if(_sampleRate != sampleRate || _isStereo != isStereo) {
|
||||||
|
//Format changed, stop recording
|
||||||
|
CloseFile();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
uint32_t sampleBytes = sampleCount * (isStereo ? 4 : 2);
|
||||||
|
_stream.write((char*)samples, sampleBytes);
|
||||||
|
_streamSize += sampleBytes;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveRecorder::UpdateSizeValues()
|
||||||
|
{
|
||||||
|
_stream.seekp(4, ios::beg);
|
||||||
|
uint32_t fileSize = _streamSize + 36;
|
||||||
|
_stream.write((char*)&fileSize, sizeof(fileSize));
|
||||||
|
|
||||||
|
_stream.seekp(40, ios::beg);
|
||||||
|
_stream.write((char*)&_streamSize, sizeof(_streamSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveRecorder::CloseFile()
|
||||||
|
{
|
||||||
|
if(_stream && _stream.is_open()) {
|
||||||
|
UpdateSizeValues();
|
||||||
|
_stream.close();
|
||||||
|
|
||||||
|
MessageManager::DisplayMessage("SoundRecorder", "SoundRecorderStopped", _outputFile);
|
||||||
|
}
|
||||||
|
}
|
21
Core/WaveRecorder.h
Normal file
21
Core/WaveRecorder.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
class WaveRecorder
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::ofstream _stream;
|
||||||
|
uint32_t _streamSize;
|
||||||
|
uint32_t _sampleRate;
|
||||||
|
bool _isStereo;
|
||||||
|
string _outputFile;
|
||||||
|
|
||||||
|
void WriteHeader();
|
||||||
|
void UpdateSizeValues();
|
||||||
|
void CloseFile();
|
||||||
|
|
||||||
|
public:
|
||||||
|
WaveRecorder(string outputFile, uint32_t sampleRate, bool isStereo);
|
||||||
|
~WaveRecorder();
|
||||||
|
|
||||||
|
bool WriteSamples(int16_t* samples, uint32_t sampleCount, uint32_t sampleRate, bool isStereo);
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "../Core/Console.h"
|
#include "../Core/Console.h"
|
||||||
#include "../Core/VideoRenderer.h"
|
#include "../Core/VideoRenderer.h"
|
||||||
|
#include "../Core/SoundMixer.h"
|
||||||
|
|
||||||
extern shared_ptr<Console> _console;
|
extern shared_ptr<Console> _console;
|
||||||
enum class VideoCodec;
|
enum class VideoCodec;
|
||||||
|
@ -10,4 +11,8 @@ extern "C"
|
||||||
DllExport void __stdcall AviRecord(char* filename, VideoCodec codec, uint32_t compressionLevel) { _console->GetVideoRenderer()->StartRecording(filename, codec, compressionLevel); }
|
DllExport void __stdcall AviRecord(char* filename, VideoCodec codec, uint32_t compressionLevel) { _console->GetVideoRenderer()->StartRecording(filename, codec, compressionLevel); }
|
||||||
DllExport void __stdcall AviStop() { _console->GetVideoRenderer()->StopRecording(); }
|
DllExport void __stdcall AviStop() { _console->GetVideoRenderer()->StopRecording(); }
|
||||||
DllExport bool __stdcall AviIsRecording() { return _console->GetVideoRenderer()->IsRecording(); }
|
DllExport bool __stdcall AviIsRecording() { return _console->GetVideoRenderer()->IsRecording(); }
|
||||||
|
|
||||||
|
DllExport void __stdcall WaveRecord(char* filename) { _console->GetSoundMixer()->StartRecording(filename); }
|
||||||
|
DllExport void __stdcall WaveStop() { _console->GetSoundMixer()->StopRecording(); }
|
||||||
|
DllExport bool __stdcall WaveIsRecording() { return _console->GetSoundMixer()->IsRecording(); }
|
||||||
}
|
}
|
34
UI/Forms/frmMain.Designer.cs
generated
34
UI/Forms/frmMain.Designer.cs
generated
|
@ -132,6 +132,9 @@
|
||||||
this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.pnlRenderer = new System.Windows.Forms.Panel();
|
this.pnlRenderer = new System.Windows.Forms.Panel();
|
||||||
this.ctrlRecentGames = new Mesen.GUI.Controls.ctrlRecentGames();
|
this.ctrlRecentGames = new Mesen.GUI.Controls.ctrlRecentGames();
|
||||||
|
this.mnuSoundRecorder = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.mnuWaveRecord = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.mnuWaveStop = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.mnuMain.SuspendLayout();
|
this.mnuMain.SuspendLayout();
|
||||||
this.pnlRenderer.SuspendLayout();
|
this.pnlRenderer.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
|
@ -751,6 +754,7 @@
|
||||||
// toolsToolStripMenuItem
|
// toolsToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
this.mnuSoundRecorder,
|
||||||
this.mnuVideoRecorder,
|
this.mnuVideoRecorder,
|
||||||
this.toolStripMenuItem11,
|
this.toolStripMenuItem11,
|
||||||
this.mnuLogWindow,
|
this.mnuLogWindow,
|
||||||
|
@ -930,6 +934,33 @@
|
||||||
this.ctrlRecentGames.TabIndex = 1;
|
this.ctrlRecentGames.TabIndex = 1;
|
||||||
this.ctrlRecentGames.Visible = false;
|
this.ctrlRecentGames.Visible = false;
|
||||||
//
|
//
|
||||||
|
// mnuSoundRecorder
|
||||||
|
//
|
||||||
|
this.mnuSoundRecorder.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
this.mnuWaveRecord,
|
||||||
|
this.mnuWaveStop});
|
||||||
|
this.mnuSoundRecorder.Image = global::Mesen.GUI.Properties.Resources.Microphone;
|
||||||
|
this.mnuSoundRecorder.Name = "mnuSoundRecorder";
|
||||||
|
this.mnuSoundRecorder.Size = new System.Drawing.Size(159, 22);
|
||||||
|
this.mnuSoundRecorder.Text = "Sound Recorder";
|
||||||
|
this.mnuSoundRecorder.DropDownOpening += new System.EventHandler(this.mnuSoundRecorder_DropDownOpening);
|
||||||
|
//
|
||||||
|
// mnuWaveRecord
|
||||||
|
//
|
||||||
|
this.mnuWaveRecord.Image = global::Mesen.GUI.Properties.Resources.Record;
|
||||||
|
this.mnuWaveRecord.Name = "mnuWaveRecord";
|
||||||
|
this.mnuWaveRecord.Size = new System.Drawing.Size(155, 22);
|
||||||
|
this.mnuWaveRecord.Text = "Record...";
|
||||||
|
this.mnuWaveRecord.Click += new System.EventHandler(this.mnuWaveRecord_Click);
|
||||||
|
//
|
||||||
|
// mnuWaveStop
|
||||||
|
//
|
||||||
|
this.mnuWaveStop.Image = global::Mesen.GUI.Properties.Resources.MediaStop;
|
||||||
|
this.mnuWaveStop.Name = "mnuWaveStop";
|
||||||
|
this.mnuWaveStop.Size = new System.Drawing.Size(155, 22);
|
||||||
|
this.mnuWaveStop.Text = "Stop Recording";
|
||||||
|
this.mnuWaveStop.Click += new System.EventHandler(this.mnuWaveStop_Click);
|
||||||
|
//
|
||||||
// frmMain
|
// frmMain
|
||||||
//
|
//
|
||||||
this.AllowDrop = true;
|
this.AllowDrop = true;
|
||||||
|
@ -1057,5 +1088,8 @@
|
||||||
private System.Windows.Forms.ToolStripMenuItem mnuAviRecord;
|
private System.Windows.Forms.ToolStripMenuItem mnuAviRecord;
|
||||||
private System.Windows.Forms.ToolStripMenuItem mnuAviStop;
|
private System.Windows.Forms.ToolStripMenuItem mnuAviStop;
|
||||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem11;
|
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem11;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem mnuSoundRecorder;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem mnuWaveRecord;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem mnuWaveStop;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -452,5 +452,30 @@ namespace Mesen.GUI.Forms
|
||||||
mnuAviRecord.Enabled = EmuRunner.IsRunning() && !RecordApi.AviIsRecording();
|
mnuAviRecord.Enabled = EmuRunner.IsRunning() && !RecordApi.AviIsRecording();
|
||||||
mnuAviStop.Enabled = EmuRunner.IsRunning() && RecordApi.AviIsRecording();
|
mnuAviStop.Enabled = EmuRunner.IsRunning() && RecordApi.AviIsRecording();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mnuWaveRecord_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
using(SaveFileDialog sfd = new SaveFileDialog()) {
|
||||||
|
sfd.SetFilter(ResourceHelper.GetMessage("FilterWave"));
|
||||||
|
sfd.InitialDirectory = ConfigManager.WaveFolder;
|
||||||
|
//TODO
|
||||||
|
//sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".wav";
|
||||||
|
if(sfd.ShowDialog(this) == DialogResult.OK) {
|
||||||
|
RecordApi.WaveRecord(sfd.FileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mnuWaveStop_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
RecordApi.WaveStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mnuSoundRecorder_DropDownOpening(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
mnuSoundRecorder.Enabled = EmuRunner.IsRunning();
|
||||||
|
mnuWaveRecord.Enabled = EmuRunner.IsRunning() && !RecordApi.WaveIsRecording();
|
||||||
|
mnuWaveStop.Enabled = EmuRunner.IsRunning() && RecordApi.WaveIsRecording();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,11 @@ namespace Mesen.GUI
|
||||||
[DllImport(DllPath)] public static extern void AviStop();
|
[DllImport(DllPath)] public static extern void AviStop();
|
||||||
[DllImport(DllPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool AviIsRecording();
|
[DllImport(DllPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool AviIsRecording();
|
||||||
|
|
||||||
/*[DllImport(DllPath)] public static extern void WaveRecord([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename);
|
[DllImport(DllPath)] public static extern void WaveRecord([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string filename);
|
||||||
[DllImport(DllPath)] public static extern void WaveStop();
|
[DllImport(DllPath)] public static extern void WaveStop();
|
||||||
[DllImport(DllPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool WaveIsRecording();
|
[DllImport(DllPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool WaveIsRecording();
|
||||||
|
|
||||||
[DllImport(DllPath)] public static extern void MoviePlay([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename);
|
/*[DllImport(DllPath)] public static extern void MoviePlay([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string filename);
|
||||||
[DllImport(DllPath)] public static extern void MovieRecord(ref RecordMovieOptions options);
|
[DllImport(DllPath)] public static extern void MovieRecord(ref RecordMovieOptions options);
|
||||||
[DllImport(DllPath)] public static extern void MovieStop();
|
[DllImport(DllPath)] public static extern void MovieStop();
|
||||||
[DllImport(DllPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool MoviePlaying();
|
[DllImport(DllPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool MoviePlaying();
|
||||||
|
|
Loading…
Add table
Reference in a new issue