formats combo, more format for wav export

This commit is contained in:
Eknous-P 2025-10-24 11:19:38 +04:00
parent 27cf8be1c4
commit ad4572be43
3 changed files with 89 additions and 42 deletions

View file

@ -102,8 +102,7 @@ enum DivMIDIModes {
};
enum DivAudioExportFormats {
DIV_EXPORT_FORMAT_S16=0,
DIV_EXPORT_FORMAT_F32,
DIV_EXPORT_FORMAT_WAV=0,
DIV_EXPORT_FORMAT_OPUS,
DIV_EXPORT_FORMAT_FLAC,
DIV_EXPORT_FORMAT_VORBIS,
@ -116,10 +115,18 @@ enum DivAudioExportBitrateModes {
DIV_EXPORT_BITRATE_AVERAGE,
};
enum DivAudioExportWavFormats {
DIV_EXPORT_WAV_U8=0,
DIV_EXPORT_WAV_S16,
DIV_EXPORT_WAV_S32,
DIV_EXPORT_WAV_F32
};
struct DivAudioExportOptions {
DivAudioExportModes mode;
DivAudioExportFormats format;
DivAudioExportBitrateModes bitRateMode;
DivAudioExportWavFormats wavFormat;
int sampleRate;
int chans;
int loops;
@ -130,7 +137,7 @@ struct DivAudioExportOptions {
float vbrQuality;
DivAudioExportOptions():
mode(DIV_EXPORT_MODE_ONE),
format(DIV_EXPORT_FORMAT_S16),
format(DIV_EXPORT_FORMAT_WAV),
bitRateMode(DIV_EXPORT_BITRATE_CONSTANT),
sampleRate(44100),
chans(2),
@ -514,6 +521,7 @@ class DivEngine {
DivAudioEngines audioEngine;
DivAudioExportModes exportMode;
DivAudioExportFormats exportFormat;
DivAudioExportWavFormats wavFormat;
DivAudioExportBitrateModes exportBitRateMode;
double exportFadeOut;
bool isFadingOut;
@ -1506,7 +1514,8 @@ class DivEngine {
haltOn(DIV_HALT_NONE),
audioEngine(DIV_AUDIO_NULL),
exportMode(DIV_EXPORT_MODE_ONE),
exportFormat(DIV_EXPORT_FORMAT_S16),
exportFormat(DIV_EXPORT_FORMAT_WAV),
wavFormat(DIV_EXPORT_WAV_S16),
exportBitRateMode(DIV_EXPORT_BITRATE_CONSTANT),
exportFadeOut(0.0),
isFadingOut(false),

View file

@ -113,7 +113,7 @@ bool DivEngine::getIsFadingOut() {
#ifdef HAVE_SNDFILE
#define MAP_BITRATE \
if (exportFormat!=DIV_EXPORT_FORMAT_S16 && exportFormat!=DIV_EXPORT_FORMAT_F32) { \
if (exportFormat!=DIV_EXPORT_FORMAT_WAV) { \
double mappedLevel=0.0; \
\
switch (exportFormat) { \
@ -179,11 +179,26 @@ void DivEngine::runExportThread() {
si.samplerate=got.rate;
si.channels=exportOutputs;
switch (exportFormat) {
case DIV_EXPORT_FORMAT_S16:
si.format=SF_FORMAT_WAV|SF_FORMAT_PCM_16;
break;
case DIV_EXPORT_FORMAT_F32:
si.format=SF_FORMAT_WAV|SF_FORMAT_FLOAT;
case DIV_EXPORT_FORMAT_WAV:
si.format=SF_FORMAT_WAV;
switch (wavFormat) {
case DIV_EXPORT_WAV_U8:
si.format|=SF_FORMAT_PCM_U8;
break;
case DIV_EXPORT_WAV_S16:
si.format|=SF_FORMAT_PCM_16;
break;
case DIV_EXPORT_WAV_S32:
si.format|=SF_FORMAT_PCM_32;
break;
case DIV_EXPORT_WAV_F32:
si.format|=SF_FORMAT_FLOAT;
break;
default:
si.format|=SF_FORMAT_PCM_U8;
logW("wtf");
break;
}
break;
case DIV_EXPORT_FORMAT_OPUS:
si.format=SF_FORMAT_OGG|SF_FORMAT_OPUS;
@ -426,11 +441,26 @@ void DivEngine::runExportThread() {
si.samplerate=got.rate;
si.channels=exportOutputs;
switch (exportFormat) {
case DIV_EXPORT_FORMAT_S16:
si.format=SF_FORMAT_WAV|SF_FORMAT_PCM_16;
break;
case DIV_EXPORT_FORMAT_F32:
si.format=SF_FORMAT_WAV|SF_FORMAT_FLOAT;
case DIV_EXPORT_FORMAT_WAV:
si.format=SF_FORMAT_WAV;
switch (wavFormat) {
case DIV_EXPORT_WAV_U8:
si.format|=SF_FORMAT_PCM_U8;
break;
case DIV_EXPORT_WAV_S16:
si.format|=SF_FORMAT_PCM_16;
break;
case DIV_EXPORT_WAV_S32:
si.format|=SF_FORMAT_PCM_32;
break;
case DIV_EXPORT_WAV_F32:
si.format|=SF_FORMAT_FLOAT;
break;
default:
si.format|=SF_FORMAT_PCM_U8;
logW("wtf");
break;
}
break;
case DIV_EXPORT_FORMAT_OPUS:
si.format=SF_FORMAT_OGG|SF_FORMAT_OPUS;
@ -584,6 +614,7 @@ bool DivEngine::saveAudio(const char* path, DivAudioExportOptions options) {
exportPath=path;
exportMode=options.mode;
exportFormat=options.format;
wavFormat=options.wavFormat;
exportBitRate=options.bitRate;
exportBitRateMode=options.bitRateMode;
exportVBRQuality=options.vbrQuality;

View file

@ -23,6 +23,21 @@
#include "misc/cpp/imgui_stdlib.h"
#include <imgui.h>
const char* audioExportFormats[]={
_("Wave"),
_("Opus"),
_("FLAC (Free Lossless Audio Codec)"),
_("Vorbis"),
_("MP3")
};
const char* audioExportWavFormats[]={
_("Unsigned 8-bit"),
_("Signed 16-bit"),
_("Signed 32-bit"),
_("FLoat 32-bit"),
};
void FurnaceGUI::drawExportAudio(bool onWindow) {
exitDisabledTimer=1;
@ -34,7 +49,8 @@ void FurnaceGUI::drawExportAudio(bool onWindow) {
}
if (ImGui::RadioButton(_("multiple files (one per chip)"),audioExportOptions.mode==DIV_EXPORT_MODE_MANY_SYS)) {
audioExportOptions.mode=DIV_EXPORT_MODE_MANY_SYS;
audioExportOptions.format=DIV_EXPORT_FORMAT_S16;
audioExportOptions.format=DIV_EXPORT_FORMAT_WAV;
audioExportOptions.wavFormat=DIV_EXPORT_WAV_S16;
}
if (ImGui::RadioButton(_("multiple files (one per channel)"),audioExportOptions.mode==DIV_EXPORT_MODE_MANY_CHAN)) {
audioExportOptions.mode=DIV_EXPORT_MODE_MANY_CHAN;
@ -42,31 +58,14 @@ void FurnaceGUI::drawExportAudio(bool onWindow) {
ImGui::Unindent();
if (audioExportOptions.mode!=DIV_EXPORT_MODE_MANY_SYS) {
ImGui::Text(_("File format:"));
ImGui::Indent();
if (ImGui::RadioButton(_("Wave (16-bit integer)"),audioExportOptions.format==DIV_EXPORT_FORMAT_S16)) {
audioExportOptions.format=DIV_EXPORT_FORMAT_S16;
}
if (ImGui::RadioButton(_("Wave (32-bit float)"),audioExportOptions.format==DIV_EXPORT_FORMAT_F32)) {
audioExportOptions.format=DIV_EXPORT_FORMAT_F32;
}
if (supportsOgg) {
if (ImGui::RadioButton(_("Opus"),audioExportOptions.format==DIV_EXPORT_FORMAT_OPUS)) {
audioExportOptions.format=DIV_EXPORT_FORMAT_OPUS;
}
if (ImGui::RadioButton(_("FLAC (Free Lossless Audio Codec)"),audioExportOptions.format==DIV_EXPORT_FORMAT_FLAC)) {
audioExportOptions.format=DIV_EXPORT_FORMAT_FLAC;
}
if (ImGui::RadioButton(_("Vorbis"),audioExportOptions.format==DIV_EXPORT_FORMAT_VORBIS)) {
audioExportOptions.format=DIV_EXPORT_FORMAT_VORBIS;
if (ImGui::BeginCombo(_("File Format"), audioExportFormats[audioExportOptions.format])) {
for (size_t i=0; i<(supportsMP3?5:4); i++) {
if (ImGui::Selectable(audioExportFormats[i],audioExportOptions.format==i)) {
audioExportOptions.format=(DivAudioExportFormats)i;
}
}
if (supportsMP3) {
if (ImGui::RadioButton(_("MP3"),audioExportOptions.format==DIV_EXPORT_FORMAT_MPEG_L3)) {
audioExportOptions.format=DIV_EXPORT_FORMAT_MPEG_L3;
}
}
ImGui::Unindent();
ImGui::EndCombo();
}
}
bool rateCheck=(
@ -126,7 +125,7 @@ void FurnaceGUI::drawExportAudio(bool onWindow) {
}
}
if (audioExportOptions.format!=DIV_EXPORT_FORMAT_S16 && audioExportOptions.format!=DIV_EXPORT_FORMAT_F32) {
if (audioExportOptions.format!=DIV_EXPORT_FORMAT_WAV) {
if (audioExportOptions.format==DIV_EXPORT_FORMAT_FLAC) {
if (ImGui::SliderFloat(_("Compression level"),&audioExportOptions.vbrQuality,0,8)) {
if (audioExportOptions.vbrQuality<0) audioExportOptions.vbrQuality=0;
@ -143,6 +142,15 @@ void FurnaceGUI::drawExportAudio(bool onWindow) {
if (audioExportOptions.bitRate<minBitRate) audioExportOptions.bitRate=minBitRate;
if (audioExportOptions.bitRate>maxBitRate) audioExportOptions.bitRate=maxBitRate;
}
} else {
if (ImGui::BeginCombo(_("Format"), audioExportWavFormats[audioExportOptions.wavFormat])) {
for (size_t i=0; i<4; i++) {
if (ImGui::Selectable(audioExportWavFormats[i], audioExportOptions.wavFormat==i)) {
audioExportOptions.wavFormat=(DivAudioExportWavFormats)i;
}
}
ImGui::EndCombo();
}
}
if (ImGui::InputInt(_("Loops"),&audioExportOptions.loops,1,2)) {
@ -207,8 +215,7 @@ void FurnaceGUI::drawExportAudio(bool onWindow) {
if (isOneOn && !rateCheck) {
if (ImGui::Button(_("Export"),ImVec2(200.0f*dpiScale,0))) {
switch (audioExportOptions.format) {
case DIV_EXPORT_FORMAT_S16:
case DIV_EXPORT_FORMAT_F32:
case DIV_EXPORT_FORMAT_WAV:
audioExportFilterName=_("Wave file");
audioExportFilterExt=".wav";
break;