diff --git a/.gitmodules b/.gitmodules index 266bac80..22cf04d2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,3 +9,7 @@ path = extern/Nuked-OPM url = https://github.com/nukeykt/Nuked-OPM branch = main +[submodule "extern/libsndfile"] + path = extern/libsndfile + url = https://github.com/libsndfile/libsndfile.git + branch = master diff --git a/CMakeLists.txt b/CMakeLists.txt index 06e9f078..c556587d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,9 @@ project(furnace) set(CMAKE_CXX_STANDARD 11) +set(BUILD_TESTING OFF) +add_subdirectory(extern/libsndfile) + if (WIN32) set(SDL_SHARED OFF) add_subdirectory(extern/SDL) @@ -16,6 +19,7 @@ else() find_library(HAVE_JACK jack) endif() find_library(HAVE_Z z) + find_library(HAVE_SNDFILE sndfile) endif() set(AUDIO_SOURCES src/audio/abstract.cpp) @@ -82,7 +86,7 @@ src/engine/platform/dummy.cpp) add_executable(furnace ${ENGINE_SOURCES} ${AUDIO_SOURCES} src/main.cpp) -target_link_libraries(furnace ${HAVE_SDL2} ${HAVE_Z}) +target_link_libraries(furnace ${HAVE_SDL2} ${HAVE_Z} sndfile) if (HAVE_JACK) target_link_libraries(furnace ${HAVE_JACK}) diff --git a/extern/libsndfile b/extern/libsndfile new file mode 160000 index 00000000..ca200890 --- /dev/null +++ b/extern/libsndfile @@ -0,0 +1 @@ +Subproject commit ca2008903f66f856de4cd86e83a387b56260d5b7 diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 67426845..6a903a6c 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -15,6 +15,7 @@ #include "platform/dummy.h" #include #include +#include void process(void* u, float** in, float** out, int inChans, int outChans, unsigned int size) { ((DivEngine*)u)->nextBuf(in,out,inChans,outChans,size); @@ -695,10 +696,22 @@ void DivEngine::setView(DivStatusView which) { } bool DivEngine::init(String outName) { + SNDFILE* outFile; + SF_INFO outInfo; if (outName!="") { // init out file got.bufsize=2048; got.rate=44100; + + outInfo.samplerate=got.rate; + outInfo.channels=1; + outInfo.format=SF_FORMAT_WAV|SF_FORMAT_PCM_16; + + outFile=sf_open(outName.c_str(),SFM_WRITE,&outInfo); + if (outFile==NULL) { + logE("could not open file for writing!\n"); + return false; + } } else { switch (audioEngine) { case DIV_AUDIO_JACK: @@ -800,6 +813,13 @@ bool DivEngine::init(String outName) { if (outName!="") { // render to file + remainingLoops=1; + while (remainingLoops) { + nextBuf(NULL,NULL,0,2,got.bufsize); + sf_writef_short(outFile,bbOut[0],got.bufsize); + } + sf_close(outFile); + return true; } else { if (!output->setRun(true)) { logE("error while activating!\n"); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 30445a08..97b763d8 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1,6 +1,7 @@ #include "dispatch.h" #include "engine.h" #include "../ta-log.h" +#include void DivEngine::nextOrder() { curRow=0; @@ -716,6 +717,8 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi blip_read_samples(bb[1],bbOut[1],size,0); } + if (out==NULL) return; + if (dispatch->isStereo()) { for (size_t i=0; i params; bool pHelp(String) { @@ -116,7 +118,8 @@ bool pLoops(String val) { } bool pOutput(String val) { - return false; + outName=val; + return true; } bool needsValue(String param) { @@ -143,6 +146,7 @@ void initParams() { } int main(int argc, char** argv) { + outName=""; #ifdef _WIN32 HANDLE winin=GetStdHandle(STD_INPUT_HANDLE); HANDLE winout=GetStdHandle(STD_OUTPUT_HANDLE); @@ -244,11 +248,11 @@ int main(int argc, char** argv) { logE("could not open file!\n"); return 1; } - if (!e.init()) { + if (!e.init(outName)) { logE("could not initialize engine!\n"); return 1; } - logI("loaded! :o\n"); + if (outName!="") return 0; logI("playing...\n"); e.play(); while (true) {