aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder/plugins
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/decoder/plugins/DsdLib.cxx4
-rw-r--r--src/decoder/plugins/DsdiffDecoderPlugin.cxx6
-rw-r--r--src/decoder/plugins/DsfDecoderPlugin.cxx8
-rw-r--r--src/decoder/plugins/FlacMetadata.cxx4
-rw-r--r--src/decoder/plugins/FluidsynthDecoderPlugin.cxx4
-rw-r--r--src/decoder/plugins/GmeDecoderPlugin.cxx188
-rw-r--r--src/decoder/plugins/MadDecoderPlugin.cxx14
-rw-r--r--src/decoder/plugins/SidplayDecoderPlugin.cxx180
-rw-r--r--src/decoder/plugins/VorbisComments.cxx4
-rw-r--r--src/decoder/plugins/WavpackDecoderPlugin.cxx6
10 files changed, 174 insertions, 244 deletions
diff --git a/src/decoder/plugins/DsdLib.cxx b/src/decoder/plugins/DsdLib.cxx
index 8892ed387..13f6bc846 100644
--- a/src/decoder/plugins/DsdLib.cxx
+++ b/src/decoder/plugins/DsdLib.cxx
@@ -32,7 +32,7 @@
#include <string.h>
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
#include <id3tag.h>
#endif
@@ -101,7 +101,7 @@ dsdlib_valid_freq(uint32_t samplefreq)
}
}
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
void
dsdlib_tag_id3(InputStream &is,
const struct tag_handler *handler,
diff --git a/src/decoder/plugins/DsdiffDecoderPlugin.cxx b/src/decoder/plugins/DsdiffDecoderPlugin.cxx
index b6c79e11e..33f433330 100644
--- a/src/decoder/plugins/DsdiffDecoderPlugin.cxx
+++ b/src/decoder/plugins/DsdiffDecoderPlugin.cxx
@@ -244,7 +244,7 @@ dsdiff_read_metadata_extra(Decoder *decoder, InputStream &is,
/** offset for title tag */
offset_type title_offset = 0;
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
offset_type id3_offset = 0;
#endif
@@ -269,7 +269,7 @@ dsdiff_read_metadata_extra(Decoder *decoder, InputStream &is,
chunk_size = chunk_header->GetSize();
title_offset = is.GetOffset();
}
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
/* 'ID3 ' chunk, offspec. Used by sacdextract */
if (chunk_header->id.Equals("ID3 ")) {
chunk_size = chunk_header->GetSize();
@@ -283,7 +283,7 @@ dsdiff_read_metadata_extra(Decoder *decoder, InputStream &is,
/* done processing chunk headers, process tags if any */
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
if (id3_offset != 0) {
/* a ID3 tag has preference over the other tags, do not process
other tags if we have one */
diff --git a/src/decoder/plugins/DsfDecoderPlugin.cxx b/src/decoder/plugins/DsfDecoderPlugin.cxx
index 690616d15..b8ae837f7 100644
--- a/src/decoder/plugins/DsfDecoderPlugin.cxx
+++ b/src/decoder/plugins/DsfDecoderPlugin.cxx
@@ -47,7 +47,7 @@ struct DsfMetaData {
unsigned sample_rate, channels;
bool bitreverse;
offset_type n_blocks;
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
offset_type id3_offset;
#endif
};
@@ -111,7 +111,7 @@ dsf_read_metadata(Decoder *decoder, InputStream &is,
if (sizeof(dsf_header) != chunk_size)
return false;
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
const offset_type metadata_offset = dsf_header.pmeta.Read();
#endif
@@ -174,7 +174,7 @@ dsf_read_metadata(Decoder *decoder, InputStream &is,
metadata->n_blocks = data_size / block_size;
metadata->channels = channels;
metadata->sample_rate = samplefreq;
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
metadata->id3_offset = metadata_offset;
#endif
/* check bits per sample format, determine if bitreverse is needed */
@@ -352,7 +352,7 @@ dsf_scan_stream(InputStream &is,
audio_format.sample_rate);
tag_handler_invoke_duration(handler, handler_ctx, songtime);
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
/* Add available tags from the ID3 tag */
dsdlib_tag_id3(is, handler, handler_ctx, metadata.id3_offset);
#endif
diff --git a/src/decoder/plugins/FlacMetadata.cxx b/src/decoder/plugins/FlacMetadata.cxx
index 03e276dce..86c6da04b 100644
--- a/src/decoder/plugins/FlacMetadata.cxx
+++ b/src/decoder/plugins/FlacMetadata.cxx
@@ -30,7 +30,7 @@
#include "tag/MixRamp.hxx"
#include "ReplayGainInfo.hxx"
#include "util/ASCII.hxx"
-#include "util/SplitString.hxx"
+#include "util/DivideString.hxx"
bool
flac_parse_replay_gain(ReplayGainInfo &rgi,
@@ -97,7 +97,7 @@ flac_scan_comment(const FLAC__StreamMetadata_VorbisComment_Entry *entry,
{
if (handler->pair != nullptr) {
const char *comment = (const char *)entry->entry;
- const SplitString split(comment, '=');
+ const DivideString split(comment, '=');
if (split.IsDefined() && !split.IsEmpty())
tag_handler_invoke_pair(handler, handler_ctx,
split.GetFirst(),
diff --git a/src/decoder/plugins/FluidsynthDecoderPlugin.cxx b/src/decoder/plugins/FluidsynthDecoderPlugin.cxx
index f19ac5bf4..55247549b 100644
--- a/src/decoder/plugins/FluidsynthDecoderPlugin.cxx
+++ b/src/decoder/plugins/FluidsynthDecoderPlugin.cxx
@@ -35,7 +35,7 @@ static unsigned sample_rate;
static const char *soundfont_path;
/**
- * Convert a fluidsynth log level to a GLib log level.
+ * Convert a fluidsynth log level to a MPD log level.
*/
static LogLevel
fluidsynth_level_to_mpd(enum fluid_log_level level)
@@ -61,7 +61,7 @@ fluidsynth_level_to_mpd(enum fluid_log_level level)
}
/**
- * The fluidsynth logging callback. It forwards messages to the GLib
+ * The fluidsynth logging callback. It forwards messages to the MPD
* logging library.
*/
static void
diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx
index cc6ce5e5d..8d3116ae1 100644
--- a/src/decoder/plugins/GmeDecoderPlugin.cxx
+++ b/src/decoder/plugins/GmeDecoderPlugin.cxx
@@ -23,6 +23,7 @@
#include "CheckAudioFormat.hxx"
#include "tag/TagHandler.hxx"
#include "fs/Path.hxx"
+#include "fs/AllocatedPath.hxx"
#include "util/Alloc.hxx"
#include "util/FormatString.hxx"
#include "util/UriUtil.hxx"
@@ -30,7 +31,6 @@
#include "util/Domain.hxx"
#include "Log.hxx"
-#include <glib.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
@@ -47,65 +47,42 @@ static constexpr unsigned GME_BUFFER_FRAMES = 2048;
static constexpr unsigned GME_BUFFER_SAMPLES =
GME_BUFFER_FRAMES * GME_CHANNELS;
-/**
- * returns the file path stripped of any /tune_xxx.* subtune
- * suffix
- */
-static char *
-get_container_name(Path path_fs)
+struct GmeContainerPath {
+ AllocatedPath path;
+ unsigned track;
+};
+
+gcc_pure
+static unsigned
+ParseSubtuneName(const char *base)
{
- const char *subtune_suffix = uri_get_suffix(path_fs.c_str());
- char *path_container = xstrdup(path_fs.c_str());
-
- char pat[64];
- snprintf(pat, sizeof(pat), "%s%s",
- "*/" SUBTUNE_PREFIX "???.",
- subtune_suffix);
- GPatternSpec *path_with_subtune = g_pattern_spec_new(pat);
- if (!g_pattern_match(path_with_subtune,
- strlen(path_container), path_container, nullptr)) {
- g_pattern_spec_free(path_with_subtune);
- return path_container;
- }
+ if (memcmp(base, SUBTUNE_PREFIX, sizeof(SUBTUNE_PREFIX) - 1) != 0)
+ return 0;
- char *ptr = g_strrstr(path_container, "/" SUBTUNE_PREFIX);
- if (ptr != nullptr)
- *ptr='\0';
+ base += sizeof(SUBTUNE_PREFIX) - 1;
- g_pattern_spec_free(path_with_subtune);
- return path_container;
+ char *endptr;
+ auto track = strtoul(base, &endptr, 10);
+ if (endptr == base || *endptr != '.')
+ return 0;
+
+ return track;
}
/**
- * returns tune number from file.nsf/tune_xxx.* style path or 0 if no subtune
- * is appended.
+ * returns the file path stripped of any /tune_xxx.* subtune suffix
+ * and the track number (or 0 if no "tune_xxx" suffix is present).
*/
-static int
-get_song_num(Path path_fs)
+static GmeContainerPath
+ParseContainerPath(Path path_fs)
{
- const char *subtune_suffix = uri_get_suffix(path_fs.c_str());
+ const Path base = path_fs.GetBase();
+ unsigned track;
+ if (base.IsNull() ||
+ (track = ParseSubtuneName(base.c_str())) < 1)
+ return { AllocatedPath(path_fs), 0 };
- char pat[64];
- snprintf(pat, sizeof(pat), "%s%s",
- "*/" SUBTUNE_PREFIX "???.",
- subtune_suffix);
- GPatternSpec *path_with_subtune = g_pattern_spec_new(pat);
-
- if (g_pattern_match(path_with_subtune,
- path_fs.length(), path_fs.data(), nullptr)) {
- char *sub = g_strrstr(path_fs.c_str(), "/" SUBTUNE_PREFIX);
- g_pattern_spec_free(path_with_subtune);
- if (!sub)
- return 0;
-
- sub += strlen("/" SUBTUNE_PREFIX);
- int song_num = strtol(sub, nullptr, 10);
-
- return song_num - 1;
- } else {
- g_pattern_spec_free(path_with_subtune);
- return 0;
- }
+ return { path_fs.GetDirectoryName(), track - 1 };
}
static char *
@@ -136,20 +113,18 @@ gme_container_scan(Path path_fs, const unsigned int tnum)
static void
gme_file_decode(Decoder &decoder, Path path_fs)
{
- char *path_container = get_container_name(path_fs);
+ const auto container = ParseContainerPath(path_fs);
Music_Emu *emu;
const char *gme_err =
- gme_open_file(path_container, &emu, GME_SAMPLE_RATE);
- free(path_container);
+ gme_open_file(container.path.c_str(), &emu, GME_SAMPLE_RATE);
if (gme_err != nullptr) {
LogWarning(gme_domain, gme_err);
return;
}
gme_info_t *ti;
- const int song_num = get_song_num(path_fs);
- gme_err = gme_track_info(emu, &ti, song_num);
+ gme_err = gme_track_info(emu, &ti, container.track);
if (gme_err != nullptr) {
LogWarning(gme_domain, gme_err);
gme_delete(emu);
@@ -175,7 +150,7 @@ gme_file_decode(Decoder &decoder, Path path_fs)
decoder_initialized(decoder, audio_format, true, song_len);
- gme_err = gme_start_track(emu, song_num);
+ gme_err = gme_start_track(emu, container.track);
if (gme_err != nullptr)
LogWarning(gme_domain, gme_err);
@@ -209,72 +184,85 @@ gme_file_decode(Decoder &decoder, Path path_fs)
gme_delete(emu);
}
-static bool
-gme_scan_file(Path path_fs,
- const struct tag_handler *handler, void *handler_ctx)
+static void
+ScanGmeInfo(const gme_info_t &info, unsigned song_num, int track_count,
+ const struct tag_handler *handler, void *handler_ctx)
{
- char *path_container = get_container_name(path_fs);
-
- Music_Emu *emu;
- const char *gme_err =
- gme_open_file(path_container, &emu, GME_SAMPLE_RATE);
- free(path_container);
- if (gme_err != nullptr) {
- LogWarning(gme_domain, gme_err);
- return false;
- }
-
- const int song_num = get_song_num(path_fs);
-
- gme_info_t *ti;
- gme_err = gme_track_info(emu, &ti, song_num);
- if (gme_err != nullptr) {
- LogWarning(gme_domain, gme_err);
- gme_delete(emu);
- return false;
- }
-
- assert(ti != nullptr);
-
- if (ti->length > 0)
+ if (info.length > 0)
tag_handler_invoke_duration(handler, handler_ctx,
- SongTime::FromMS(ti->length));
+ SongTime::FromMS(info.length));
- if (ti->song != nullptr) {
- if (gme_track_count(emu) > 1) {
+ if (info.song != nullptr) {
+ if (track_count > 1) {
/* start numbering subtunes from 1 */
char tag_title[1024];
snprintf(tag_title, sizeof(tag_title),
- "%s (%d/%d)",
- ti->song, song_num + 1,
- gme_track_count(emu));
+ "%s (%u/%d)",
+ info.song, song_num + 1,
+ track_count);
tag_handler_invoke_tag(handler, handler_ctx,
TAG_TITLE, tag_title);
} else
tag_handler_invoke_tag(handler, handler_ctx,
- TAG_TITLE, ti->song);
+ TAG_TITLE, info.song);
}
- if (ti->author != nullptr)
+ if (info.author != nullptr)
tag_handler_invoke_tag(handler, handler_ctx,
- TAG_ARTIST, ti->author);
+ TAG_ARTIST, info.author);
- if (ti->game != nullptr)
+ if (info.game != nullptr)
tag_handler_invoke_tag(handler, handler_ctx,
- TAG_ALBUM, ti->game);
+ TAG_ALBUM, info.game);
- if (ti->comment != nullptr)
+ if (info.comment != nullptr)
tag_handler_invoke_tag(handler, handler_ctx,
- TAG_COMMENT, ti->comment);
+ TAG_COMMENT, info.comment);
- if (ti->copyright != nullptr)
+ if (info.copyright != nullptr)
tag_handler_invoke_tag(handler, handler_ctx,
- TAG_DATE, ti->copyright);
+ TAG_DATE, info.copyright);
+}
+
+static bool
+ScanMusicEmu(Music_Emu *emu, unsigned song_num,
+ const struct tag_handler *handler, void *handler_ctx)
+{
+ gme_info_t *ti;
+ const char *gme_err = gme_track_info(emu, &ti, song_num);
+ if (gme_err != nullptr) {
+ LogWarning(gme_domain, gme_err);
+ return false;
+ }
+
+ assert(ti != nullptr);
+
+ ScanGmeInfo(*ti, song_num, gme_track_count(emu),
+ handler, handler_ctx);
gme_free_info(ti);
+ return true;
+}
+
+static bool
+gme_scan_file(Path path_fs,
+ const struct tag_handler *handler, void *handler_ctx)
+{
+ const auto container = ParseContainerPath(path_fs);
+
+ Music_Emu *emu;
+ const char *gme_err =
+ gme_open_file(container.path.c_str(), &emu, GME_SAMPLE_RATE);
+ if (gme_err != nullptr) {
+ LogWarning(gme_domain, gme_err);
+ return false;
+ }
+
+ const bool result = ScanMusicEmu(emu, container.track, handler, handler_ctx);
+
gme_delete(emu);
- return true;
+ return result;
}
static const char *const gme_suffixes[] = {
diff --git a/src/decoder/plugins/MadDecoderPlugin.cxx b/src/decoder/plugins/MadDecoderPlugin.cxx
index de6c9b127..62f31974f 100644
--- a/src/decoder/plugins/MadDecoderPlugin.cxx
+++ b/src/decoder/plugins/MadDecoderPlugin.cxx
@@ -36,7 +36,7 @@
#include <mad.h>
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
#include <id3tag.h>
#endif
@@ -251,7 +251,7 @@ MadDecoder::FillBuffer()
return true;
}
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
static bool
parse_id3_replay_gain_info(ReplayGainInfo &rgi,
struct id3_tag *tag)
@@ -285,7 +285,7 @@ parse_id3_replay_gain_info(ReplayGainInfo &rgi,
}
#endif
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
gcc_pure
static MixRampInfo
parse_id3_mixramp(struct id3_tag *tag)
@@ -317,7 +317,7 @@ parse_id3_mixramp(struct id3_tag *tag)
inline void
MadDecoder::ParseId3(size_t tagsize, Tag **mpd_tag)
{
-#ifdef HAVE_ID3TAG
+#ifdef ENABLE_ID3TAG
id3_byte_t *allocated = nullptr;
const id3_length_t count = stream.bufend - stream.this_frame;
@@ -369,7 +369,7 @@ MadDecoder::ParseId3(size_t tagsize, Tag **mpd_tag)
id3_tag_delete(id3_tag);
delete[] allocated;
-#else /* !HAVE_ID3TAG */
+#else /* !ENABLE_ID3TAG */
(void)mpd_tag;
/* This code is enabled when libid3tag is disabled. Instead
@@ -386,7 +386,7 @@ MadDecoder::ParseId3(size_t tagsize, Tag **mpd_tag)
#endif
}
-#ifndef HAVE_ID3TAG
+#ifndef ENABLE_ID3TAG
/**
* This function emulates libid3tag when it is disabled. Instead of
* doing a real analyzation of the frame, it just checks whether the
@@ -402,7 +402,7 @@ id3_tag_query(const void *p0, size_t length)
? (p[8] << 7) + p[9] + 10
: 0;
}
-#endif /* !HAVE_ID3TAG */
+#endif /* !ENABLE_ID3TAG */
static enum mp3_action
RecoverFrameError(struct mad_stream &stream)
diff --git a/src/decoder/plugins/SidplayDecoderPlugin.cxx b/src/decoder/plugins/SidplayDecoderPlugin.cxx
index 8435f095f..395945157 100644
--- a/src/decoder/plugins/SidplayDecoderPlugin.cxx
+++ b/src/decoder/plugins/SidplayDecoderPlugin.cxx
@@ -22,67 +22,44 @@
#include "../DecoderAPI.hxx"
#include "tag/TagHandler.hxx"
#include "fs/Path.hxx"
+#include "fs/AllocatedPath.hxx"
#include "util/FormatString.hxx"
#include "util/Domain.hxx"
+#include "util/Error.hxx"
#include "system/ByteOrder.hxx"
+#include "system/FatalError.hxx"
#include "Log.hxx"
-#include <errno.h>
-#include <stdlib.h>
#include <string.h>
-#include <glib.h>
#include <sidplay/sidplay2.h>
#include <sidplay/builders/resid.h>
#include <sidplay/utils/SidTuneMod.h>
+#include <sidplay/utils/SidDatabase.h>
#define SUBTUNE_PREFIX "tune_"
static constexpr Domain sidplay_domain("sidplay");
-static GPatternSpec *path_with_subtune;
-static const char *songlength_file;
-static GKeyFile *songlength_database;
+static SidDatabase *songlength_database;
static bool all_files_are_containers;
static unsigned default_songlength;
static bool filter_setting;
-static GKeyFile *
-sidplay_load_songlength_db(const char *path)
+static SidDatabase *
+sidplay_load_songlength_db(const Path path)
{
- GError *error = nullptr;
- gchar *data;
- gsize size;
-
- if (!g_file_get_contents(path, &data, &size, &error)) {
+ SidDatabase *db = new SidDatabase();
+ if (db->open(path.c_str()) < 0) {
FormatError(sidplay_domain,
"unable to read songlengths file %s: %s",
- path, error->message);
- g_error_free(error);
- return nullptr;
- }
-
- /* replace any ; comment characters with # */
- for (gsize i = 0; i < size; i++)
- if (data[i] == ';')
- data[i] = '#';
-
- GKeyFile *db = g_key_file_new();
- bool success = g_key_file_load_from_data(db, data, size,
- G_KEY_FILE_NONE, &error);
- g_free(data);
- if (!success) {
- FormatError(sidplay_domain,
- "unable to parse songlengths file %s: %s",
- path, error->message);
- g_error_free(error);
- g_key_file_free(db);
+ path.c_str(), db->error());
+ delete db;
return nullptr;
}
- g_key_file_set_list_separator(db, ' ');
return db;
}
@@ -90,18 +67,18 @@ static bool
sidplay_init(const config_param &param)
{
/* read the songlengths database file */
- songlength_file = param.GetBlockValue("songlength_database");
- if (songlength_file != nullptr)
- songlength_database = sidplay_load_songlength_db(songlength_file);
+ Error error;
+ const auto database_path = param.GetBlockPath("songlength_database", error);
+ if (!database_path.IsNull())
+ songlength_database = sidplay_load_songlength_db(database_path);
+ else if (error.IsDefined())
+ FatalError(error);
default_songlength = param.GetBlockValue("default_songlength", 0u);
all_files_are_containers =
param.GetBlockValue("all_files_are_containers", true);
- path_with_subtune=g_pattern_spec_new(
- "*/" SUBTUNE_PREFIX "???.sid");
-
filter_setting = param.GetBlockValue("filter", true);
return true;
@@ -110,96 +87,61 @@ sidplay_init(const config_param &param)
static void
sidplay_finish()
{
- g_pattern_spec_free(path_with_subtune);
-
- if(songlength_database)
- g_key_file_free(songlength_database);
+ delete songlength_database;
}
-/**
- * returns the file path stripped of any /tune_xxx.sid subtune
- * suffix
- */
-static char *
-get_container_name(Path path_fs)
+struct SidplayContainerPath {
+ AllocatedPath path;
+ unsigned track;
+};
+
+gcc_pure
+static unsigned
+ParseSubtuneName(const char *base)
{
- char *path_container = strdup(path_fs.c_str());
+ if (memcmp(base, SUBTUNE_PREFIX, sizeof(SUBTUNE_PREFIX) - 1) != 0)
+ return 0;
- if(!g_pattern_match(path_with_subtune,
- strlen(path_container), path_container, nullptr))
- return path_container;
+ base += sizeof(SUBTUNE_PREFIX) - 1;
- char *ptr=g_strrstr(path_container, "/" SUBTUNE_PREFIX);
- if(ptr) *ptr='\0';
+ char *endptr;
+ auto track = strtoul(base, &endptr, 10);
+ if (endptr == base || *endptr != '.')
+ return 0;
- return path_container;
+ return track;
}
/**
- * returns tune number from file.sid/tune_xxx.sid style path or 1 if
- * no subtune is appended
+ * returns the file path stripped of any /tune_xxx.* subtune suffix
+ * and the track number (or 1 if no "tune_xxx" suffix is present).
*/
-static unsigned
-get_song_num(const char *path_fs)
+static SidplayContainerPath
+ParseContainerPath(Path path_fs)
{
- if(g_pattern_match(path_with_subtune,
- strlen(path_fs), path_fs, nullptr)) {
- char *sub=g_strrstr(path_fs, "/" SUBTUNE_PREFIX);
- if(!sub) return 1;
-
- sub+=strlen("/" SUBTUNE_PREFIX);
- int song_num=strtol(sub, nullptr, 10);
-
- if (errno == EINVAL)
- return 1;
- else
- return song_num;
- } else
- return 1;
+ const Path base = path_fs.GetBase();
+ unsigned track;
+ if (base.IsNull() ||
+ (track = ParseSubtuneName(base.c_str())) < 1)
+ return { AllocatedPath(path_fs), 1 };
+
+ return { path_fs.GetDirectoryName(), track };
}
/* get the song length in seconds */
static SignedSongTime
-get_song_length(Path path_fs)
+get_song_length(SidTuneMod &tune)
{
+ assert(tune);
+
if (songlength_database == nullptr)
return SignedSongTime::Negative();
- char *sid_file = get_container_name(path_fs);
- SidTuneMod tune(sid_file);
- free(sid_file);
- if(!tune) {
- LogWarning(sidplay_domain,
- "failed to load file for calculating md5 sum");
+ const auto length = songlength_database->length(tune);
+ if (length < 0)
return SignedSongTime::Negative();
- }
- char md5sum[SIDTUNE_MD5_LENGTH+1];
- tune.createMD5(md5sum);
-
- const unsigned song_num = get_song_num(path_fs.c_str());
- gsize num_items;
- gchar **values=g_key_file_get_string_list(songlength_database,
- "Database", md5sum, &num_items, nullptr);
- if(!values || song_num>num_items) {
- g_strfreev(values);
- return SignedSongTime::Negative();
- }
-
- int minutes=strtol(values[song_num-1], nullptr, 10);
- if(errno==EINVAL) minutes=0;
-
- int seconds;
- char *ptr=strchr(values[song_num-1], ':');
- if(ptr) {
- seconds=strtol(ptr+1, nullptr, 10);
- if(errno==EINVAL) seconds=0;
- } else
- seconds=0;
-
- g_strfreev(values);
-
- return SignedSongTime::FromS((minutes * 60) + seconds);
+ return SignedSongTime::FromS(length);
}
static void
@@ -209,18 +151,17 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* load the tune */
- char *path_container=get_container_name(path_fs);
- SidTune tune(path_container, nullptr, true);
- free(path_container);
+ const auto container = ParseContainerPath(path_fs);
+ SidTuneMod tune(container.path.c_str());
if (!tune) {
LogWarning(sidplay_domain, "failed to load file");
return;
}
- const int song_num = get_song_num(path_fs.c_str());
+ const int song_num = container.track;
tune.selectSong(song_num);
- auto duration = get_song_length(path_fs);
+ auto duration = get_song_length(tune);
if (duration.IsNegative() && default_songlength > 0)
duration = SongTime::FromS(default_songlength);
@@ -347,14 +288,15 @@ static bool
sidplay_scan_file(Path path_fs,
const struct tag_handler *handler, void *handler_ctx)
{
- const int song_num = get_song_num(path_fs.c_str());
- char *path_container=get_container_name(path_fs);
+ const auto container = ParseContainerPath(path_fs);
+ const unsigned song_num = container.track;
- SidTune tune(path_container, nullptr, true);
- free(path_container);
+ SidTuneMod tune(container.path.c_str());
if (!tune)
return false;
+ tune.selectSong(song_num);
+
const SidTuneInfo &info = tune.getInfo();
/* title */
@@ -385,7 +327,7 @@ sidplay_scan_file(Path path_fs,
tag_handler_invoke_tag(handler, handler_ctx, TAG_TRACK, track);
/* time */
- const auto duration = get_song_length(path_fs);
+ const auto duration = get_song_length(tune);
if (!duration.IsNegative())
tag_handler_invoke_duration(handler, handler_ctx,
SongTime(duration));
diff --git a/src/decoder/plugins/VorbisComments.cxx b/src/decoder/plugins/VorbisComments.cxx
index 062f46acf..10652f129 100644
--- a/src/decoder/plugins/VorbisComments.cxx
+++ b/src/decoder/plugins/VorbisComments.cxx
@@ -27,7 +27,7 @@
#include "tag/ReplayGain.hxx"
#include "ReplayGainInfo.hxx"
#include "util/ASCII.hxx"
-#include "util/SplitString.hxx"
+#include "util/DivideString.hxx"
#include <stddef.h>
#include <stdlib.h>
@@ -74,7 +74,7 @@ vorbis_scan_comment(const char *comment,
const struct tag_handler *handler, void *handler_ctx)
{
if (handler->pair != nullptr) {
- const SplitString split(comment, '=');
+ const DivideString split(comment, '=');
if (split.IsDefined() && !split.IsEmpty())
tag_handler_invoke_pair(handler, handler_ctx,
split.GetFirst(),
diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx
index 67859bbd2..0b41d052e 100644
--- a/src/decoder/plugins/WavpackDecoderPlugin.cxx
+++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx
@@ -28,10 +28,10 @@
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "util/Macros.hxx"
+#include "util/Alloc.hxx"
#include "Log.hxx"
#include <wavpack/wavpack.h>
-#include <glib.h>
#include <assert.h>
#include <stdio.h>
@@ -484,10 +484,10 @@ wavpack_open_wvc(Decoder &decoder, const char *uri)
if (uri == nullptr)
return nullptr;
- char *wvc_url = g_strconcat(uri, "c", nullptr);
+ char *wvc_url = xstrcatdup(uri, "c");
InputStream *is_wvc = decoder_open_uri(decoder, uri, IgnoreError());
- g_free(wvc_url);
+ free(wvc_url);
if (is_wvc == nullptr)
return nullptr;