diff --git a/src/audio/abstract.cpp b/src/audio/abstract.cpp index 8026adf8c..d445dbe40 100644 --- a/src/audio/abstract.cpp +++ b/src/audio/abstract.cpp @@ -27,7 +27,8 @@ bool TAAudio::setRun(bool run) { } bool TAAudio::init(TAAudioDesc& request, TAAudioDesc& response) { - return false; + response=request; + return true; } TAAudio::~TAAudio() { diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 9d651b255..d2035e817 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1932,7 +1932,7 @@ void DivEngine::runExportThread() { sf=sf_open(exportPath.c_str(),SFM_WRITE,&si); if (sf==NULL) { - logE("could not open file for writing!\n"); + logE("could not open file for writing! (%s)\n",sf_strerror(NULL)); exporting=false; return; } @@ -1946,6 +1946,8 @@ void DivEngine::runExportThread() { deinitAudioBackend(); playSub(false); + logI("rendering to file...\n"); + while (playing) { nextBuf(NULL,outBuf,0,2,EXPORT_BUFSIZE); for (int i=0; isetCallback(process,this); - logI("initializing audio.\n"); if (!output->init(want,got)) { logE("error while initializing audio!\n"); delete output; diff --git a/src/engine/engine.h b/src/engine/engine.h index 2b0266ad3..e733a7b26 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -22,7 +22,9 @@ enum DivStatusView { enum DivAudioEngines { DIV_AUDIO_JACK=0, - DIV_AUDIO_SDL=1 + DIV_AUDIO_SDL=1, + DIV_AUDIO_NULL=2, + DIV_AUDIO_DUMMY=3 }; enum DivAudioExportModes { @@ -518,7 +520,7 @@ class DivEngine { speed1(3), speed2(3), view(DIV_STATUS_NOTHING), - audioEngine(DIV_AUDIO_SDL), + audioEngine(DIV_AUDIO_NULL), samp_bbInLen(0), samp_temp(0), samp_prevSample(0), diff --git a/src/main.cpp b/src/main.cpp index fb9193e58..5df66c4b6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,6 +25,8 @@ FurnaceGUI g; #endif String outName; +int loops=1; +DivAudioExportModes outMode=DIV_EXPORT_MODE_ONE; #ifdef HAVE_GUI bool consoleMode=false; @@ -48,6 +50,10 @@ bool pHelp(String) { } bool pAudio(String val) { + if (outName!="") { + logE("can't use -audio and -output at the same time.\n"); + return false; + } if (val=="jack") { e.setAudio(DIV_AUDIO_JACK); } else if (val=="sdl") { @@ -143,9 +149,9 @@ bool pLoops(String val) { try { int count=std::stoi(val); if (count<0) { - e.setLoops(-1); + loops=0; } else { - e.setLoops(count+1); + loops=count+1; } } catch (std::exception& e) { logE("loop count shall be a number.\n"); @@ -154,8 +160,23 @@ bool pLoops(String val) { return true; } +bool pOutMode(String val) { + if (val=="one") { + outMode=DIV_EXPORT_MODE_ONE; + } else if (val=="persys") { + outMode=DIV_EXPORT_MODE_MANY_SYS; + } else if (val=="perchan") { + outMode=DIV_EXPORT_MODE_MANY_CHAN; + } else { + logE("invalid value for outmode! valid values are: one, persys and perchan.\n"); + return false; + } + return true; +} + bool pOutput(String val) { outName=val; + e.setAudio(DIV_AUDIO_DUMMY); return true; } @@ -178,6 +199,7 @@ void initParams() { params.push_back(TAParam("c","console",false,pConsole,"","enable console mode")); params.push_back(TAParam("l","loops",true,pLoops,"","set number of loops (-1 means loop forever)")); + params.push_back(TAParam("o","outmode",true,pOutMode,"one|persys|perchan","set file output mode")); params.push_back(TAParam("V","version",false,pVersion,"","view information about Furnace.")); params.push_back(TAParam("W","warranty",false,pWarranty,"","view warranty disclaimer.")); @@ -298,7 +320,12 @@ int main(int argc, char** argv) { logE("could not initialize engine!\n"); return 1; } - if (outName!="") return 0; + if (outName!="") { + e.setConsoleMode(true); + e.saveAudio(outName.c_str(),loops,outMode); + e.waitAudioFile(); + return 0; + } if (consoleMode) { logI("playing...\n");