Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ffmpeg export #2309

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,11 @@ endif()

set(ENGINE_SOURCES
src/log.cpp
src/subprocess.cpp
src/baseutils.cpp
src/fileutils.cpp
src/utfutils.cpp
src/stringutils.cpp

extern/itcompress/compression.c

Expand Down
11 changes: 9 additions & 2 deletions scripts/Cross-MinGW.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
set(TARGET_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32)

set(CMAKE_C_COMPILER ${TARGET_PREFIX}-gcc-posix)
set(CMAKE_CXX_COMPILER ${TARGET_PREFIX}-g++-posix)
find_program(found_posix ${TARGET_PREFIX}-gcc-posix)
if (found_posix)
set(CMAKE_C_COMPILER ${TARGET_PREFIX}-gcc-posix)
set(CMAKE_CXX_COMPILER ${TARGET_PREFIX}-g++-posix)
else()
set(CMAKE_C_COMPILER ${TARGET_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TARGET_PREFIX}-g++)
endif()

set(PKG_CONFIG_EXECUTABLE ${TARGET_PREFIX}-pkg-config)

set(CMAKE_FIND_ROOT_PATH /usr/${TARGET_PREFIX})
Expand Down
44 changes: 40 additions & 4 deletions src/engine/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,26 @@ enum DivAudioExportFormats {
DIV_EXPORT_FORMAT_F32
};

enum DivAudioExportWriters {
DIV_EXPORT_WRITER_SNDFILE=0,
DIV_EXPORT_WRITER_COMMAND
};

struct DivAudioCommandExportDef {
String name, fileExt, commandTemplate;
DivAudioCommandExportDef(String n, String fe, String ct):
name(n),
fileExt(fe),
commandTemplate(ct) {}
};

struct DivAudioExportOptions {
DivAudioExportModes mode;
DivAudioExportFormats format;
String extraFlags;
DivAudioExportWriters curWriter;
std::vector<DivAudioCommandExportDef> commandExportWriterDefs;
int curCommandWriterIndex;
int sampleRate;
int chans;
int loops;
Expand All @@ -118,6 +135,9 @@ struct DivAudioExportOptions {
DivAudioExportOptions():
mode(DIV_EXPORT_MODE_ONE),
format(DIV_EXPORT_FORMAT_S16),
extraFlags(""),
curWriter(DIV_EXPORT_WRITER_SNDFILE),
curCommandWriterIndex(0),
sampleRate(44100),
chans(2),
loops(0),
Expand All @@ -127,6 +147,16 @@ struct DivAudioExportOptions {
for (int i=0; i<DIV_MAX_CHANS; i++) {
channelMask[i]=true;
}

const char *ffmpegTemplate="%ffmpeg% -y -v verbose -f %input_format% -ar %sample_rate% -ac %channel_count% -i pipe:0 %output_file%"; // TODO: %extra_flags% (or maybe don't use that)

commandExportWriterDefs={
DivAudioCommandExportDef("FLAC file (.flac) (ffmpeg)","flac",ffmpegTemplate),
DivAudioCommandExportDef("OGG file (.ogg) (ffmpeg)","ogg",ffmpegTemplate),
DivAudioCommandExportDef("MP3 file (.mp3) (ffmpeg)","mp3",ffmpegTemplate),
DivAudioCommandExportDef("M4A file (.m4a) (ffmpeg)","m4a",ffmpegTemplate),
DivAudioCommandExportDef("OPUS file (.opus) (ffmpeg)","opus",ffmpegTemplate)
};
}
};

Expand Down Expand Up @@ -499,6 +529,10 @@ class DivEngine {
DivAudioEngines audioEngine;
DivAudioExportModes exportMode;
DivAudioExportFormats exportFormat;
DivAudioExportWriters exportWriter;
String exportCommand;
String exportFileExtNoDot;
String exportExtraFlags;
double exportFadeOut;
bool isFadingOut;
int exportOutputs;
Expand Down Expand Up @@ -623,8 +657,8 @@ class DivEngine {
void loadFF(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
void loadWOPL(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
void loadWOPN(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
//sample banks

// sample banks
void loadP(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
void loadPPC(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
void loadPPS(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
Expand All @@ -633,8 +667,6 @@ class DivEngine {
void loadPZI(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);
void loadP86(SafeReader& reader, std::vector<DivSample*>& ret, String& stripPath);



int loadSampleROM(String path, ssize_t expectedSize, unsigned char*& ret);

bool initAudioBackend();
Expand Down Expand Up @@ -1472,6 +1504,10 @@ class DivEngine {
audioEngine(DIV_AUDIO_NULL),
exportMode(DIV_EXPORT_MODE_ONE),
exportFormat(DIV_EXPORT_FORMAT_S16),
exportWriter(DIV_EXPORT_WRITER_SNDFILE),
exportCommand(""),
exportFileExtNoDot("wav"),
exportExtraFlags(""),
exportFadeOut(0.0),
isFadingOut(false),
exportOutputs(2),
Expand Down
79 changes: 57 additions & 22 deletions src/engine/sfWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
#include "../ta-log.h"
#include "sndfile.h"

#ifndef _WIN32
#include <fcntl.h>
#include <unistd.h>
#endif

sf_count_t _vioGetSize(void* user) {
return ((SFWrapper*)user)->ioGetSize();
}
Expand All @@ -45,42 +50,47 @@ sf_count_t _vioTell(void* user) {
sf_count_t SFWrapper::ioGetSize() {
sf_count_t ret=(sf_count_t)len;
if (fileMode==SFM_WRITE || fileMode==SFM_RDWR) {
ssize_t lastTell=ftell(f);
fseek(f,0,SEEK_END);
ret=(sf_count_t)ftell(f);
fseek(f,lastTell,SEEK_SET);
ssize_t lastTell=ftell(fp);
fseek(fp,0,SEEK_END);
ret=(sf_count_t)ftell(fp);
fseek(fp,lastTell,SEEK_SET);
}
return ret;
}

sf_count_t SFWrapper::ioSeek(sf_count_t offset, int whence) {
return fseek(f,offset,whence);
return fseek(fp,offset,whence);
}

sf_count_t SFWrapper::ioRead(void* ptr, sf_count_t count) {
return fread(ptr,1,count,f);
return fread(ptr,1,count,fp);
}

sf_count_t SFWrapper::ioWrite(const void* ptr, sf_count_t count) {
return fwrite(ptr,1,count,f);
return fwrite(ptr,1,count,fp);
}

sf_count_t SFWrapper::ioTell() {
return ftell(f);
return ftell(fp);
}

int SFWrapper::doClose() {
int ret=sf_close(sf);
fclose(f);
fclose(fp);
fd=-1;
return ret;
}

SNDFILE* SFWrapper::doOpen(const char* path, int mode, SF_INFO* sfinfo) {
void SFWrapper::initVio() {
vio.get_filelen=_vioGetSize;
vio.read=_vioRead;
vio.seek=_vioSeek;
vio.tell=_vioTell;
vio.write=_vioWrite;
}

SNDFILE* SFWrapper::doOpen(const char* path, int mode, SF_INFO* sfinfo) {
initVio();
logV("SFWrapper: opening %s",path);

const char* modeC="rb";
Expand All @@ -91,33 +101,39 @@ SNDFILE* SFWrapper::doOpen(const char* path, int mode, SF_INFO* sfinfo) {
modeC="rb+";
}

f=ps_fopen(path,modeC);
if (f==NULL) {
fp=ps_fopen(path,modeC);
if (fp==NULL) {
logE("SFWrapper: failed to open (%s)",strerror(errno));
return NULL;
}

if (fseek(f,0,SEEK_END)==-1) {
fd=fileno(fp);
if (fd==-1) {
logE("SFWrapper: failed to get file descriptor (%s)",strerror(errno));
return NULL;
}

if (fseek(fp,0,SEEK_END)==-1) {
logE("SFWrapper: failed to seek to end (%s)",strerror(errno));
fclose(f);
f=NULL;
fclose(fp);
fp=NULL;
return NULL;
}
len=ftell(f);

len=ftell(fp);
if (len==(SIZE_MAX>>1)) {
logE("SFWrapper: failed to tell (%s)",strerror(errno));
len=0;
fclose(f);
f=NULL;
fclose(fp);
fp=NULL;
return NULL;
}

if (fseek(f,0,SEEK_SET)==-1) {
if (fseek(fp,0,SEEK_SET)==-1) {
logE("SFWrapper: failed to seek to beginning (%s)",strerror(errno));
len=0;
fclose(f);
f=NULL;
fclose(fp);
fp=NULL;
return NULL;
}

Expand All @@ -128,3 +144,22 @@ SNDFILE* SFWrapper::doOpen(const char* path, int mode, SF_INFO* sfinfo) {
}
return sf;
}

SNDFILE* SFWrapper::doOpenFromWriteFd(int writeFd, SF_INFO* sfinfo) {
fp=fdopen(writeFd,"w");
if (fp==NULL) {
logE("SFWrapper: failed to open file descriptor %d (pipe) as file: %s",writeFd,strerror(errno));
return NULL;
}
fd=writeFd;

initVio();
len=0; // I am hoping this is not used when writing
fileMode=SFM_WRITE;

sf=sf_open_virtual(&vio,SFM_WRITE,sfinfo,this);
if (sf==NULL) {
logE("SFWrapper: WHY IS IT NULL?!");
}
return sf;
}
11 changes: 9 additions & 2 deletions src/engine/sfWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@

#ifndef _SFWRAPPER_H
#define _SFWRAPPER_H

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sndfile.h>
#include "../ta-utils.h"

class SFWrapper {
FILE* f;
// manage both a file pointer and a file descriptor for flexibility
FILE* fp;
int fd;

size_t len;
SF_VIRTUAL_IO vio;
SNDFILE* sf;
Expand All @@ -44,10 +48,13 @@ class SFWrapper {
sf_count_t ioWrite(const void* ptr, sf_count_t count);
sf_count_t ioTell();

void initVio();
int doClose();
SNDFILE* doOpen(const char* path, int mode, SF_INFO* sfinfo);
SNDFILE* doOpenFromWriteFd(int fd, SF_INFO* sfinfo);
SFWrapper():
f(NULL),
fp(NULL),
fd(-1),
len(0),
sf(NULL),
fileMode(0) {}
Expand Down
Loading