From d2432c92f54af4dfa6c8a54d504d6645076c6b80 Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Fri, 17 Oct 2025 23:23:17 +0200 Subject: [PATCH 01/17] Inital port of libav Could enable printfx on more platforms Builds, runs and produces output equivalent to ffmpeg Pad not implemented Need to test in cross-compile job Needs cleanup --- projects/Makefile | 4 +- projects/Makefile.X64 | 5 +- projects/rules_libav | 7 + sources/Application/FX/FxPrinter.cpp | 27 +- sources/Application/FX/FxPrinter.h | 13 +- sources/Application/FX/LibavProcessor.c | 704 ++++++++++++++++++++++++ sources/Application/FX/LibavProcessor.h | 14 + 7 files changed, 749 insertions(+), 25 deletions(-) create mode 100644 projects/rules_libav create mode 100644 sources/Application/FX/LibavProcessor.c create mode 100644 sources/Application/FX/LibavProcessor.h diff --git a/projects/Makefile b/projects/Makefile index f735c9d7..5267e08f 100644 --- a/projects/Makefile +++ b/projects/Makefile @@ -259,7 +259,9 @@ COMMONFILES := \ char.o n_assert.o fixed.o wildcard.o \ SyncMaster.o TablePlayback.o Player.o \ Table.o TableView.o\ - InstrumentBank.o WavFileWriter.o WavFile.o MidiInstrument.o Filters.o SampleVariable.o SampleInstrument.o SamplePool.o CommandList.o FxPrinter.o\ + InstrumentBank.o WavFileWriter.o WavFile.o MidiInstrument.o Filters.o \ + SampleVariable.o SampleInstrument.o SamplePool.o CommandList.o \ + LibavProcessor.o FxPrinter.o\ PersistencyService.o Persistent.o \ Observable.o SingletonRegistry.o \ Audio.o AudioMixer.o AudioOutDriver.o AudioDriver.o \ diff --git a/projects/Makefile.X64 b/projects/Makefile.X64 index 6460f413..d9fa59a8 100644 --- a/projects/Makefile.X64 +++ b/projects/Makefile.X64 @@ -1,4 +1,5 @@ -include $(PWD)/rules_base +-include $(PWD)/rules_libav # config DEFINES := \ @@ -24,10 +25,10 @@ SDL_LIBS := $(shell pkg-config sdl2 --libs) OPT_FLAGS := -O3 #For debugging OPT_FLAGS := -g -INCLUDES := $(ALSA_CFLAGS) $(JACK_CFLAGS) $(SDL_CFLAGS) -I$(PWD)/../sources +INCLUDES := $(ALSA_CFLAGS) $(JACK_CFLAGS) $(SDL_CFLAGS) $(FFMPEG_CFLAGS) -I$(PWD)/../sources CFLAGS := $(OPT_FLAGS) $(DEFINES) $(INCLUDES) -Wall CXXFLAGS := $(CFLAGS) -std=gnu++11 -LIBS := $(ALSA_LIBS) $(JACK_LIBS) $(SDL_LIBS) +LIBS := $(ALSA_LIBS) $(JACK_LIBS) $(SDL_LIBS) $(FFMPEG_LIBS) OUTPUT := ../lgpt EXTENSION := x64 diff --git a/projects/rules_libav b/projects/rules_libav new file mode 100644 index 00000000..c8e13cf4 --- /dev/null +++ b/projects/rules_libav @@ -0,0 +1,7 @@ +FFMPEG_INCL= libavformat \ + libavfilter \ + libavcodec \ + libavutil \ + +FFMPEG_CFLAGS := $(shell pkg-config --cflags $(FFMPEG_INCL)) +FFMPEG_LIBS := $(shell pkg-config --libs $(FFMPEG_INCL)) \ No newline at end of file diff --git a/sources/Application/FX/FxPrinter.cpp b/sources/Application/FX/FxPrinter.cpp index 3c4a442a..8e22aaa0 100644 --- a/sources/Application/FX/FxPrinter.cpp +++ b/sources/Application/FX/FxPrinter.cpp @@ -8,11 +8,6 @@ FxPrinter::FxPrinter(ViewData* viewData) InstrumentBank* bank = viewData_->project_->GetInstrumentBank(); instrument_ = static_cast(bank->GetInstrument(curInstr)); notificationResult_ = ""; - // Assume ffmpeg exists but swap for local ffmpig if it doesn't - ffmpeg_ = "ffmpeg"; - Path pigPath("bin:ffmpig"); - Path ffmpigPath(pigPath.GetPath().c_str()); - if(ffmpigPath.Exists()) ffmpeg_ = pigPath.GetPath(); } void FxPrinter::setParams() { @@ -22,9 +17,10 @@ void FxPrinter::setParams() { void FxPrinter::setPaths() { fi_ = std::string(instrument_->GetName()); + fiPath_ = samples_dir.GetPath() + '/' + fi_; - foWav_ = fi_.substr(0, fi_.find_last_of('.')) + "_.wav"; - fo_ = "\"" + samples_dir.GetPath() + '/' + foWav_ + "\""; + fo_ = fi_.substr(0, fi_.find_last_of('.')) + "_.wav"; + foPath_ = samples_dir.GetPath() + '/' + fo_; ir_ = impulse_dir.GetPath() + "/IR-s/"; ir_ += std::string(instrument_->FindVariable(SIP_PRINTFX)->GetString()); @@ -36,9 +32,9 @@ std::string FxPrinter::parseCommand() { float smplLength = static_cast(instrument_->GetSampleSize()) / 44100; std::ostringstream cm1, cm2, cm3, cm4, cm5; - cm1 << ffmpeg_ << " -y -i " - << "\"" << samples_dir.GetPath() << "/" << fi_ << "\"" - << " -i " << ir_ << " -filter_complex "; + // cm1 << ffmpeg_ << " -y -i " + // << "\"" << fi_ << "\"" + // << " -i " << ir_ << " -filter_complex "; // bug in ffmpeg version 4.4.2 // requires pad_dur to be over 0 or output will be infinitely long if (irPad_ > 0) { @@ -64,13 +60,12 @@ bool FxPrinter::Run() { setParams(); setPaths(); // Are we overwriting an already imported sample? - bool imported = SamplePool::GetInstance()->IsImported(foWav_); - std::string cmd = parseCommand(); - Trace::Log("Processed", cmd.c_str()); - if (system(cmd.c_str()) == 0) { - int newIndex = SamplePool::GetInstance()->Reassign(foWav_, imported); + bool imported = SamplePool::GetInstance()->IsImported(fo_); + parseCommand(); + if (encode(fiPath_.c_str(), ir_.c_str(), foPath_.c_str(), irWet_, irPad_) == 0) { + int newIndex = SamplePool::GetInstance()->Reassign(fo_, imported); instrument_->AssignSample(newIndex); - notificationResult_ = "OK!"; + notificationResult_ = "libav OK!"; return true; } else { Trace::Log("PRINTFX", "Failed"); diff --git a/sources/Application/FX/FxPrinter.h b/sources/Application/FX/FxPrinter.h index 61ad65ad..0e5e3018 100644 --- a/sources/Application/FX/FxPrinter.h +++ b/sources/Application/FX/FxPrinter.h @@ -1,13 +1,14 @@ #ifndef FxPrinter_H #define FxPrinter_H -#include -#include -#include "Application/Views/ViewData.h" #include "Application/Instruments/InstrumentBank.h" #include "Application/Instruments/SampleInstrument.h" -#include "System/FileSystem/FileSystem.h" #include "Application/Instruments/SamplePool.h" +#include "Application/Views/ViewData.h" +#include "LibavProcessor.h" +#include "System/FileSystem/FileSystem.h" +#include +#include class FxPrinter { public: @@ -26,10 +27,10 @@ class FxPrinter { int irPad_; int irWet_; std::string fi_; + std::string fiPath_; std::string fo_; + std::string foPath_; std::string ir_; - std::string foWav_; - std::string ffmpeg_; char* notificationResult_; }; diff --git a/sources/Application/FX/LibavProcessor.c b/sources/Application/FX/LibavProcessor.c new file mode 100644 index 00000000..f10374e0 --- /dev/null +++ b/sources/Application/FX/LibavProcessor.c @@ -0,0 +1,704 @@ +/** + * Apply effects to a file using libav + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static AVFormatContext *ifmt_ctx; +static AVFormatContext *ir_fmt_ctx; +static AVFormatContext *ofmt_ctx; +static AVFilterGraph *filter_graph; +static AVFilterContext *buffersrc_ctx; +static AVFilterContext *ir_buffersrc_ctx; +static AVFilterContext *buffersink_ctx; +static AVCodecContext *enc_ctx = NULL; + +static int open_input_file(const char *filename) +{ + const AVCodec *dec; + AVCodecContext *dec_ctx; + AVStream *stream; + int ret; + + if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n"); + return ret; + } + + if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n"); + return ret; + } + + /* select the audio stream */ + ret = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot find an audio stream in the input file\n"); + return ret; + } + + stream = ifmt_ctx->streams[ret]; + + /* create decoding context */ + dec_ctx = avcodec_alloc_context3(dec); + if (!dec_ctx) + return AVERROR(ENOMEM); + avcodec_parameters_to_context(dec_ctx, stream->codecpar); + + /* init the audio decoder */ + if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot open audio decoder\n"); + return ret; + } + + stream->codecpar->codec_id = dec_ctx->codec_id; + stream->codecpar->sample_rate = dec_ctx->sample_rate; + stream->codecpar->format = dec_ctx->sample_fmt; + av_channel_layout_copy(&stream->codecpar->ch_layout, &dec_ctx->ch_layout); + + avcodec_free_context(&dec_ctx); + + return 0; +} + +static int open_ir_file(const char *filename) +{ + const AVCodec *dec; + AVCodecContext *dec_ctx; + AVStream *stream; + int ret; + + if ((ret = avformat_open_input(&ir_fmt_ctx, filename, NULL, NULL)) < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot open IR file\n"); + return ret; + } + + if ((ret = avformat_find_stream_info(ir_fmt_ctx, NULL)) < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot find stream information in IR file\n"); + return ret; + } + + /* select the audio stream */ + ret = av_find_best_stream(ir_fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot find an audio stream in the IR file\n"); + return ret; + } + + stream = ir_fmt_ctx->streams[ret]; + + /* create decoding context */ + dec_ctx = avcodec_alloc_context3(dec); + if (!dec_ctx) + return AVERROR(ENOMEM); + avcodec_parameters_to_context(dec_ctx, stream->codecpar); + + /* init the audio decoder */ + if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot open IR audio decoder\n"); + return ret; + } + + stream->codecpar->codec_id = dec_ctx->codec_id; + stream->codecpar->sample_rate = dec_ctx->sample_rate; + stream->codecpar->format = dec_ctx->sample_fmt; + av_channel_layout_copy(&stream->codecpar->ch_layout, &dec_ctx->ch_layout); + + avcodec_free_context(&dec_ctx); + + return 0; +} + +static int open_output_file(const char *filename) +{ + AVStream *out_stream; + AVStream *in_stream; + const AVCodec *encoder; + int ret; + + avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename); + if (!ofmt_ctx) { + av_log(NULL, AV_LOG_ERROR, "Could not create output context\n"); + return AVERROR_UNKNOWN; + } + + in_stream = ifmt_ctx->streams[0]; + out_stream = avformat_new_stream(ofmt_ctx, NULL); + if (!out_stream) { + av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n"); + return AVERROR_UNKNOWN; + } + + /* find encoder - force PCM 16-bit little-endian as requested */ + encoder = avcodec_find_encoder(AV_CODEC_ID_PCM_S16LE); + if (!encoder) { + av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n"); + return AVERROR_INVALIDDATA; + } + + enc_ctx = avcodec_alloc_context3(encoder); + if (!enc_ctx) { + av_log(NULL, AV_LOG_FATAL, "Failed to allocate the encoder context\n"); + return AVERROR(ENOMEM); + } + + /* Set output parameters to target format: 44.1kHz, 16-bit, stereo unless IR is mono */ + enc_ctx->sample_rate = 44100; + + /* Set channel layout based on IR format */ + int ir_channels = ir_fmt_ctx->streams[0]->codecpar->ch_layout.nb_channels; + if (ir_channels == 0) { + ir_channels = ir_fmt_ctx->streams[0]->codecpar->channels; + } + + if (ir_channels == 1) { + av_channel_layout_default(&enc_ctx->ch_layout, 1); /* Mono */ + } else { + av_channel_layout_default(&enc_ctx->ch_layout, 2); /* Stereo */ + } + + /* Use S16 format to match encoder */ + enc_ctx->sample_fmt = AV_SAMPLE_FMT_S16; + + /* Third parameter can be used to pass settings to encoder */ + ret = avcodec_open2(enc_ctx, encoder, NULL); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream\n"); + return ret; + } + ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctx); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream\n"); + return ret; + } + + out_stream->time_base = enc_ctx->time_base; + + av_dump_format(ofmt_ctx, 0, filename, 1); + + /* open the output file, if needed */ + if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) { + ret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", filename); + return ret; + } + } + + /* init muxer, write output file header */ + ret = avformat_write_header(ofmt_ctx, NULL); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n"); + return ret; + } + + return 0; +} + +static int init_filters(int ir_wet, int ir_pad) +{ + char args[512]; + char ir_args[512]; + int ret = 0; + const AVFilter *abuffer, *abuffersink; + AVFilterInOut *outputs = avfilter_inout_alloc(); + AVFilterInOut *inputs = avfilter_inout_alloc(); + AVRational time_base = ifmt_ctx->streams[0]->time_base; + AVRational ir_time_base = ir_fmt_ctx->streams[0]->time_base; + + /* Determine the target format - always 44.1kHz, stereo unless IR is mono */ + char target_layout[64]; + int target_sample_rate = 44100; + + /* Determine output channel layout based on IR format */ + int ir_channels = ir_fmt_ctx->streams[0]->codecpar->ch_layout.nb_channels; + if (ir_channels == 0) { + ir_channels = ir_fmt_ctx->streams[0]->codecpar->channels; + } + + if (ir_channels == 1) { + strcpy(target_layout, "mono"); /* If IR is mono, output mono for simplicity */ + } else { + strcpy(target_layout, "stereo"); /* Otherwise, output stereo */ + } + + filter_graph = avfilter_graph_alloc(); + if (!outputs || !inputs || !filter_graph) { + ret = AVERROR(ENOMEM); + goto end; + } + + /* buffer audio source: the decoded frames from the decoder will be inserted here. */ + abuffer = avfilter_get_by_name("abuffer"); + if (!abuffer) { + av_log(NULL, AV_LOG_ERROR, "Could not find the abuffer filter.\n"); + ret = AVERROR_FILTER_NOT_FOUND; + goto end; + } + + buffersrc_ctx = avfilter_graph_alloc_filter(filter_graph, abuffer, "in"); + if (!buffersrc_ctx) { + av_log(NULL, AV_LOG_ERROR, "Could not allocate the abuffer instance.\n"); + ret = AVERROR(ENOMEM); + goto end; + } + + /* Set the filter options through the AVOptions API. */ + char ch_layout_str[64]; + // Use the actual channel layout from the input file + if (ifmt_ctx->streams[0]->codecpar->ch_layout.nb_channels == 0) { + // If channel layout is unknown, default based on channel count + if (ifmt_ctx->streams[0]->codecpar->channels == 1) { + strcpy(ch_layout_str, "mono"); + } else if (ifmt_ctx->streams[0]->codecpar->channels == 2) { + strcpy(ch_layout_str, "stereo"); + } else { + snprintf(ch_layout_str, sizeof(ch_layout_str), "%dc", ifmt_ctx->streams[0]->codecpar->channels); + } + } else { + av_channel_layout_describe(&ifmt_ctx->streams[0]->codecpar->ch_layout, ch_layout_str, sizeof(ch_layout_str)); + } + snprintf(args, sizeof(args), + "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%s", + time_base.num, time_base.den, ifmt_ctx->streams[0]->codecpar->sample_rate, + av_get_sample_fmt_name(ifmt_ctx->streams[0]->codecpar->format), + ch_layout_str); + ret = avfilter_init_str(buffersrc_ctx, args); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Could not initialize the abuffer filter.\n"); + goto end; + } + + /* buffer audio source for IR: the decoded IR frames will be inserted here. */ + ir_buffersrc_ctx = avfilter_graph_alloc_filter(filter_graph, abuffer, "ir_in"); + if (!ir_buffersrc_ctx) { + av_log(NULL, AV_LOG_ERROR, "Could not allocate the IR abuffer instance.\n"); + ret = AVERROR(ENOMEM); + goto end; + } + + char ir_ch_layout_str[64]; + // Use the actual channel layout from the IR file + if (ir_fmt_ctx->streams[0]->codecpar->ch_layout.nb_channels == 0) { + // If channel layout is unknown, default based on channel count + if (ir_fmt_ctx->streams[0]->codecpar->channels == 1) { + strcpy(ir_ch_layout_str, "mono"); + } else if (ir_fmt_ctx->streams[0]->codecpar->channels == 2) { + strcpy(ir_ch_layout_str, "stereo"); + } else { + snprintf(ir_ch_layout_str, sizeof(ir_ch_layout_str), "%dc", ir_fmt_ctx->streams[0]->codecpar->channels); + } + } else { + av_channel_layout_describe(&ir_fmt_ctx->streams[0]->codecpar->ch_layout, ir_ch_layout_str, sizeof(ir_ch_layout_str)); + } + snprintf(ir_args, sizeof(ir_args), + "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%s", + ir_time_base.num, ir_time_base.den, ir_fmt_ctx->streams[0]->codecpar->sample_rate, + av_get_sample_fmt_name(ir_fmt_ctx->streams[0]->codecpar->format), + ir_ch_layout_str); + ret = avfilter_init_str(ir_buffersrc_ctx, ir_args); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Could not initialize the IR abuffer filter.\n"); + goto end; + } + + /* buffer audio sink: to terminate the filter chain. */ + abuffersink = avfilter_get_by_name("abuffersink"); + if (!abuffersink) { + av_log(NULL, AV_LOG_ERROR, "Could not find the abuffersink filter.\n"); + ret = AVERROR_FILTER_NOT_FOUND; + goto end; + } + + buffersink_ctx = avfilter_graph_alloc_filter(filter_graph, abuffersink, "out"); + if (!buffersink_ctx) { + av_log(NULL, AV_LOG_ERROR, "Could not allocate the abuffersink instance.\n"); + ret = AVERROR(ENOMEM); + goto end; + } + + /* Configure the buffersink to accept the expected format */ + static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 }; + ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1, AV_OPT_SEARCH_CHILDREN); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n"); + goto end; + } + + ret = av_opt_set(buffersink_ctx, "ch_layouts", target_layout, AV_OPT_SEARCH_CHILDREN); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n"); + goto end; + } + + /* This filter takes no options. */ + ret = avfilter_init_str(buffersink_ctx, NULL); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Could not initialize the abuffersink instance.\n"); + goto end; + } + + /* + * Set the endpoints for the filter graph. The filter_graph will + * be linked to the graph described by filters_descr. + */ + + /* + * The buffer source output must be connected to the input pad of + * the first filter described by filters_descr; since the first + * filter input label is "in", with the pointer, we leave this + * pad open. + */ + outputs->name = av_strdup("in"); + outputs->filter_ctx = buffersrc_ctx; + outputs->pad_idx = 0; + outputs->next = avfilter_inout_alloc(); + + outputs->next->name = av_strdup("ir_in"); + outputs->next->filter_ctx = ir_buffersrc_ctx; + outputs->next->pad_idx = 0; + outputs->next->next = NULL; + + /* + * The buffer sink input must be connected to the output pad of + * the last filter described by filters_descr; since the last + * filter output label is "out", with the pointer, we leave this + * pad open. + */ + inputs->name = av_strdup("out"); + inputs->filter_ctx = buffersink_ctx; + inputs->pad_idx = 0; + inputs->next = NULL; + + /* Apply convolution reverb using afir filter with format normalization */ + char filters_descr[512]; + snprintf(filters_descr, sizeof(filters_descr), + "[ir_in]aresample=%d,aformat=sample_fmts=fltp:channel_layouts=%s[ir_norm];" + "[in]aresample=%d,aformat=sample_fmts=fltp:channel_layouts=%s,asplit[in_1][in_2];" + "[in_1][ir_norm]afir=dry=10:wet=10[reverb];" + "[in_2][reverb]amix=inputs=2:weights=100 %d,volume=1.5,aformat=sample_fmts=s16:channel_layouts=%s[out]", + target_sample_rate, target_layout, target_sample_rate, target_layout, ir_wet, target_layout); + + av_log(NULL, AV_LOG_INFO, "Filter graph: %s\n", filters_descr); + + if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr, + &inputs, &outputs, NULL)) < 0) + goto end; + + if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) + goto end; + +end: + avfilter_inout_free(&inputs); + avfilter_inout_free(&outputs); + + return ret; +} + +static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) { + int ret; + int got_frame_local; + AVPacket *enc_pkt; + + if (!got_frame) + got_frame = &got_frame_local; + + if (!enc_ctx) { + return AVERROR(EINVAL); + } + + enc_pkt = av_packet_alloc(); + if (!enc_pkt) { + return AVERROR(ENOMEM); + } + + /* encode filtered frame */ + ret = avcodec_send_frame(enc_ctx, filt_frame); + if (ret < 0) + goto end; + + while (ret >= 0) { + ret = avcodec_receive_packet(enc_ctx, enc_pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + ret = 0; /* These are not errors */ + break; + } else if (ret < 0) + goto end; + + /* prepare packet for muxing */ + enc_pkt->stream_index = stream_index; + av_packet_rescale_ts(enc_pkt, + enc_ctx->time_base, + ofmt_ctx->streams[stream_index]->time_base); + + /* mux encoded frame */ + ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt); + if (ret < 0) + break; + } + +end: + av_packet_free(&enc_pkt); + return ret; +} + +static int filter_encode_write_frame(AVFrame *frame, AVFrame *ir_frame, unsigned int stream_index) +{ + int ret; + AVFrame *filt_frame; + + /* Only add frames if they are provided */ + if (frame) { + ret = av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while feeding the input filtergraph\n"); + return ret; + } + } + + if (ir_frame) { + ret = av_buffersrc_add_frame_flags(ir_buffersrc_ctx, ir_frame, AV_BUFFERSRC_FLAG_KEEP_REF); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while feeding the IR filtergraph\n"); + return ret; + } + } + + /* Always try to pull filtered frames from the filtergraph */ + while (1) { + filt_frame = av_frame_alloc(); + if (!filt_frame) { + ret = AVERROR(ENOMEM); + break; + } + ret = av_buffersink_get_frame(buffersink_ctx, filt_frame); + if (ret < 0) { + /* if no more frames for output - returns AVERROR(EAGAIN) + * if flushed and no more frames for output - returns AVERROR_EOF + * rewrite retcode to 0 to show it as normal procedure completion + */ + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + ret = 0; + av_frame_free(&filt_frame); + break; + } + + printf("Got filtered frame: %d samples, %d channels, %d Hz\n", + filt_frame->nb_samples, filt_frame->ch_layout.nb_channels, filt_frame->sample_rate); + + ret = encode_write_frame(filt_frame, stream_index, NULL); + av_frame_free(&filt_frame); + if (ret < 0) + break; + } + + return ret; +} + +int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad) +{ + int ret; + AVPacket *packet = NULL, *ir_packet = NULL; + AVFrame *frame = NULL, *ir_frame = NULL; + AVCodecContext *dec_ctx = NULL, *ir_dec_ctx = NULL; + unsigned int stream_index; + int ir_loaded = 0; + + if ((ret = open_input_file(fi)) < 0) + goto end; + if ((ret = open_ir_file(ir)) < 0) + goto end; + if ((ret = open_output_file(fo)) < 0) + goto end; + if ((ret = init_filters(irWet, irPad)) < 0) + goto end; + + packet = av_packet_alloc(); + ir_packet = av_packet_alloc(); + frame = av_frame_alloc(); + ir_frame = av_frame_alloc(); + if (!packet || !ir_packet || !frame || !ir_frame) { + fprintf(stderr, "Could not allocate frame or packet\n"); + return(1); + } + + /* Set up decoder contexts */ + const AVCodec *dec = avcodec_find_decoder(ifmt_ctx->streams[0]->codecpar->codec_id); + const AVCodec *ir_dec = avcodec_find_decoder(ir_fmt_ctx->streams[0]->codecpar->codec_id); + + dec_ctx = avcodec_alloc_context3(dec); + ir_dec_ctx = avcodec_alloc_context3(ir_dec); + + avcodec_parameters_to_context(dec_ctx, ifmt_ctx->streams[0]->codecpar); + avcodec_parameters_to_context(ir_dec_ctx, ir_fmt_ctx->streams[0]->codecpar); + + avcodec_open2(dec_ctx, dec, NULL); + avcodec_open2(ir_dec_ctx, ir_dec, NULL); + + /* Process both streams - load ALL IR data first, then process main audio */ + int ir_eof = 0, main_eof = 0; + + /* First load all IR data */ + while (!ir_eof && av_read_frame(ir_fmt_ctx, ir_packet) >= 0) { + if (ir_packet->stream_index == 0) { + ret = avcodec_send_packet(ir_dec_ctx, ir_packet); + while (ret >= 0) { + ret = avcodec_receive_frame(ir_dec_ctx, ir_frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + break; + } else if (ret < 0) { + fprintf(stderr, "Error while decoding IR\n"); + goto end; + } + + ret = av_buffersrc_add_frame_flags(ir_buffersrc_ctx, ir_frame, AV_BUFFERSRC_FLAG_KEEP_REF); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while feeding the IR filtergraph\n"); + goto end; + } + ir_loaded = 1; + } + } + av_packet_unref(ir_packet); + } + + /* Signal end of IR stream */ + ret = av_buffersrc_add_frame_flags(ir_buffersrc_ctx, NULL, 0); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error closing IR filtergraph\n"); + goto end; + } + + if (!ir_loaded) { + fprintf(stderr, "No impulse response data loaded\n"); + goto end; + } + + /* Now process the main audio */ + while (!main_eof && av_read_frame(ifmt_ctx, packet) >= 0) { + if (packet->stream_index == 0) { + ret = avcodec_send_packet(dec_ctx, packet); + while (ret >= 0) { + ret = avcodec_receive_frame(dec_ctx, frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + break; + } else if (ret < 0) { + fprintf(stderr, "Error while decoding\n"); + goto end; + } + + ret = av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while feeding the input filtergraph\n"); + goto end; + } + /* Pull filtered frames immediately */ + while (1) { + AVFrame *filt_frame = av_frame_alloc(); + ret = av_buffersink_get_frame(buffersink_ctx, filt_frame); + if (ret == AVERROR(EAGAIN)) { + av_frame_free(&filt_frame); + break; /* Need more input */ + } else if (ret == AVERROR_EOF) { + av_frame_free(&filt_frame); + break; /* No more frames */ + } else if (ret < 0) { + printf("Error getting frame from filter: %s\n", av_err2str(ret)); + av_frame_free(&filt_frame); + goto end; + } + + ret = encode_write_frame(filt_frame, 0, NULL); + av_frame_free(&filt_frame); + if (ret < 0) { + goto end; + } + } + } + } + av_packet_unref(packet); + } + + /* flush the filter graph by sending EOF to input sources */ + ret = av_buffersrc_add_frame_flags(buffersrc_ctx, NULL, 0); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while closing the input filtergraph\n"); + goto end; + } + + /* Pull any remaining frames from the filter graph */ + ret = filter_encode_write_frame(NULL, NULL, 0); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Flushing filter failed\n"); + goto end; + } + + /* flush the encoder */ + ret = avcodec_send_frame(enc_ctx, NULL); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error sending NULL frame to encoder\n"); + goto end; + } + + while (ret >= 0) { + AVPacket *enc_pkt = av_packet_alloc(); + ret = avcodec_receive_packet(enc_ctx, enc_pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + av_packet_free(&enc_pkt); + break; + } else if (ret < 0) { + av_packet_free(&enc_pkt); + av_log(NULL, AV_LOG_ERROR, "Error during encoder flush\n"); + goto end; + } + + enc_pkt->stream_index = 0; + av_packet_rescale_ts(enc_pkt, enc_ctx->time_base, ofmt_ctx->streams[0]->time_base); + ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt); + av_packet_free(&enc_pkt); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error writing final packet\n"); + goto end; + } + } + + av_write_trailer(ofmt_ctx); +end: + if (dec_ctx) { + avcodec_free_context(&dec_ctx); + } + if (ir_dec_ctx) { + avcodec_free_context(&ir_dec_ctx); + } + av_frame_free(&frame); + av_frame_free(&ir_frame); + av_packet_free(&packet); + av_packet_free(&ir_packet); + avfilter_graph_free(&filter_graph); + avformat_close_input(&ifmt_ctx); + avformat_close_input(&ir_fmt_ctx); + + if (enc_ctx) { + avcodec_free_context(&enc_ctx); + } + + if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) { + avio_closep(&ofmt_ctx->pb); + } + avformat_free_context(ofmt_ctx); + + if (ret < 0 && ret != AVERROR_EOF) { + fprintf(stderr, "Error occurred: %s\n", av_err2str(ret)); + return(1); + } + return 0; +} diff --git a/sources/Application/FX/LibavProcessor.h b/sources/Application/FX/LibavProcessor.h new file mode 100644 index 00000000..10b24fd9 --- /dev/null +++ b/sources/Application/FX/LibavProcessor.h @@ -0,0 +1,14 @@ +#ifndef LIBAV_PROC_H +#define LIBAV_PROC_H + +#ifdef __cplusplus +extern "C" { +#endif + +int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file From 5e8eda6ad792f975318bd9e084de202a76715b29 Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Sat, 18 Oct 2025 20:53:14 +0200 Subject: [PATCH 02/17] Add legacy support Adds backwards compatibility Bittboy config builds OK! Garlic config Miyoo does not build, missing libs in toolchain --- projects/Makefile.BITTBOY | 9 ++- projects/Makefile.GARLIC | 8 ++- projects/Makefile.MIYOO | 6 +- projects/rules_libav | 8 ++- sources/Application/FX/LibavProcessor.c | 81 ++++++++++++++++++++++--- 5 files changed, 95 insertions(+), 17 deletions(-) diff --git a/projects/Makefile.BITTBOY b/projects/Makefile.BITTBOY index 2b505bcf..165fc21f 100644 --- a/projects/Makefile.BITTBOY +++ b/projects/Makefile.BITTBOY @@ -1,4 +1,5 @@ -include $(PWD)/rules_base + STRIP = $(CROSS_COMPILE)strip DEFINES := \ @@ -8,6 +9,8 @@ DEFINES := \ -DHAVE_STDINT_H \ -D_NDEBUG \ -D__LINUX_ALSA__ \ + -DFFMPEG_ENABLED \ + -DFFMPEG_LEGACY_API \ -D_NO_JACK_ DEVKIT=/opt/arm-buildroot-linux-musleabi_sdk-buildroot @@ -19,14 +22,16 @@ SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) SDL_LIBS := $(shell $(SYSROOT)/usr/bin/sdl-config --libs) SDL_BASE = $(DEVKIT)/arm-buildroot-linux-musleabi/sysroot/usr/bin/ +-include $(PWD)/rules_libav + TOOLPATH=$(DEVKIT)/usr/bin PREFIX := arm-linux- OPT_FLAGS = -O3 -Ofast -INCLUDES = -I$(PWD)/../sources -Iinclude $(SDL_CFLAGS) +INCLUDES = -I$(PWD)/../sources -Iinclude $(SDL_CFLAGS) $(FFMPEG_CFLAGS) CFLAGS := $(DEFINES) $(INCLUDES) $(OPT_FLAGS) $(SDL_CFLAGS) -Wall -DRS97 CXXFLAGS:= $(CFLAGS) -std=gnu++03 -LIBS := $(SDL_LIBS) -lSDL -lSDL_mixer -lasound -lpthread +LIBS := $(SDL_LIBS) -lSDL -lSDL_mixer -lasound -lpthread $(FFMPEG_LIBS) LIBDIRS := $(DEKVIT)/usr/lib OUTPUT = ../lgpt-bittboy EXTENSION:= elf diff --git a/projects/Makefile.GARLIC b/projects/Makefile.GARLIC index 657f6abe..63fa2393 100644 --- a/projects/Makefile.GARLIC +++ b/projects/Makefile.GARLIC @@ -6,6 +6,8 @@ DEFINES := \ -DCPP_MEMORY \ -D_NDEBUG \ -DHAVE_STDINT_H \ + -DFFMPEG_ENABLED \ + -DFFMPEG_LEGACY_API \ -D_NO_JACK_ DEVKIT = /opt/miyoo/ @@ -19,13 +21,15 @@ SYSROOT := $(shell $(CROSS_COMPILE)gcc --print-sysroot) SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) SDL_LIBS := $(shell $(SYSROOT)/usr/bin/sdl-config --libs) +-include $(PWD)/rules_libav + # optimization OPT_FLAGS = -O3 -Ofast -fdata-sections -fdata-sections -fno-common -fno-PIC -flto -marm -mtune=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard PREFIX := arm-linux-gnueabihf- -INCLUDES:= -Iinclude $(SDL_CFLAGS) -I$(PWD)/../sources +INCLUDES:= -Iinclude $(SDL_CFLAGS) $(FFMPEG_CFLAGS) -I$(PWD)/../sources CFLAGS := $(DEFINES) $(INCLUDES) $(OPT_FLAGS) -Wall CXXFLAGS:= $(CFLAGS) -std=gnu++03 -LIBS := $(SDL_LIBS) -lpthread +LIBS := $(SDL_LIBS) $(FFMPEG_LIBS) -lpthread LIBDIRS := $(DEKVIT)/usr/lib LIBDIRS += $(DEKVIT)/usr/include OUTPUT := ../lgpt-garlic diff --git a/projects/Makefile.MIYOO b/projects/Makefile.MIYOO index e38c4117..e36bda73 100644 --- a/projects/Makefile.MIYOO +++ b/projects/Makefile.MIYOO @@ -6,6 +6,7 @@ DEFINES := \ -DCPP_MEMORY \ -DHAVE_STDINT_H \ -D_NDEBUG \ + -DFFMPEG_ENABLED \ -D_NO_JACK_ DEVKIT = /opt/miyoomini-toolchain/ @@ -18,16 +19,17 @@ SYSROOT := $(shell $(CROSS_COMPILE)gcc --print-sysroot) SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) SDL_LIBS := $(shell $(SYSROOT)/usr/bin/sdl-config --libs) -INCLUDES = -Iinclude $(SDL_CFLAGS) -I$(PWD)/../sources +INCLUDES = -Iinclude $(SDL_CFLAGS) $(FFMPEG_CFLAGS) -I$(PWD)/../sources OPT_FLAGS = -O3 -Ofast -fdata-sections -fdata-sections -fno-common -fno-PIC -flto -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve+simd +-include $(PWD)/rules_libav TOOLPATH=$(DEVKIT)/usr/bin PREFIX := arm-linux-gnueabihf- CFLAGS := $(DEFINES) $(INCLUDES) $(SDL_CFLAGS) $(OPT_FLAGS) -Wall CXXFLAGS:= $(CFLAGS) -std=gnu++03 -LIBS := -lSDL -lSDL_mixer -lpthread $(SDL_LIBS) +LIBS := -lSDL -lSDL_mixer -lpthread $(SDL_LIBS) $(FFMPEG_LIBS) LIBDIRS := $(DEKVIT)/usr/lib LIBDIRS += $(DEKVIT)/usr/include OUTPUT = ../lgpt-miyoo diff --git a/projects/rules_libav b/projects/rules_libav index c8e13cf4..9c577791 100644 --- a/projects/rules_libav +++ b/projects/rules_libav @@ -3,5 +3,11 @@ FFMPEG_INCL= libavformat \ libavcodec \ libavutil \ +# Use SYSROOT for cross-compilation, fallback to system pkg-config for native builds +ifdef SYSROOT +FFMPEG_CFLAGS := $(shell $(DEVKIT)/bin/pkg-config --cflags $(FFMPEG_INCL)) +FFMPEG_LIBS := $(shell $(DEVKIT)/bin/pkg-config --libs $(FFMPEG_INCL)) +else FFMPEG_CFLAGS := $(shell pkg-config --cflags $(FFMPEG_INCL)) -FFMPEG_LIBS := $(shell pkg-config --libs $(FFMPEG_INCL)) \ No newline at end of file +FFMPEG_LIBS := $(shell pkg-config --libs $(FFMPEG_INCL)) +endif \ No newline at end of file diff --git a/sources/Application/FX/LibavProcessor.c b/sources/Application/FX/LibavProcessor.c index f10374e0..8f0de6d2 100644 --- a/sources/Application/FX/LibavProcessor.c +++ b/sources/Application/FX/LibavProcessor.c @@ -24,7 +24,7 @@ static AVCodecContext *enc_ctx = NULL; static int open_input_file(const char *filename) { - const AVCodec *dec; + AVCodec *dec; AVCodecContext *dec_ctx; AVStream *stream; int ret; @@ -63,7 +63,12 @@ static int open_input_file(const char *filename) stream->codecpar->codec_id = dec_ctx->codec_id; stream->codecpar->sample_rate = dec_ctx->sample_rate; stream->codecpar->format = dec_ctx->sample_fmt; +#ifdef FFMPEG_LEGACY_API + stream->codecpar->channels = dec_ctx->channels; + stream->codecpar->channel_layout = dec_ctx->channel_layout; +#else av_channel_layout_copy(&stream->codecpar->ch_layout, &dec_ctx->ch_layout); +#endif avcodec_free_context(&dec_ctx); @@ -72,7 +77,7 @@ static int open_input_file(const char *filename) static int open_ir_file(const char *filename) { - const AVCodec *dec; + AVCodec *dec; AVCodecContext *dec_ctx; AVStream *stream; int ret; @@ -111,7 +116,12 @@ static int open_ir_file(const char *filename) stream->codecpar->codec_id = dec_ctx->codec_id; stream->codecpar->sample_rate = dec_ctx->sample_rate; stream->codecpar->format = dec_ctx->sample_fmt; +#ifdef FFMPEG_LEGACY_API + stream->codecpar->channels = dec_ctx->channels; + stream->codecpar->channel_layout = dec_ctx->channel_layout; +#else av_channel_layout_copy(&stream->codecpar->ch_layout, &dec_ctx->ch_layout); +#endif avcodec_free_context(&dec_ctx); @@ -155,6 +165,20 @@ static int open_output_file(const char *filename) enc_ctx->sample_rate = 44100; /* Set channel layout based on IR format */ +#ifdef FFMPEG_LEGACY_API + int ir_channels = ir_fmt_ctx->streams[0]->codecpar->channels; + if (ir_channels == 0) { + ir_channels = ir_fmt_ctx->streams[0]->codecpar->channels; + } + + if (ir_channels == 1) { + enc_ctx->channels = 1; + enc_ctx->channel_layout = AV_CH_LAYOUT_MONO; + } else { + enc_ctx->channels = 2; + enc_ctx->channel_layout = AV_CH_LAYOUT_STEREO; + } +#else int ir_channels = ir_fmt_ctx->streams[0]->codecpar->ch_layout.nb_channels; if (ir_channels == 0) { ir_channels = ir_fmt_ctx->streams[0]->codecpar->channels; @@ -165,7 +189,8 @@ static int open_output_file(const char *filename) } else { av_channel_layout_default(&enc_ctx->ch_layout, 2); /* Stereo */ } - +#endif + /* Use S16 format to match encoder */ enc_ctx->sample_fmt = AV_SAMPLE_FMT_S16; @@ -220,11 +245,18 @@ static int init_filters(int ir_wet, int ir_pad) int target_sample_rate = 44100; /* Determine output channel layout based on IR format */ +#ifdef FFMPEG_LEGACY_API + int ir_channels = ir_fmt_ctx->streams[0]->codecpar->channels; + if (ir_channels == 0) { + ir_channels = ir_fmt_ctx->streams[0]->codecpar->channels; + } +#else int ir_channels = ir_fmt_ctx->streams[0]->codecpar->ch_layout.nb_channels; if (ir_channels == 0) { ir_channels = ir_fmt_ctx->streams[0]->codecpar->channels; } - +#endif + if (ir_channels == 1) { strcpy(target_layout, "mono"); /* If IR is mono, output mono for simplicity */ } else { @@ -255,6 +287,15 @@ static int init_filters(int ir_wet, int ir_pad) /* Set the filter options through the AVOptions API. */ char ch_layout_str[64]; // Use the actual channel layout from the input file +#ifdef FFMPEG_LEGACY_API + if (ifmt_ctx->streams[0]->codecpar->channels == 1) { + strcpy(ch_layout_str, "mono"); + } else if (ifmt_ctx->streams[0]->codecpar->channels == 2) { + strcpy(ch_layout_str, "stereo"); + } else { + snprintf(ch_layout_str, sizeof(ch_layout_str), "%dc", ifmt_ctx->streams[0]->codecpar->channels); + } +#else if (ifmt_ctx->streams[0]->codecpar->ch_layout.nb_channels == 0) { // If channel layout is unknown, default based on channel count if (ifmt_ctx->streams[0]->codecpar->channels == 1) { @@ -265,8 +306,10 @@ static int init_filters(int ir_wet, int ir_pad) snprintf(ch_layout_str, sizeof(ch_layout_str), "%dc", ifmt_ctx->streams[0]->codecpar->channels); } } else { - av_channel_layout_describe(&ifmt_ctx->streams[0]->codecpar->ch_layout, ch_layout_str, sizeof(ch_layout_str)); + av_channel_layout_describe(&buffersink_ctx->inputs[0]->ch_layout, + ch_layout_str, sizeof(ch_layout_str)); } +#endif snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%s", time_base.num, time_base.den, ifmt_ctx->streams[0]->codecpar->sample_rate, @@ -288,6 +331,15 @@ static int init_filters(int ir_wet, int ir_pad) char ir_ch_layout_str[64]; // Use the actual channel layout from the IR file +#ifdef FFMPEG_LEGACY_API + if (ir_fmt_ctx->streams[0]->codecpar->channels == 1) { + strcpy(ir_ch_layout_str, "mono"); + } else if (ir_fmt_ctx->streams[0]->codecpar->channels == 2) { + strcpy(ir_ch_layout_str, "stereo"); + } else { + snprintf(ir_ch_layout_str, sizeof(ir_ch_layout_str), "%dc", ir_fmt_ctx->streams[0]->codecpar->channels); + } +#else if (ir_fmt_ctx->streams[0]->codecpar->ch_layout.nb_channels == 0) { // If channel layout is unknown, default based on channel count if (ir_fmt_ctx->streams[0]->codecpar->channels == 1) { @@ -298,8 +350,10 @@ static int init_filters(int ir_wet, int ir_pad) snprintf(ir_ch_layout_str, sizeof(ir_ch_layout_str), "%dc", ir_fmt_ctx->streams[0]->codecpar->channels); } } else { - av_channel_layout_describe(&ir_fmt_ctx->streams[0]->codecpar->ch_layout, ir_ch_layout_str, sizeof(ir_ch_layout_str)); + av_channel_layout_describe(&buffersink_ctx->inputs[0]->ch_layout, + ir_ch_layout_str, sizeof(ir_ch_layout_str)); } +#endif snprintf(ir_args, sizeof(ir_args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%s", ir_time_base.num, ir_time_base.den, ir_fmt_ctx->streams[0]->codecpar->sample_rate, @@ -492,8 +546,14 @@ static int filter_encode_write_frame(AVFrame *frame, AVFrame *ir_frame, unsigned break; } - printf("Got filtered frame: %d samples, %d channels, %d Hz\n", - filt_frame->nb_samples, filt_frame->ch_layout.nb_channels, filt_frame->sample_rate); + printf("Got filtered frame: %d samples, %d channels, %d Hz\n", +#ifdef FFMPEG_LEGACY_API + filt_frame->nb_samples, filt_frame->channels, + filt_frame->sample_rate); +#else + filt_frame->nb_samples, filt_frame->ch_layout.nb_channels, + filt_frame->sample_rate); +#endif ret = encode_write_frame(filt_frame, stream_index, NULL); av_frame_free(&filt_frame); @@ -532,8 +592,9 @@ int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad) } /* Set up decoder contexts */ - const AVCodec *dec = avcodec_find_decoder(ifmt_ctx->streams[0]->codecpar->codec_id); - const AVCodec *ir_dec = avcodec_find_decoder(ir_fmt_ctx->streams[0]->codecpar->codec_id); + AVCodec *dec = + avcodec_find_decoder(ifmt_ctx->streams[0]->codecpar->codec_id); + AVCodec *ir_dec = avcodec_find_decoder(ir_fmt_ctx->streams[0]->codecpar->codec_id); dec_ctx = avcodec_alloc_context3(dec); ir_dec_ctx = avcodec_alloc_context3(ir_dec); From b325f83a35c3080c1c7eb0af0dd4318c61bc8062 Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Sat, 18 Oct 2025 23:41:29 +0200 Subject: [PATCH 03/17] Fix build errors for most platforms Add support for garlicplus, rg35xxplus Conditionally import libavprocessor if ffmpeg enabled --- .github/workflows/build.yml | 7 ++++--- .github/workflows/check.yml | 10 ++++++---- projects/Makefile | 9 +++++++-- projects/Makefile.GARLICPLUS | 10 +++++++--- projects/Makefile.RG35XXPLUS | 6 ++++-- sources/Application/FX/FxPrinter.cpp | 2 ++ sources/Application/FX/FxPrinter.h | 4 +++- 7 files changed, 33 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c811a04c..9839b784 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,7 +14,7 @@ jobs: run: | python -m pip install --upgrade pip pip install Pillow - choco install -y directx-sdk zip --no-progress --yes + choco install -y directx-sdk zip ffmpeg-shared --no-progress --yes shell: powershell - name: Download and Extract VCE9 release @@ -151,7 +151,7 @@ jobs: - name: Install required libraries run: | sudo apt update - sudo apt install -y make pkgconf libsdl2-dev libasound2-plugins libjack-dev python3-pillow + sudo apt install -y make pkgconf libsdl2-dev libasound2-plugins libjack-dev python3-pillow libavcodec-dev libavformat-dev libavfilter-dev libavutil-dev libswresample-dev - name: Build X64 working-directory: projects @@ -319,7 +319,7 @@ jobs: wget -qO ./debian-archive-keyring.deb "$BASE$LATEST" dpkg -i ./debian-archive-keyring.deb - apt update && apt install -y python3 python3-pillow + apt update && apt install -y python3 python3-pillow cd projects make PLATFORM=GARLIC ' @@ -439,6 +439,7 @@ jobs: wget https://www.libsdl.org/release/SDL2-2.0.14.dmg hdiutil attach SDL2-2.0.14.dmg sudo cp -R /Volumes/SDL2/SDL2.framework /Library/Frameworks/ + brew install ffmpeg - name: Build Xcode project run: | diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index cac485d8..ec3fffa6 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -60,7 +60,7 @@ jobs: uses: actions/checkout@v4.1.7 - name: Install build deps - run: choco install -y directx-sdk zip --no-progress --yes + run: choco install -y directx-sdk zip ffmpeg-shared --no-progress --yes shell: powershell - name: Download and Extract VCE9 release @@ -116,7 +116,7 @@ jobs: run: | sudo dpkg --add-architecture i386 sudo apt update - sudo apt install -y make pkgconf gcc-multilib g++-multilib libsdl1.2-dev:i386 libasound2-plugins:i386 libjack-dev:i386 python3-pillow + sudo apt install -y make pkgconf gcc-multilib g++-multilib libsdl1.2-dev:i386 libasound2-plugins:i386 libjack-dev:i386 python3-pillow libavcodec-dev:i386 libavformat-dev:i386 libavfilter-dev:i386 libavutil-dev:i386 libswresample-dev:i386 - name: Build DEB working-directory: projects @@ -148,7 +148,7 @@ jobs: run: | sudo dpkg --add-architecture i386 sudo apt update - sudo apt install -y make pkgconf gcc-multilib g++-multilib libsdl2-dev:i386 libasound2-plugins:i386 libjack-dev:i386 python3-pillow + sudo apt install -y make pkgconf gcc-multilib g++-multilib libsdl2-dev:i386 libasound2-plugins:i386 libjack-dev:i386 python3-pillow libavcodec-dev:i386 libavformat-dev:i386 libavfilter-dev:i386 libavutil-dev:i386 libswresample-dev:i386 - name: Build X86 working-directory: projects @@ -395,7 +395,8 @@ jobs: - name: Install required libraries run: | sudo apt update - sudo apt install -y make pkgconf libsdl2-dev libasound2-plugins libjack-dev python3-pillow + sudo apt install -y make pkgconf libsdl2-dev libasound2-plugins libjack-dev python3-pillow libavcodec-dev libavformat-dev libavfilter-dev libavutil-dev libswresample-dev + - name: Build X64 working-directory: projects @@ -429,6 +430,7 @@ jobs: wget https://www.libsdl.org/release/SDL2-2.0.14.dmg hdiutil attach SDL2-2.0.14.dmg sudo cp -R /Volumes/SDL2/SDL2.framework /Library/Frameworks/ + brew install ffmpeg - name: Build Xcode project run: | diff --git a/projects/Makefile b/projects/Makefile index 5267e08f..4bed97eb 100644 --- a/projects/Makefile +++ b/projects/Makefile @@ -260,8 +260,7 @@ COMMONFILES := \ SyncMaster.o TablePlayback.o Player.o \ Table.o TableView.o\ InstrumentBank.o WavFileWriter.o WavFile.o MidiInstrument.o Filters.o \ - SampleVariable.o SampleInstrument.o SamplePool.o CommandList.o \ - LibavProcessor.o FxPrinter.o\ + SampleVariable.o SampleInstrument.o SamplePool.o CommandList.o FxPrinter.o\ PersistencyService.o Persistent.o \ Observable.o SingletonRegistry.o \ Audio.o AudioMixer.o AudioOutDriver.o AudioDriver.o \ @@ -276,6 +275,12 @@ COMMONFILES := \ HexBuffers.o lz.o \ tinyxmlparser.o tinyxml.o tinyxmlerror.o tinystr.o Tiny2NosStub.o +ifneq ($(FFMPEG_ENABLED), 0) +ifneq ($(strip $(FFMPEG_LIBS)),) + COMMONFILES += LibavProcessor.o +endif +endif + #--------------------------------------------------------------------------------- # Linux #--------------------------------------------------------------------------------- diff --git a/projects/Makefile.GARLICPLUS b/projects/Makefile.GARLICPLUS index 72ce69c4..008de35a 100644 --- a/projects/Makefile.GARLICPLUS +++ b/projects/Makefile.GARLICPLUS @@ -9,7 +9,9 @@ DEFINES := \ -DCPP_MEMORY \ -D_NDEBUG \ -DHAVE_STDINT_H \ - -D_NO_JACK_ + -D_NO_JACK_ \ + -DFFMPEG_ENABLED + # compiled using the https://github.com/shauninman/union-rg35xxplus-toolchain @@ -23,13 +25,15 @@ SYSROOT := $(shell $(CROSS_COMPILE)gcc --print-sysroot) SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) SDL_LIBS := $(shell $(SYSROOT)/usr/bin/sdl-config --libs) +-include $(PWD)/rules_libav + # optimization OPT_FLAGS = -O3 -Ofast -fdata-sections -fdata-sections -fno-common -fno-PIC -flto -marm -mtune=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard PREFIX := arm-linux-gnueabihf- -INCLUDES = -Iinclude $(SDL_CFLAGS) -I$(PWD)/../sources +INCLUDES = -Iinclude $(SDL_CFLAGS) $(FFMPEG_CFLAGS) -I$(PWD)/../sources CFLAGS := $(DEFINES) $(INCLUDES) $(OPT_FLAGS) -Wall CXXFLAGS:= $(CFLAGS) -std=gnu++03 -LIBS := -lSDL -lpthread +LIBS := -lSDL -lpthread $(FFMPEG_LIBS) LIBDIRS := $(DEKVIT)/usr/lib LIBDIRS += $(DEKVIT)/usr/include OUTPUT = ../lgpt-garlicplus diff --git a/projects/Makefile.RG35XXPLUS b/projects/Makefile.RG35XXPLUS index dc04b211..09e0a131 100644 --- a/projects/Makefile.RG35XXPLUS +++ b/projects/Makefile.RG35XXPLUS @@ -24,11 +24,13 @@ TOOLPATH=$(DEVKIT)/usr/bin SDL_CFLAGS := -I/$(SYSROOT)/include -D_REENTRANT SDL_LIBS := -lSDL2 +-include $(PWD)/rules_libav + OPT_FLAGS = -O3 -mlittle-endian -mabi=lp64 -march=armv8-a+crypto+crc -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -dumpbase -INCLUDES = -Iinclude $(SDL_CFLAGS) -I$(DEVKIT)/$(TRIPLET)/include -I$(DEVKIT)/$(TRIPLET)/include/c++/11/ -I$(PWD)/../sources +INCLUDES = -Iinclude $(SDL_CFLAGS) $(FFMPEG_CFLAGS) -I$(DEVKIT)/$(TRIPLET)/include -I$(DEVKIT)/$(TRIPLET)/include/c++/11/ -I$(PWD)/../sources CFLAGS := $(DEFINES) $(INCLUDES) $(OPT_FLAGS) -Wall CXXFLAGS:= $(CFLAGS) -std=gnu++03 -LIBS := -Wl,-rpath-link,$(DEVKIT)/$(TRIPLET)/lib -Wl,-rpath-link,$(DEVKIT)/$(TRIPLET)/lib/pulseaudio $(SDL_LIBS) -lpthread +LIBS := -Wl,-rpath-link,$(DEVKIT)/$(TRIPLET)/lib -Wl,-rpath-link,$(DEVKIT)/$(TRIPLET)/lib/pulseaudio $(SDL_LIBS) $(FFMPEG_LIBS) -lpthread OUTPUT = ../lgpt-rg35xxplus EXTENSION:= elf diff --git a/sources/Application/FX/FxPrinter.cpp b/sources/Application/FX/FxPrinter.cpp index 8e22aaa0..665a7f91 100644 --- a/sources/Application/FX/FxPrinter.cpp +++ b/sources/Application/FX/FxPrinter.cpp @@ -62,6 +62,7 @@ bool FxPrinter::Run() { // Are we overwriting an already imported sample? bool imported = SamplePool::GetInstance()->IsImported(fo_); parseCommand(); +#ifdef FFMPEG_ENABLED if (encode(fiPath_.c_str(), ir_.c_str(), foPath_.c_str(), irWet_, irPad_) == 0) { int newIndex = SamplePool::GetInstance()->Reassign(fo_, imported); instrument_->AssignSample(newIndex); @@ -72,4 +73,5 @@ bool FxPrinter::Run() { notificationResult_ = "Failed, check lgpt.log"; return false; } +#endif } diff --git a/sources/Application/FX/FxPrinter.h b/sources/Application/FX/FxPrinter.h index 0e5e3018..912fdae2 100644 --- a/sources/Application/FX/FxPrinter.h +++ b/sources/Application/FX/FxPrinter.h @@ -5,10 +5,12 @@ #include "Application/Instruments/SampleInstrument.h" #include "Application/Instruments/SamplePool.h" #include "Application/Views/ViewData.h" -#include "LibavProcessor.h" #include "System/FileSystem/FileSystem.h" #include #include +#ifdef FFMPEG_ENABLED +#include "LibavProcessor.h" +#endif class FxPrinter { public: From 9a87db733972b111c0bb262f775e77fb0804d028 Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Sun, 19 Oct 2025 00:56:14 +0200 Subject: [PATCH 04/17] Fix no return value in Run RG35xx is missing libavfilter required for porting Added visual confirmation of includes Fix build error in x86 --- projects/Makefile.RG35XXPLUS | 12 +++++++++++- projects/Makefile.X86 | 14 ++++++++++++-- projects/rules_libav | 5 ++++- sources/Application/FX/FxPrinter.cpp | 4 ++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/projects/Makefile.RG35XXPLUS b/projects/Makefile.RG35XXPLUS index 09e0a131..e9f647f7 100644 --- a/projects/Makefile.RG35XXPLUS +++ b/projects/Makefile.RG35XXPLUS @@ -24,7 +24,17 @@ TOOLPATH=$(DEVKIT)/usr/bin SDL_CFLAGS := -I/$(SYSROOT)/include -D_REENTRANT SDL_LIBS := -lSDL2 --include $(PWD)/rules_libav +FFMPEG_INCL= libavformat \ + libavfilter \ + libavcodec \ + libavutil \ + +LIBAV_PATH := aarch64-linux-gnu/include +FFMPEG_CFLAGS := -I$(DEVKIT)/$(LIBAV_PATH)/libavformat -I$(DEVKIT)/$(LIBAV_PATH)/libavfilter -I$(DEVKIT)/$(LIBAV_PATH)/libavcodec -I$(SYSROOT)/$(LIBAV_PATH)/libavutil +FFMPEG_LIBS := -lavformat -lavfilter -lavcodec -lavutil + +$(info FFMPEG_CFLAGS: $(FFMPEG_CFLAGS)) +$(info FFMPEG_LIBS: $(FFMPEG_LIBS)) OPT_FLAGS = -O3 -mlittle-endian -mabi=lp64 -march=armv8-a+crypto+crc -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -dumpbase INCLUDES = -Iinclude $(SDL_CFLAGS) $(FFMPEG_CFLAGS) -I$(DEVKIT)/$(TRIPLET)/include -I$(DEVKIT)/$(TRIPLET)/include/c++/11/ -I$(PWD)/../sources diff --git a/projects/Makefile.X86 b/projects/Makefile.X86 index 4c8b3b86..8255db5e 100644 --- a/projects/Makefile.X86 +++ b/projects/Makefile.X86 @@ -11,21 +11,31 @@ DEFINES := \ -DRTMIDI \ -DFFMPEG_ENABLED +FFMPEG_INCL= libavformat \ + libavfilter \ + libavcodec \ + libavutil \ + ALSA_CFLAGS := $(shell i686-linux-gnu-pkg-config alsa --cflags) ALSA_LIBS := $(shell i686-linux-gnu-pkg-config alsa --libs) JACK_CFLAGS := $(shell i686-linux-gnu-pkg-config jack --cflags) JACK_LIBS := $(shell i686-linux-gnu-pkg-config jack --libs) SDL_CFLAGS := $(shell i686-linux-gnu-pkg-config sdl2 --cflags) SDL_LIBS := $(shell i686-linux-gnu-pkg-config sdl2 --libs) +FFMPEG_CFLAGS := $(shell i686-linux-gnu-pkg-config $(FFMPEG_INCL) --cflags) +FFMPEG_LIBS := $(shell i686-linux-gnu-pkg-config $(FFMPEG_INCL) --libs) + +$(info FFMPEG_CFLAGS: $(FFMPEG_CFLAGS)) +$(info FFMPEG_LIBS: $(FFMPEG_LIBS)) # optimization OPT_FLAGS := -O3 -m32 #For debugging #OPT_FLAGS := -g -m32 -INCLUDES := $(ALSA_CFLAGS) $(JACK_CFLAGS) $(SDL_CFLAGS) -I$(PWD)/../sources +INCLUDES := $(ALSA_CFLAGS) $(JACK_CFLAGS) $(SDL_CFLAGS) $(FFMPEG_CFLAGS) -I$(PWD)/../sources CFLAGS := $(OPT_FLAGS) $(DEFINES) $(INCLUDES) -Wall CXXFLAGS := $(CFLAGS) -LIBS := $(ALSA_LIBS) $(JACK_LIBS) $(SDL_LIBS) +LIBS := $(ALSA_LIBS) $(JACK_LIBS) $(SDL_LIBS) $(FFMPEG_LIBS) LDFLAGS := -m32 OUTPUT = ../lgpt EXTENSION := x86 diff --git a/projects/rules_libav b/projects/rules_libav index 9c577791..e8876171 100644 --- a/projects/rules_libav +++ b/projects/rules_libav @@ -10,4 +10,7 @@ FFMPEG_LIBS := $(shell $(DEVKIT)/bin/pkg-config --libs $(FFMPEG_INCL)) else FFMPEG_CFLAGS := $(shell pkg-config --cflags $(FFMPEG_INCL)) FFMPEG_LIBS := $(shell pkg-config --libs $(FFMPEG_INCL)) -endif \ No newline at end of file +endif + +$(info FFMPEG_CFLAGS: $(FFMPEG_CFLAGS)) +$(info FFMPEG_LIBS: $(FFMPEG_LIBS)) diff --git a/sources/Application/FX/FxPrinter.cpp b/sources/Application/FX/FxPrinter.cpp index 665a7f91..40b3b368 100644 --- a/sources/Application/FX/FxPrinter.cpp +++ b/sources/Application/FX/FxPrinter.cpp @@ -73,5 +73,9 @@ bool FxPrinter::Run() { notificationResult_ = "Failed, check lgpt.log"; return false; } +#else + Trace::Log("PRINTFX", "Failed"); + notificationResult_ = "Failed, check lgpt.log"; + return false; #endif } From 580f3486ac6d3c993cfae50a8f979d9209181926 Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Sun, 19 Oct 2025 19:47:20 +0200 Subject: [PATCH 05/17] Swap garlicplus toolchain --- .github/workflows/build.yml | 2 +- .github/workflows/check.yml | 2 +- projects/Makefile.GARLICPLUS | 11 ++++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9839b784..b329380b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -358,7 +358,7 @@ jobs: - name: Install Garlic Plus toolchain run: | sudo apt update && sudo apt install -y python3-pillow - wget -O /tmp/rg35xxplus-toolchain.tar.xz https://github.com/simotek/union-rg35xxplus-toolchain/releases/download/20240830/rg35xxplus-toolchain.tar.xz + wget -O /tmp/rg35xxplus-toolchain.tar.xz https://github.com/djdiskmachine/union-rg35xxplus-toolchain/releases/download/1.1/rg35xxplus-toolchain.tar.gz mkdir /opt/rg35xxplus-toolchain tar -xvf /tmp/rg35xxplus-toolchain.tar.xz -C /opt/rg35xxplus-toolchain --strip-components=1 diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index ec3fffa6..f416dfe6 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -292,7 +292,7 @@ jobs: - name: Install Garlic Plus toolchain run: | sudo apt update && sudo apt install -y python3-pillow - wget -O /tmp/rg35xxplus-toolchain.tar.xz https://github.com/simotek/union-rg35xxplus-toolchain/releases/download/20240830/rg35xxplus-toolchain.tar.xz + wget -O /tmp/rg35xxplus-toolchain.tar.xz https://github.com/djdiskmachine/union-rg35xxplus-toolchain/releases/download/1.1/rg35xxplus-toolchain.tar.gz mkdir /opt/rg35xxplus-toolchain tar -xvf /tmp/rg35xxplus-toolchain.tar.xz -C /opt/rg35xxplus-toolchain --strip-components=1 diff --git a/projects/Makefile.GARLICPLUS b/projects/Makefile.GARLICPLUS index 008de35a..4b2588a1 100644 --- a/projects/Makefile.GARLICPLUS +++ b/projects/Makefile.GARLICPLUS @@ -25,7 +25,16 @@ SYSROOT := $(shell $(CROSS_COMPILE)gcc --print-sysroot) SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) SDL_LIBS := $(shell $(SYSROOT)/usr/bin/sdl-config --libs) --include $(PWD)/rules_libav +FFMPEG_INCL= libavformat \ + libavfilter \ + libavcodec \ + libavutil \ + +FFMPEG_CFLAGS := $(shell $(DEVKIT)/usr/bin/pkg-config --cflags $(FFMPEG_INCL)) +FFMPEG_LIBS := $(shell $(DEVKIT)/usr/bin/pkg-config --libs $(FFMPEG_INCL)) + +$(info FFMPEG_CFLAGS: $(FFMPEG_CFLAGS)) +$(info FFMPEG_LIBS: $(FFMPEG_LIBS)) # optimization OPT_FLAGS = -O3 -Ofast -fdata-sections -fdata-sections -fno-common -fno-PIC -flto -marm -mtune=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard From e4b878a18ef93248bf92adf74baa6798dc194535 Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Sun, 19 Oct 2025 20:14:25 +0200 Subject: [PATCH 06/17] Add Win32 Removed Miyoo from targets Fix legacy ffmpeg for garlicplus Updated vcproj Update README table --- README.md | 35 +++++++++++++++++------------------ projects/Makefile.GARLICPLUS | 3 ++- projects/Makefile.MIYOO | 7 ++----- projects/lgpt.vcproj | 16 ++++++++++++---- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index ce6d7ee7..a8492d1d 100644 --- a/README.md +++ b/README.md @@ -40,25 +40,24 @@ Recommended reading to get you started: ## Features per platform -| Platform | MIDI_Possible | MIDI_enabled | Soundfonts | Note | -|-------------|---------------|--------------|------------|--------------------------------------| -| PSP | NO | NO | YES | [See notes](projects/resources/PSP/INSTALL_HOW_TO.txt) | -| DEB | YES | YES | YES | | -| X64 | YES | YES | NO | | -| X86 | YES | YES | YES | | -| STEAM | YES | YES | NO | | -| MIYOO | NO | NO | YES | Port by [Nine-H](https://ninethehacker.xyz) | -| W32 | YES | YES | YES | Built in VS2008 with love | -| RASPI | YES | YES | YES | Versatile platform | -| CHIP | YES | YES | YES | [See notes](projects/resources/CHIP/INSTALL_HOW_TO.txt) | -| BITTBOY | MAYBE | NO | YES | | -| GARLIC | MAYBE | NO | YES | Port by [Simotek](http://simotek.net)| -| GARLICPLUS | MAYBE | NO | YES | Port by [Simotek](http://simotek.net)| -| RG35XXPLUS | MAYBE | NO | YES | Port by [Simotek](http://simotek.net)| -| MACOS | YES | YES | NO | Port by [clsource](https://genserver.social/clsource) | - +| Platform | MIDI_Possible | MIDI_enabled | Soundfonts | PrintFX | Note | +|-------------|---------------|--------------|------------|---------|--------------------------------------| +| PSP | NO | NO | YES | NO | [See notes](projects/resources/PSP/INSTALL_HOW_TO.txt) | +| DEB | YES | YES | YES | YES | | +| X64 | YES | YES | NO | YES | | +| X86 | YES | YES | YES | YES | | +| STEAM | YES | YES | NO | YES | | +| MIYOO | NO | NO | YES | NO | Port by [Nine-H](https://ninethehacker.xyz) | +| W32 | YES | YES | YES | YES | Built in VS2008 with love | +| RASPI | YES | YES | YES | YES | Versatile platform | +| CHIP | YES | YES | YES | YES | [See notes](projects/resources/CHIP/INSTALL_HOW_TO.txt) | +| BITTBOY | MAYBE | NO | YES | YES | | +| GARLIC | MAYBE | NO | YES | YES | Port by [Simotek](http://simotek.net)| +| GARLICPLUS | MAYBE | NO | YES | YES | Port by [Simotek](http://simotek.net)| +| RG35XXPLUS | MAYBE | NO | YES | NO | Port by [Simotek](http://simotek.net)| +| MACOS | YES | YES | NO | NO | Port by [clsource](https://genserver.social/clsource) | * **Soundfont library is currently not ported for 64bit OS** * **MIDI functionality __greatly__ depends on kernel support, please feature request your favourite OS maintainer =)** * **Install ffmpeg by following install instructions for your platform [here](https://www.ffmpeg.org/download.html)** -* **PrintFX requires full ffmpeg. If marked as TBA, it requires a redesign using [libav](https://trac.ffmpeg.org/wiki/Using%20libav*)** +* **PrintFX requires toolchain support of ffmpeg libs, for all targets marked maybe contact the maintainer of your consoles toolchain** diff --git a/projects/Makefile.GARLICPLUS b/projects/Makefile.GARLICPLUS index 4b2588a1..51b588d3 100644 --- a/projects/Makefile.GARLICPLUS +++ b/projects/Makefile.GARLICPLUS @@ -10,7 +10,8 @@ DEFINES := \ -D_NDEBUG \ -DHAVE_STDINT_H \ -D_NO_JACK_ \ - -DFFMPEG_ENABLED + -DFFMPEG_ENABLED \ + -DFFMPEG_LEGACY_API # compiled using the https://github.com/shauninman/union-rg35xxplus-toolchain diff --git a/projects/Makefile.MIYOO b/projects/Makefile.MIYOO index e36bda73..759de6cf 100644 --- a/projects/Makefile.MIYOO +++ b/projects/Makefile.MIYOO @@ -6,7 +6,6 @@ DEFINES := \ -DCPP_MEMORY \ -DHAVE_STDINT_H \ -D_NDEBUG \ - -DFFMPEG_ENABLED \ -D_NO_JACK_ DEVKIT = /opt/miyoomini-toolchain/ @@ -19,17 +18,15 @@ SYSROOT := $(shell $(CROSS_COMPILE)gcc --print-sysroot) SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) SDL_LIBS := $(shell $(SYSROOT)/usr/bin/sdl-config --libs) -INCLUDES = -Iinclude $(SDL_CFLAGS) $(FFMPEG_CFLAGS) -I$(PWD)/../sources +INCLUDES = -Iinclude $(SDL_CFLAGS) -I$(PWD)/../sources OPT_FLAGS = -O3 -Ofast -fdata-sections -fdata-sections -fno-common -fno-PIC -flto -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve+simd --include $(PWD)/rules_libav - TOOLPATH=$(DEVKIT)/usr/bin PREFIX := arm-linux-gnueabihf- CFLAGS := $(DEFINES) $(INCLUDES) $(SDL_CFLAGS) $(OPT_FLAGS) -Wall CXXFLAGS:= $(CFLAGS) -std=gnu++03 -LIBS := -lSDL -lSDL_mixer -lpthread $(SDL_LIBS) $(FFMPEG_LIBS) +LIBS := -lSDL -lSDL_mixer -lpthread $(SDL_LIBS) LIBDIRS := $(DEKVIT)/usr/lib LIBDIRS += $(DEKVIT)/usr/include OUTPUT = ../lgpt-miyoo diff --git a/projects/lgpt.vcproj b/projects/lgpt.vcproj index d50935b8..30d70204 100644 --- a/projects/lgpt.vcproj +++ b/projects/lgpt.vcproj @@ -43,7 +43,7 @@ AdditionalOptions="/MP" Optimization="0" AdditionalIncludeDirectories="../sources/Externals;../sources/" - PreprocessorDefinitions="WIN32;_DEBUG;__WINDOWS_DS__;__WINDOWS_ASIO__;_CRT_SECURE_NO_WARNINGS;__WINDOWS_MM__;CPP_MEMORY;_LGPT_NO_SCREEN_CACHE_" + PreprocessorDefinitions="WIN32;_DEBUG;__WINDOWS_DS__;__WINDOWS_ASIO__;_CRT_SECURE_NO_WARNINGS;__WINDOWS_MM__;CPP_MEMORY;_LGPT_NO_SCREEN_CACHE_;FFMPEG_ENABLED;FFMPEG_LEGACY_API" MinimalRebuild="false" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -65,7 +65,7 @@ + + + + Date: Sun, 19 Oct 2025 20:28:14 +0200 Subject: [PATCH 07/17] Bump project number --- sources/Application/Model/Project.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/Application/Model/Project.h b/sources/Application/Model/Project.h index 6c347642..33829259 100644 --- a/sources/Application/Model/Project.h +++ b/sources/Application/Model/Project.h @@ -19,8 +19,8 @@ #define VAR_SCALE MAKE_FOURCC('S', 'C', 'A', 'L') #define PROJECT_NUMBER "1" -#define PROJECT_RELEASE "5" -#define BUILD_COUNT "0-bacon2" +#define PROJECT_RELEASE "6" +#define BUILD_COUNT "0-bacon0" #define MAX_TAP 3 From fd49f8cdfc294f155632e3a99e5babea6352f31e Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Sun, 19 Oct 2025 20:39:09 +0200 Subject: [PATCH 08/17] FFMPEG deps for Win32 --- .github/workflows/check.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index f416dfe6..e882f642 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -63,6 +63,13 @@ jobs: run: choco install -y directx-sdk zip ffmpeg-shared --no-progress --yes shell: powershell + - name: Install FFmpeg development libraries via vcpkg + run: | + git clone https://github.com/Microsoft/vcpkg.git C:\vcpkg + C:\vcpkg\bootstrap-vcpkg.bat + C:\vcpkg\vcpkg.exe install ffmpeg[avcodec,avformat,avfilter,avutil]:x86-windows-static + shell: cmd + - name: Download and Extract VCE9 release run: | $url = "https://github.com/djdiskmachine/VCE9/releases/download/v1.0.0/Microsoft.Visual.Studio.9.0.zip" From adbb530c295df2d20d71ef10abd59636609f5dd3 Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Sun, 19 Oct 2025 20:59:56 +0200 Subject: [PATCH 09/17] vcpkg installation ffmpeg --- .github/workflows/check.yml | 8 +++----- projects/lgpt.vcproj | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index e882f642..04881628 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -62,12 +62,10 @@ jobs: - name: Install build deps run: choco install -y directx-sdk zip ffmpeg-shared --no-progress --yes shell: powershell - - - name: Install FFmpeg development libraries via vcpkg + + - name: Install FFmpeg run: | - git clone https://github.com/Microsoft/vcpkg.git C:\vcpkg - C:\vcpkg\bootstrap-vcpkg.bat - C:\vcpkg\vcpkg.exe install ffmpeg[avcodec,avformat,avfilter,avutil]:x86-windows-static + vcpkg install ffmpeg[avcodec,avformat,avfilter,avutil]:x86-windows-static shell: cmd - name: Download and Extract VCE9 release diff --git a/projects/lgpt.vcproj b/projects/lgpt.vcproj index 30d70204..fb7deefc 100644 --- a/projects/lgpt.vcproj +++ b/projects/lgpt.vcproj @@ -42,7 +42,7 @@ Name="VCCLCompilerTool" AdditionalOptions="/MP" Optimization="0" - AdditionalIncludeDirectories="../sources/Externals;../sources/" + AdditionalIncludeDirectories="../sources/Externals;../sources/;C:\vcpkg\installed\x86-windows-static\include" PreprocessorDefinitions="WIN32;_DEBUG;__WINDOWS_DS__;__WINDOWS_ASIO__;_CRT_SECURE_NO_WARNINGS;__WINDOWS_MM__;CPP_MEMORY;_LGPT_NO_SCREEN_CACHE_;FFMPEG_ENABLED;FFMPEG_LEGACY_API" MinimalRebuild="false" BasicRuntimeChecks="3" @@ -125,7 +125,7 @@ Date: Sun, 19 Oct 2025 21:26:14 +0200 Subject: [PATCH 10/17] libav install fix --- .github/workflows/check.yml | 5 ++--- projects/lgpt.vcproj | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 04881628..0fc8e278 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -63,9 +63,8 @@ jobs: run: choco install -y directx-sdk zip ffmpeg-shared --no-progress --yes shell: powershell - - name: Install FFmpeg - run: | - vcpkg install ffmpeg[avcodec,avformat,avfilter,avutil]:x86-windows-static + - name: Install FFmpeg development libraries + run: vcpkg install ffmpeg[avcodec,avformat,avfilter]:x86-windows-static shell: cmd - name: Download and Extract VCE9 release diff --git a/projects/lgpt.vcproj b/projects/lgpt.vcproj index fb7deefc..6439789c 100644 --- a/projects/lgpt.vcproj +++ b/projects/lgpt.vcproj @@ -68,7 +68,7 @@ AdditionalDependencies="sdlmain.lib sdl.lib winmm.lib dsound.lib SDL_image.lib avformat.lib avcodec.lib avutil.lib avfilter.lib" OutputFile="$(OutDir)/lgptd.exe" LinkIncremental="2" - AdditionalLibraryDirectories="../libs/WSDL" + AdditionalLibraryDirectories="../libs/WSDL;C:\vcpkg\installed\x86-windows-static\lib" IgnoreDefaultLibraryNames="msvcrt.lib" GenerateDebugInformation="true" ProgramDatabaseFile="$(OutDir)/lgpt.pdb" @@ -148,7 +148,7 @@ AdditionalDependencies="sdlmain-release.lib sdl-release.lib winmm.lib dsound.lib avformat.lib avcodec.lib avutil.lib avfilter.lib" OutputFile="$(OutDir)/lgpt-W32.exe" LinkIncremental="1" - AdditionalLibraryDirectories="../libs/WSDL" + AdditionalLibraryDirectories="../libs/WSDL;C:\vcpkg\installed\x86-windows-static\lib" GenerateManifest="false" IgnoreDefaultLibraryNames="" GenerateDebugInformation="false" From f5d2bf8cff0ee1c29e3227710a3e2edfd77aa920 Mon Sep 17 00:00:00 2001 From: djdiskmachine <110535302+djdiskmachine@users.noreply.github.com> Date: Thu, 23 Oct 2025 15:20:01 +0000 Subject: [PATCH 11/17] Update miyoo toolchain & add back ffmpeg --- .github/workflows/check.yml | 2 +- projects/Makefile.MIYOO | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 0fc8e278..cd7c1478 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -364,7 +364,7 @@ jobs: - name: Install Miyoo Mini toolchain run: | sudo apt update && sudo apt install -y python3-pillow - wget -O /tmp/miyoomini-toolchain.tar.xz https://github.com/djdiskmachine/miyoomini-toolchain-buildroot/releases/download/1.0.0/miyoomini-toolchain.tar.xz + wget -O /tmp/miyoomini-toolchain.tar.xz https://github.com/djdiskmachine/miyoomini-toolchain-buildroot/releases/download/1.1/miyoomini-toolchain.tar.xz mkdir /opt/miyoomini-toolchain tar -xvf /tmp/miyoomini-toolchain.tar.xz -C /opt/miyoomini-toolchain --strip-components=1 diff --git a/projects/Makefile.MIYOO b/projects/Makefile.MIYOO index 759de6cf..e36bda73 100644 --- a/projects/Makefile.MIYOO +++ b/projects/Makefile.MIYOO @@ -6,6 +6,7 @@ DEFINES := \ -DCPP_MEMORY \ -DHAVE_STDINT_H \ -D_NDEBUG \ + -DFFMPEG_ENABLED \ -D_NO_JACK_ DEVKIT = /opt/miyoomini-toolchain/ @@ -18,15 +19,17 @@ SYSROOT := $(shell $(CROSS_COMPILE)gcc --print-sysroot) SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) SDL_LIBS := $(shell $(SYSROOT)/usr/bin/sdl-config --libs) -INCLUDES = -Iinclude $(SDL_CFLAGS) -I$(PWD)/../sources +INCLUDES = -Iinclude $(SDL_CFLAGS) $(FFMPEG_CFLAGS) -I$(PWD)/../sources OPT_FLAGS = -O3 -Ofast -fdata-sections -fdata-sections -fno-common -fno-PIC -flto -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve+simd +-include $(PWD)/rules_libav + TOOLPATH=$(DEVKIT)/usr/bin PREFIX := arm-linux-gnueabihf- CFLAGS := $(DEFINES) $(INCLUDES) $(SDL_CFLAGS) $(OPT_FLAGS) -Wall CXXFLAGS:= $(CFLAGS) -std=gnu++03 -LIBS := -lSDL -lSDL_mixer -lpthread $(SDL_LIBS) +LIBS := -lSDL -lSDL_mixer -lpthread $(SDL_LIBS) $(FFMPEG_LIBS) LIBDIRS := $(DEKVIT)/usr/lib LIBDIRS += $(DEKVIT)/usr/include OUTPUT = ../lgpt-miyoo From b0b8325a847846142a569d8bab14e6cb688db45d Mon Sep 17 00:00:00 2001 From: djdiskmachine <110535302+djdiskmachine@users.noreply.github.com> Date: Fri, 24 Oct 2025 05:20:06 +0000 Subject: [PATCH 12/17] Fix includes for miyoo --- .github/workflows/check.yml | 2 +- projects/Makefile.MIYOO | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index cd7c1478..8236221e 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -370,7 +370,7 @@ jobs: - name: Build Miyoo Mini working-directory: projects - run: | + run: | make PLATFORM=MIYOO - name: Package build diff --git a/projects/Makefile.MIYOO b/projects/Makefile.MIYOO index e36bda73..90f00aef 100644 --- a/projects/Makefile.MIYOO +++ b/projects/Makefile.MIYOO @@ -19,11 +19,21 @@ SYSROOT := $(shell $(CROSS_COMPILE)gcc --print-sysroot) SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) SDL_LIBS := $(shell $(SYSROOT)/usr/bin/sdl-config --libs) +FFMPEG_INCL= libavformat \ + libavfilter \ + libavcodec \ + libavutil \ + +LIBAV_PATH := arm-linux-gnueabihf/libc/usr/include +FFMPEG_CFLAGS := -I$(DEVKIT)/$(LIBAV_PATH)/libavformat -I$(DEVKIT)/$(LIBAV_PATH)/libavfilter -I$(DEVKIT)/$(LIBAV_PATH)/libavcodec -I$(SYSROOT)/$(LIBAV_PATH)/libavutil +FFMPEG_LIBS := -lavformat -lavfilter -lavcodec -lavutil + +$(info FFMPEG_CFLAGS: $(FFMPEG_CFLAGS)) +$(info FFMPEG_LIBS: $(FFMPEG_LIBS)) + INCLUDES = -Iinclude $(SDL_CFLAGS) $(FFMPEG_CFLAGS) -I$(PWD)/../sources OPT_FLAGS = -O3 -Ofast -fdata-sections -fdata-sections -fno-common -fno-PIC -flto -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve+simd --include $(PWD)/rules_libav - TOOLPATH=$(DEVKIT)/usr/bin PREFIX := arm-linux-gnueabihf- From a1f451f1174279d7204dcc5687d659c0cd7ee5f2 Mon Sep 17 00:00:00 2001 From: djdiskmachine <110535302+djdiskmachine@users.noreply.github.com> Date: Fri, 24 Oct 2025 05:26:52 +0000 Subject: [PATCH 13/17] Fix check.ym --- .github/workflows/check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 8236221e..cd7c1478 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -370,7 +370,7 @@ jobs: - name: Build Miyoo Mini working-directory: projects - run: | + run: | make PLATFORM=MIYOO - name: Package build From 8cfb07fd311a2566e1fc5d184a50e5161654cdaa Mon Sep 17 00:00:00 2001 From: djdiskmachine <110535302+djdiskmachine@users.noreply.github.com> Date: Fri, 24 Oct 2025 07:43:29 +0200 Subject: [PATCH 14/17] Add FFMPEG_LEGACY_API to Makefile.MIYOO --- projects/Makefile.MIYOO | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/Makefile.MIYOO b/projects/Makefile.MIYOO index 90f00aef..6e127b27 100644 --- a/projects/Makefile.MIYOO +++ b/projects/Makefile.MIYOO @@ -7,6 +7,7 @@ DEFINES := \ -DHAVE_STDINT_H \ -D_NDEBUG \ -DFFMPEG_ENABLED \ + -DFFMPEG_LEGACY_API \ -D_NO_JACK_ DEVKIT = /opt/miyoomini-toolchain/ From c8cc287eaed7220ef285b9279eb60917b7ce456b Mon Sep 17 00:00:00 2001 From: djdiskmachine Date: Fri, 24 Oct 2025 19:50:46 +0200 Subject: [PATCH 15/17] vs2008->vs2019 --- .github/workflows/check.yml | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index cd7c1478..c920b44e 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -67,30 +67,11 @@ jobs: run: vcpkg install ffmpeg[avcodec,avformat,avfilter]:x86-windows-static shell: cmd - - name: Download and Extract VCE9 release - run: | - $url = "https://github.com/djdiskmachine/VCE9/releases/download/v1.0.0/Microsoft.Visual.Studio.9.0.zip" - $destination = "C:\Program Files (x86)\" - New-Item -ItemType Directory -Force -Path $destination | Out-Null - Invoke-WebRequest -Uri $url -OutFile "$env:TEMP\VCE9.zip" - Expand-Archive -Path "$env:TEMP\VCE9.zip" -DestinationPath $destination -Force - shell: pwsh - - - name: Install Visual Studio 2008 Express - run: | - Invoke-WebRequest -Uri "http://download.microsoft.com/download/8/B/5/8B5804AD-4990-40D0-A6AA-CE894CBBB3DC/VS2008ExpressENUX1397868.iso" -OutFile "$env:GITHUB_WORKSPACE\VS2008ExpressENUX1397868.iso" - $mountResult = Mount-DiskImage -ImagePath "$env:GITHUB_WORKSPACE\VS2008ExpressENUX1397868.iso" -PassThru - $driveLetter = ($mountResult | Get-Volume).DriveLetter - Write-Host "ISO mounted to drive letter $driveLetter" - $driveLetter = (Get-DiskImage -ImagePath "$env:GITHUB_WORKSPACE\VS2008ExpressENUX1397868.iso" | Get-Volume).DriveLetter - Start-Process -FilePath "${driveLetter}:\VCExpress\setup.exe" -ArgumentList '/q', '/norestart' -Wait - shell: pwsh - - name: Build Solution working-directory: projects run: | - & "C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat" - & "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcpackages\vcbuild.exe" "lgpt.sln" "Release|Win32" + & "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x86 + & msbuild "lgpt.sln" /p:Configuration=Release /p:Platform=Win32 shell: pwsh - name: Package build From eb02d731de72abfffa3fdd610aa5aafe24534b97 Mon Sep 17 00:00:00 2001 From: djdiskmachine <110535302+djdiskmachine@users.noreply.github.com> Date: Fri, 31 Oct 2025 16:05:17 +0000 Subject: [PATCH 16/17] Logging and redundancy removal in LibavProcessor.c Make LibavProcessor errors more obvious Remove unnecessary channel forcing in libav parser Fix typo in makefiles Logging in rules file restore vs2008 build --- .github/workflows/check.yml | 23 +++++++- projects/Makefile.BITTBOY | 2 +- projects/Makefile.MIYOO | 17 +++--- projects/rules_libav | 2 +- sources/Application/FX/LibavProcessor.c | 72 ++++++++++++------------- 5 files changed, 64 insertions(+), 52 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index c920b44e..cd7c1478 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -67,11 +67,30 @@ jobs: run: vcpkg install ffmpeg[avcodec,avformat,avfilter]:x86-windows-static shell: cmd + - name: Download and Extract VCE9 release + run: | + $url = "https://github.com/djdiskmachine/VCE9/releases/download/v1.0.0/Microsoft.Visual.Studio.9.0.zip" + $destination = "C:\Program Files (x86)\" + New-Item -ItemType Directory -Force -Path $destination | Out-Null + Invoke-WebRequest -Uri $url -OutFile "$env:TEMP\VCE9.zip" + Expand-Archive -Path "$env:TEMP\VCE9.zip" -DestinationPath $destination -Force + shell: pwsh + + - name: Install Visual Studio 2008 Express + run: | + Invoke-WebRequest -Uri "http://download.microsoft.com/download/8/B/5/8B5804AD-4990-40D0-A6AA-CE894CBBB3DC/VS2008ExpressENUX1397868.iso" -OutFile "$env:GITHUB_WORKSPACE\VS2008ExpressENUX1397868.iso" + $mountResult = Mount-DiskImage -ImagePath "$env:GITHUB_WORKSPACE\VS2008ExpressENUX1397868.iso" -PassThru + $driveLetter = ($mountResult | Get-Volume).DriveLetter + Write-Host "ISO mounted to drive letter $driveLetter" + $driveLetter = (Get-DiskImage -ImagePath "$env:GITHUB_WORKSPACE\VS2008ExpressENUX1397868.iso" | Get-Volume).DriveLetter + Start-Process -FilePath "${driveLetter}:\VCExpress\setup.exe" -ArgumentList '/q', '/norestart' -Wait + shell: pwsh + - name: Build Solution working-directory: projects run: | - & "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x86 - & msbuild "lgpt.sln" /p:Configuration=Release /p:Platform=Win32 + & "C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat" + & "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcpackages\vcbuild.exe" "lgpt.sln" "Release|Win32" shell: pwsh - name: Package build diff --git a/projects/Makefile.BITTBOY b/projects/Makefile.BITTBOY index 165fc21f..067ce5fc 100644 --- a/projects/Makefile.BITTBOY +++ b/projects/Makefile.BITTBOY @@ -32,7 +32,7 @@ INCLUDES = -I$(PWD)/../sources -Iinclude $(SDL_CFLAGS) $(FFMPEG_CFLAGS) CFLAGS := $(DEFINES) $(INCLUDES) $(OPT_FLAGS) $(SDL_CFLAGS) -Wall -DRS97 CXXFLAGS:= $(CFLAGS) -std=gnu++03 LIBS := $(SDL_LIBS) -lSDL -lSDL_mixer -lasound -lpthread $(FFMPEG_LIBS) -LIBDIRS := $(DEKVIT)/usr/lib +LIBDIRS := $(SYSROOT)/usr/lib OUTPUT = ../lgpt-bittboy EXTENSION:= elf diff --git a/projects/Makefile.MIYOO b/projects/Makefile.MIYOO index 6e127b27..9567f158 100644 --- a/projects/Makefile.MIYOO +++ b/projects/Makefile.MIYOO @@ -7,7 +7,7 @@ DEFINES := \ -DHAVE_STDINT_H \ -D_NDEBUG \ -DFFMPEG_ENABLED \ - -DFFMPEG_LEGACY_API \ + -DFFMPEG_LEGACY_API \ -D_NO_JACK_ DEVKIT = /opt/miyoomini-toolchain/ @@ -20,13 +20,12 @@ SYSROOT := $(shell $(CROSS_COMPILE)gcc --print-sysroot) SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) SDL_LIBS := $(shell $(SYSROOT)/usr/bin/sdl-config --libs) -FFMPEG_INCL= libavformat \ - libavfilter \ - libavcodec \ - libavutil \ - LIBAV_PATH := arm-linux-gnueabihf/libc/usr/include -FFMPEG_CFLAGS := -I$(DEVKIT)/$(LIBAV_PATH)/libavformat -I$(DEVKIT)/$(LIBAV_PATH)/libavfilter -I$(DEVKIT)/$(LIBAV_PATH)/libavcodec -I$(SYSROOT)/$(LIBAV_PATH)/libavutil +FFMPEG_CFLAGS := -I$(DEVKIT)/$(LIBAV_PATH)/libavformat \ + -I$(DEVKIT)/$(LIBAV_PATH)/libavfilter \ + -I$(DEVKIT)/$(LIBAV_PATH)/libavcodec \ + -I$(DEVKIT)/$(LIBAV_PATH)/libavutil \ + FFMPEG_LIBS := -lavformat -lavfilter -lavcodec -lavutil $(info FFMPEG_CFLAGS: $(FFMPEG_CFLAGS)) @@ -41,8 +40,8 @@ PREFIX := arm-linux-gnueabihf- CFLAGS := $(DEFINES) $(INCLUDES) $(SDL_CFLAGS) $(OPT_FLAGS) -Wall CXXFLAGS:= $(CFLAGS) -std=gnu++03 LIBS := -lSDL -lSDL_mixer -lpthread $(SDL_LIBS) $(FFMPEG_LIBS) -LIBDIRS := $(DEKVIT)/usr/lib -LIBDIRS += $(DEKVIT)/usr/include +LIBDIRS := $(DEVKIT)/usr/lib +LIBDIRS += $(DEVKIT)/usr/include OUTPUT = ../lgpt-miyoo EXTENSION:= elf diff --git a/projects/rules_libav b/projects/rules_libav index e8876171..b96ad7f7 100644 --- a/projects/rules_libav +++ b/projects/rules_libav @@ -3,7 +3,7 @@ FFMPEG_INCL= libavformat \ libavcodec \ libavutil \ -# Use SYSROOT for cross-compilation, fallback to system pkg-config for native builds +$(info SYSROOT: $(SYSROOT)) ifdef SYSROOT FFMPEG_CFLAGS := $(shell $(DEVKIT)/bin/pkg-config --cflags $(FFMPEG_INCL)) FFMPEG_LIBS := $(shell $(DEVKIT)/bin/pkg-config --libs $(FFMPEG_INCL)) diff --git a/sources/Application/FX/LibavProcessor.c b/sources/Application/FX/LibavProcessor.c index 8f0de6d2..44ca575e 100644 --- a/sources/Application/FX/LibavProcessor.c +++ b/sources/Application/FX/LibavProcessor.c @@ -30,19 +30,19 @@ static int open_input_file(const char *filename) int ret; if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Cannot open input file\n"); return ret; } if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Cannot find stream information\n"); return ret; } /* select the audio stream */ ret = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot find an audio stream in the input file\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Cannot find an audio stream in the input file\n"); return ret; } @@ -56,7 +56,7 @@ static int open_input_file(const char *filename) /* init the audio decoder */ if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot open audio decoder\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Cannot open audio decoder\n"); return ret; } @@ -83,19 +83,19 @@ static int open_ir_file(const char *filename) int ret; if ((ret = avformat_open_input(&ir_fmt_ctx, filename, NULL, NULL)) < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot open IR file\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Cannot open IR file\n"); return ret; } if ((ret = avformat_find_stream_info(ir_fmt_ctx, NULL)) < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot find stream information in IR file\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Cannot find stream information in IR file\n"); return ret; } /* select the audio stream */ ret = av_find_best_stream(ir_fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot find an audio stream in the IR file\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Cannot find an audio stream in the IR file\n"); return ret; } @@ -109,7 +109,7 @@ static int open_ir_file(const char *filename) /* init the audio decoder */ if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot open IR audio decoder\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Cannot open IR audio decoder\n"); return ret; } @@ -137,14 +137,14 @@ static int open_output_file(const char *filename) avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename); if (!ofmt_ctx) { - av_log(NULL, AV_LOG_ERROR, "Could not create output context\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not create output context\n"); return AVERROR_UNKNOWN; } in_stream = ifmt_ctx->streams[0]; out_stream = avformat_new_stream(ofmt_ctx, NULL); if (!out_stream) { - av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Failed allocating output stream\n"); return AVERROR_UNKNOWN; } @@ -197,12 +197,12 @@ static int open_output_file(const char *filename) /* Third parameter can be used to pass settings to encoder */ ret = avcodec_open2(enc_ctx, encoder, NULL); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Cannot open video encoder for stream\n"); return ret; } ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctx); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Failed to copy encoder parameters to output stream\n"); return ret; } @@ -214,7 +214,7 @@ static int open_output_file(const char *filename) if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) { ret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", filename); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not open output file '%s'", filename); return ret; } } @@ -222,7 +222,7 @@ static int open_output_file(const char *filename) /* init muxer, write output file header */ ret = avformat_write_header(ofmt_ctx, NULL); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Error occurred when opening output file\n"); return ret; } @@ -272,14 +272,14 @@ static int init_filters(int ir_wet, int ir_pad) /* buffer audio source: the decoded frames from the decoder will be inserted here. */ abuffer = avfilter_get_by_name("abuffer"); if (!abuffer) { - av_log(NULL, AV_LOG_ERROR, "Could not find the abuffer filter.\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not find the abuffer filter.\n"); ret = AVERROR_FILTER_NOT_FOUND; goto end; } buffersrc_ctx = avfilter_graph_alloc_filter(filter_graph, abuffer, "in"); if (!buffersrc_ctx) { - av_log(NULL, AV_LOG_ERROR, "Could not allocate the abuffer instance.\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not allocate the abuffer instance.\n"); ret = AVERROR(ENOMEM); goto end; } @@ -317,14 +317,14 @@ static int init_filters(int ir_wet, int ir_pad) ch_layout_str); ret = avfilter_init_str(buffersrc_ctx, args); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Could not initialize the abuffer filter.\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not initialize the abuffer filter.\n"); goto end; } /* buffer audio source for IR: the decoded IR frames will be inserted here. */ ir_buffersrc_ctx = avfilter_graph_alloc_filter(filter_graph, abuffer, "ir_in"); if (!ir_buffersrc_ctx) { - av_log(NULL, AV_LOG_ERROR, "Could not allocate the IR abuffer instance.\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not allocate the IR abuffer instance.\n"); ret = AVERROR(ENOMEM); goto end; } @@ -361,21 +361,21 @@ static int init_filters(int ir_wet, int ir_pad) ir_ch_layout_str); ret = avfilter_init_str(ir_buffersrc_ctx, ir_args); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Could not initialize the IR abuffer filter.\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not initialize the IR abuffer filter.\n"); goto end; } /* buffer audio sink: to terminate the filter chain. */ abuffersink = avfilter_get_by_name("abuffersink"); if (!abuffersink) { - av_log(NULL, AV_LOG_ERROR, "Could not find the abuffersink filter.\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not find the abuffersink filter.\n"); ret = AVERROR_FILTER_NOT_FOUND; goto end; } buffersink_ctx = avfilter_graph_alloc_filter(filter_graph, abuffersink, "out"); if (!buffersink_ctx) { - av_log(NULL, AV_LOG_ERROR, "Could not allocate the abuffersink instance.\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not allocate the abuffersink instance.\n"); ret = AVERROR(ENOMEM); goto end; } @@ -384,20 +384,14 @@ static int init_filters(int ir_wet, int ir_pad) static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 }; ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1, AV_OPT_SEARCH_CHILDREN); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n"); - goto end; - } - - ret = av_opt_set(buffersink_ctx, "ch_layouts", target_layout, AV_OPT_SEARCH_CHILDREN); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Cannot set output sample format\n"); goto end; } /* This filter takes no options. */ ret = avfilter_init_str(buffersink_ctx, NULL); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Could not initialize the abuffersink instance.\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not initialize the abuffersink instance.\n"); goto end; } @@ -514,7 +508,7 @@ static int filter_encode_write_frame(AVFrame *frame, AVFrame *ir_frame, unsigned if (frame) { ret = av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while feeding the input filtergraph\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Error while feeding the input filtergraph\n"); return ret; } } @@ -522,7 +516,7 @@ static int filter_encode_write_frame(AVFrame *frame, AVFrame *ir_frame, unsigned if (ir_frame) { ret = av_buffersrc_add_frame_flags(ir_buffersrc_ctx, ir_frame, AV_BUFFERSRC_FLAG_KEEP_REF); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while feeding the IR filtergraph\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Error while feeding the IR filtergraph\n"); return ret; } } @@ -623,7 +617,7 @@ int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad) ret = av_buffersrc_add_frame_flags(ir_buffersrc_ctx, ir_frame, AV_BUFFERSRC_FLAG_KEEP_REF); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while feeding the IR filtergraph\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Error while feeding the IR filtergraph\n"); goto end; } ir_loaded = 1; @@ -635,7 +629,7 @@ int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad) /* Signal end of IR stream */ ret = av_buffersrc_add_frame_flags(ir_buffersrc_ctx, NULL, 0); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error closing IR filtergraph\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Error closing IR filtergraph\n"); goto end; } @@ -659,7 +653,7 @@ int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad) ret = av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while feeding the input filtergraph\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Error while feeding the input filtergraph\n"); goto end; } /* Pull filtered frames immediately */ @@ -692,21 +686,21 @@ int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad) /* flush the filter graph by sending EOF to input sources */ ret = av_buffersrc_add_frame_flags(buffersrc_ctx, NULL, 0); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error while closing the input filtergraph\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Error while closing the input filtergraph\n"); goto end; } /* Pull any remaining frames from the filter graph */ ret = filter_encode_write_frame(NULL, NULL, 0); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Flushing filter failed\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Flushing filter failed\n"); goto end; } /* flush the encoder */ ret = avcodec_send_frame(enc_ctx, NULL); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error sending NULL frame to encoder\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Error sending NULL frame to encoder\n"); goto end; } @@ -718,7 +712,7 @@ int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad) break; } else if (ret < 0) { av_packet_free(&enc_pkt); - av_log(NULL, AV_LOG_ERROR, "Error during encoder flush\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Error during encoder flush\n"); goto end; } @@ -727,7 +721,7 @@ int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad) ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt); av_packet_free(&enc_pkt); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error writing final packet\n"); + av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Error writing final packet\n"); goto end; } } From a7b496c4cee3ce8b0828ba3badf416962882f46f Mon Sep 17 00:00:00 2001 From: djdiskmachine <110535302+djdiskmachine@users.noreply.github.com> Date: Sun, 21 Dec 2025 22:04:35 +0000 Subject: [PATCH 17/17] Fix unallocated crash, segmentation fault --- sources/Application/FX/FxPrinter.cpp | 2 +- sources/Application/FX/LibavProcessor.c | 76 +++++++++++++------ .../Instruments/SampleInstrument.cpp | 11 +++ .../Instruments/SampleInstrument.h | 16 ++-- 4 files changed, 73 insertions(+), 32 deletions(-) diff --git a/sources/Application/FX/FxPrinter.cpp b/sources/Application/FX/FxPrinter.cpp index 40b3b368..cdf7426c 100644 --- a/sources/Application/FX/FxPrinter.cpp +++ b/sources/Application/FX/FxPrinter.cpp @@ -16,7 +16,7 @@ void FxPrinter::setParams() { } void FxPrinter::setPaths() { - fi_ = std::string(instrument_->GetName()); + fi_ = std::string(instrument_->GetFullName()); fiPath_ = samples_dir.GetPath() + '/' + fi_; fo_ = fi_.substr(0, fi_.find_last_of('.')) + "_.wav"; diff --git a/sources/Application/FX/LibavProcessor.c b/sources/Application/FX/LibavProcessor.c index 44ca575e..2c894cf5 100644 --- a/sources/Application/FX/LibavProcessor.c +++ b/sources/Application/FX/LibavProcessor.c @@ -24,7 +24,7 @@ static AVCodecContext *enc_ctx = NULL; static int open_input_file(const char *filename) { - AVCodec *dec; + const AVCodec *dec; AVCodecContext *dec_ctx; AVStream *stream; int ret; @@ -77,7 +77,7 @@ static int open_input_file(const char *filename) static int open_ir_file(const char *filename) { - AVCodec *dec; + const AVCodec *dec; AVCodecContext *dec_ctx; AVStream *stream; int ret; @@ -131,7 +131,6 @@ static int open_ir_file(const char *filename) static int open_output_file(const char *filename) { AVStream *out_stream; - AVStream *in_stream; const AVCodec *encoder; int ret; @@ -140,8 +139,6 @@ static int open_output_file(const char *filename) av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Could not create output context\n"); return AVERROR_UNKNOWN; } - - in_stream = ifmt_ctx->streams[0]; out_stream = avformat_new_stream(ofmt_ctx, NULL); if (!out_stream) { av_log(NULL, AV_LOG_ERROR, "[LibAvProc] Failed allocating output stream\n"); @@ -306,7 +303,8 @@ static int init_filters(int ir_wet, int ir_pad) snprintf(ch_layout_str, sizeof(ch_layout_str), "%dc", ifmt_ctx->streams[0]->codecpar->channels); } } else { - av_channel_layout_describe(&buffersink_ctx->inputs[0]->ch_layout, + // Use the input stream's channel layout + av_channel_layout_describe(&ifmt_ctx->streams[0]->codecpar->ch_layout, ch_layout_str, sizeof(ch_layout_str)); } #endif @@ -350,7 +348,8 @@ static int init_filters(int ir_wet, int ir_pad) snprintf(ir_ch_layout_str, sizeof(ir_ch_layout_str), "%dc", ir_fmt_ctx->streams[0]->codecpar->channels); } } else { - av_channel_layout_describe(&buffersink_ctx->inputs[0]->ch_layout, + // Use the IR stream's channel layout + av_channel_layout_describe(&ir_fmt_ctx->streams[0]->codecpar->ch_layout, ir_ch_layout_str, sizeof(ir_ch_layout_str)); } #endif @@ -429,12 +428,21 @@ static int init_filters(int ir_wet, int ir_pad) /* Apply convolution reverb using afir filter with format normalization */ char filters_descr[512]; + /* Scale ir_wet from 0-100 to 0-10 for afir filter */ + int afir_wet = (ir_wet * 10) / 100; + if (afir_wet > 10) afir_wet = 10; + if (afir_wet < 0) afir_wet = 0; + snprintf(filters_descr, sizeof(filters_descr), - "[ir_in]aresample=%d,aformat=sample_fmts=fltp:channel_layouts=%s[ir_norm];" - "[in]aresample=%d,aformat=sample_fmts=fltp:channel_layouts=%s,asplit[in_1][in_2];" - "[in_1][ir_norm]afir=dry=10:wet=10[reverb];" - "[in_2][reverb]amix=inputs=2:weights=100 %d,volume=1.5,aformat=sample_fmts=s16:channel_layouts=%s[out]", - target_sample_rate, target_layout, target_sample_rate, target_layout, ir_wet, target_layout); + "[ir_in]aresample=%d,aformat=sample_fmts=fltp:channel_layouts=%s[" + "ir_norm];" + "[in]aresample=%d,aformat=sample_fmts=fltp:channel_layouts=%s," + "asplit[in_1][in_2];" + "[in_1][ir_norm]afir=dry=10:wet=%d[reverb];" + "[in_2][reverb]amix=inputs=2:weights=1 " + "1,volume=2.5,aformat=sample_fmts=s16:channel_layouts=%s[out]", + target_sample_rate, target_layout, target_sample_rate, + target_layout, afir_wet, target_layout); av_log(NULL, AV_LOG_INFO, "Filter graph: %s\n", filters_descr); @@ -558,13 +566,12 @@ static int filter_encode_write_frame(AVFrame *frame, AVFrame *ir_frame, unsigned return ret; } -int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad) -{ +int encode(const char *fi, const char *ir, const char *fo, int irWet, + int irPad) { int ret; AVPacket *packet = NULL, *ir_packet = NULL; AVFrame *frame = NULL, *ir_frame = NULL; AVCodecContext *dec_ctx = NULL, *ir_dec_ctx = NULL; - unsigned int stream_index; int ir_loaded = 0; if ((ret = open_input_file(fi)) < 0) @@ -582,22 +589,45 @@ int encode(const char *fi, const char *ir, const char *fo, int irWet, int irPad) ir_frame = av_frame_alloc(); if (!packet || !ir_packet || !frame || !ir_frame) { fprintf(stderr, "Could not allocate frame or packet\n"); - return(1); + ret = AVERROR(ENOMEM); + goto end; } /* Set up decoder contexts */ - AVCodec *dec = + const AVCodec *dec = avcodec_find_decoder(ifmt_ctx->streams[0]->codecpar->codec_id); - AVCodec *ir_dec = avcodec_find_decoder(ir_fmt_ctx->streams[0]->codecpar->codec_id); - + const AVCodec *ir_dec = + avcodec_find_decoder(ir_fmt_ctx->streams[0]->codecpar->codec_id); + + if (!dec || !ir_dec) { + fprintf(stderr, "Could not find decoders (dec=%p, ir_dec=%p)\n", dec, ir_dec); + ret = AVERROR_DECODER_NOT_FOUND; + goto end; + } + dec_ctx = avcodec_alloc_context3(dec); ir_dec_ctx = avcodec_alloc_context3(ir_dec); - + + if (!dec_ctx || !ir_dec_ctx) { + fprintf(stderr, "Could not allocate decoder contexts\n"); + ret = AVERROR(ENOMEM); + goto end; + } + avcodec_parameters_to_context(dec_ctx, ifmt_ctx->streams[0]->codecpar); avcodec_parameters_to_context(ir_dec_ctx, ir_fmt_ctx->streams[0]->codecpar); - - avcodec_open2(dec_ctx, dec, NULL); - avcodec_open2(ir_dec_ctx, ir_dec, NULL); + + ret = avcodec_open2(dec_ctx, dec, NULL); + if (ret < 0) { + fprintf(stderr, "Could not open decoder: %s\n", av_err2str(ret)); + goto end; + } + + ret = avcodec_open2(ir_dec_ctx, ir_dec, NULL); + if (ret < 0) { + fprintf(stderr, "Could not open IR decoder: %s\n", av_err2str(ret)); + goto end; + } /* Process both streams - load ALL IR data first, then process main audio */ int ir_eof = 0, main_eof = 0; diff --git a/sources/Application/Instruments/SampleInstrument.cpp b/sources/Application/Instruments/SampleInstrument.cpp index c1b4f6b6..6d08e834 100644 --- a/sources/Application/Instruments/SampleInstrument.cpp +++ b/sources/Application/Instruments/SampleInstrument.cpp @@ -1410,6 +1410,17 @@ const char *SampleInstrument::GetName() { return src; } +/* + Get full name, don't shorten it for + display width limitation purposes +*/ +const char *SampleInstrument::GetFullName() { + Variable *v = FindVariable(SIP_SAMPLE); + const char *src = v->GetString(); + + return src; +} + void SampleInstrument::Purge() { IteratorPtr it(GetIterator()) ; for (it->Begin();!it->IsDone();it->Next()) { diff --git a/sources/Application/Instruments/SampleInstrument.h b/sources/Application/Instruments/SampleInstrument.h index ebf47e28..ea0e2166 100644 --- a/sources/Application/Instruments/SampleInstrument.h +++ b/sources/Application/Instruments/SampleInstrument.h @@ -92,16 +92,16 @@ class SampleInstrument: public I_Instrument,I_Observer { int GetLoopEnd(); virtual const char *GetName() ; // returns sample name until real // namer is implemented - - static void EnableDownsamplingLegacy(); + virtual const char *GetFullName(); + static void EnableDownsamplingLegacy(); -protected: - void updateInstrumentData(bool search) ; - void doTickUpdate(int channel) ; - void doKRateUpdate(int channel) ; - void updateFeedback(renderParams *rp) ; + protected: + void updateInstrumentData(bool search); + void doTickUpdate(int channel); + void doKRateUpdate(int channel); + void updateFeedback(renderParams *rp); -private: + private: SoundSource *source_ ; struct renderParams renderParams_[SONG_CHANNEL_COUNT] ; bool running_ ;