decoder/DecoderPlugin: container_scan() returns forward_list<string>
This commit is contained in:
parent
114fcee2ae
commit
0abee77e62
2
NEWS
2
NEWS
|
@ -21,9 +21,11 @@ ver 0.20 (not yet released)
|
||||||
- ffmpeg: support ReplayGain and MixRamp
|
- ffmpeg: support ReplayGain and MixRamp
|
||||||
- ffmpeg: support stream tags
|
- ffmpeg: support stream tags
|
||||||
- gme: add option "accuracy"
|
- gme: add option "accuracy"
|
||||||
|
- gme: faster scanning
|
||||||
- mad: reduce memory usage while scanning tags
|
- mad: reduce memory usage while scanning tags
|
||||||
- mpcdec: read the bit rate
|
- mpcdec: read the bit rate
|
||||||
- pcm: support audio/L16 (RFC 2586) and audio/x-mpd-float
|
- pcm: support audio/L16 (RFC 2586) and audio/x-mpd-float
|
||||||
|
- sidplay: faster scanning
|
||||||
* playlist
|
* playlist
|
||||||
- cue: don't skip pregap
|
- cue: don't skip pregap
|
||||||
- embcue: fix last track
|
- embcue: fix last track
|
||||||
|
|
|
@ -96,10 +96,14 @@ UpdateWalk::UpdateContainerFile(Directory &directory,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocatedString<> vtrack = nullptr;
|
const auto v = plugin.container_scan(pathname);
|
||||||
unsigned int tnum = 0;
|
if (v.empty()) {
|
||||||
|
editor.LockDeleteDirectory(contdir);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
TagBuilder tag_builder;
|
TagBuilder tag_builder;
|
||||||
while ((vtrack = plugin.container_scan(pathname, ++tnum)) != nullptr) {
|
for (const auto &vtrack : v) {
|
||||||
Song *song = Song::NewFile(vtrack.c_str(), *contdir);
|
Song *song = Song::NewFile(vtrack.c_str(), *contdir);
|
||||||
|
|
||||||
// shouldn't be necessary but it's there..
|
// shouldn't be necessary but it's there..
|
||||||
|
@ -126,9 +130,5 @@ UpdateWalk::UpdateContainerFile(Directory &directory,
|
||||||
directory.GetPath(), vtrack.c_str());
|
directory.GetPath(), vtrack.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tnum == 1) {
|
return true;
|
||||||
editor.LockDeleteDirectory(contdir);
|
|
||||||
return false;
|
|
||||||
} else
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,13 @@
|
||||||
|
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
struct ConfigBlock;
|
struct ConfigBlock;
|
||||||
class InputStream;
|
class InputStream;
|
||||||
struct TagHandler;
|
struct TagHandler;
|
||||||
class Path;
|
class Path;
|
||||||
template<typename T> class AllocatedString;
|
|
||||||
class DecoderClient;
|
class DecoderClient;
|
||||||
|
|
||||||
struct DecoderPlugin {
|
struct DecoderPlugin {
|
||||||
|
@ -85,14 +87,13 @@ struct DecoderPlugin {
|
||||||
/**
|
/**
|
||||||
* @brief Return a "virtual" filename for subtracks in
|
* @brief Return a "virtual" filename for subtracks in
|
||||||
* container formats like flac
|
* container formats like flac
|
||||||
* @param const char* pathname full pathname for the file on fs
|
* @param path_fs full pathname for the file on fs
|
||||||
* @param const unsigned int tnum track number
|
|
||||||
*
|
*
|
||||||
* @return nullptr if there are no multiple files
|
* @return an empty list if there are no multiple files
|
||||||
* a filename for every single track according to tnum (param 2)
|
* a filename for every single track;
|
||||||
* do not include full pathname here, just the "virtual" file
|
* do not include full pathname here, just the "virtual" file
|
||||||
*/
|
*/
|
||||||
AllocatedString<char> (*container_scan)(Path path_fs, unsigned tnum);
|
std::forward_list<std::string> (*container_scan)(Path path_fs);
|
||||||
|
|
||||||
/* last element in these arrays must always be a nullptr: */
|
/* last element in these arrays must always be a nullptr: */
|
||||||
const char *const*suffixes;
|
const char *const*suffixes;
|
||||||
|
|
|
@ -27,16 +27,16 @@
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
#include "util/FormatString.hxx"
|
#include "util/FormatString.hxx"
|
||||||
#include "util/AllocatedString.hxx"
|
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
|
#include <gme/gme.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <gme/gme.h>
|
|
||||||
|
|
||||||
#define SUBTUNE_PREFIX "tune_"
|
#define SUBTUNE_PREFIX "tune_"
|
||||||
|
|
||||||
|
@ -103,29 +103,36 @@ ParseContainerPath(Path path_fs)
|
||||||
return { path_fs.GetDirectoryName(), track - 1 };
|
return { path_fs.GetDirectoryName(), track - 1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
static AllocatedString<>
|
static std::forward_list<std::string>
|
||||||
gme_container_scan(Path path_fs, const unsigned int tnum)
|
gme_container_scan(Path path_fs)
|
||||||
{
|
{
|
||||||
|
std::forward_list<std::string> list;
|
||||||
|
|
||||||
Music_Emu *emu;
|
Music_Emu *emu;
|
||||||
const char *gme_err = gme_open_file(path_fs.c_str(), &emu,
|
const char *gme_err = gme_open_file(path_fs.c_str(), &emu,
|
||||||
GME_SAMPLE_RATE);
|
GME_SAMPLE_RATE);
|
||||||
if (gme_err != nullptr) {
|
if (gme_err != nullptr) {
|
||||||
LogWarning(gme_domain, gme_err);
|
LogWarning(gme_domain, gme_err);
|
||||||
return nullptr;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned num_songs = gme_track_count(emu);
|
const unsigned num_songs = gme_track_count(emu);
|
||||||
gme_delete(emu);
|
gme_delete(emu);
|
||||||
/* if it only contains a single tune, don't treat as container */
|
/* if it only contains a single tune, don't treat as container */
|
||||||
if (num_songs < 2)
|
if (num_songs < 2)
|
||||||
return nullptr;
|
return list;
|
||||||
|
|
||||||
const char *subtune_suffix = uri_get_suffix(path_fs.c_str());
|
const char *subtune_suffix = uri_get_suffix(path_fs.c_str());
|
||||||
if (tnum <= num_songs){
|
|
||||||
return FormatString(SUBTUNE_PREFIX "%03u.%s",
|
auto tail = list.before_begin();
|
||||||
tnum, subtune_suffix);
|
for (unsigned i = 1; i < num_songs; ++i) {
|
||||||
} else
|
char track_name[64];
|
||||||
return nullptr;
|
snprintf(track_name, sizeof(track_name),
|
||||||
|
"%03u.%s", i, subtune_suffix);
|
||||||
|
tail = list.emplace_after(tail, track_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -25,14 +25,11 @@
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "util/Macros.hxx"
|
#include "util/Macros.hxx"
|
||||||
#include "util/FormatString.hxx"
|
#include "util/FormatString.hxx"
|
||||||
#include "util/AllocatedString.hxx"
|
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "system/ByteOrder.hxx"
|
#include "system/ByteOrder.hxx"
|
||||||
#include "system/FatalError.hxx"
|
#include "system/FatalError.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SIDPLAYFP
|
#ifdef HAVE_SIDPLAYFP
|
||||||
#include <sidplayfp/sidplayfp.h>
|
#include <sidplayfp/sidplayfp.h>
|
||||||
#include <sidplayfp/SidInfo.h>
|
#include <sidplayfp/SidInfo.h>
|
||||||
|
@ -49,6 +46,9 @@
|
||||||
#include <sidplay/utils/SidDatabase.h>
|
#include <sidplay/utils/SidDatabase.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define SUBTUNE_PREFIX "tune_"
|
#define SUBTUNE_PREFIX "tune_"
|
||||||
|
|
||||||
static constexpr Domain sidplay_domain("sidplay");
|
static constexpr Domain sidplay_domain("sidplay");
|
||||||
|
@ -476,12 +476,14 @@ sidplay_scan_file(Path path_fs,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AllocatedString<>
|
static std::forward_list<std::string>
|
||||||
sidplay_container_scan(Path path_fs, const unsigned int tnum)
|
sidplay_container_scan(Path path_fs)
|
||||||
{
|
{
|
||||||
|
std::forward_list<std::string> list;
|
||||||
|
|
||||||
SidTune tune(path_fs.c_str(), nullptr, true);
|
SidTune tune(path_fs.c_str(), nullptr, true);
|
||||||
if (!tune.getStatus())
|
if (!tune.getStatus())
|
||||||
return nullptr;
|
return list;
|
||||||
|
|
||||||
#ifdef HAVE_SIDPLAYFP
|
#ifdef HAVE_SIDPLAYFP
|
||||||
const SidTuneInfo &info = *tune.getInfo();
|
const SidTuneInfo &info = *tune.getInfo();
|
||||||
|
@ -494,14 +496,18 @@ sidplay_container_scan(Path path_fs, const unsigned int tnum)
|
||||||
/* Don't treat sids containing a single tune
|
/* Don't treat sids containing a single tune
|
||||||
as containers */
|
as containers */
|
||||||
if(!all_files_are_containers && n_tracks < 2)
|
if(!all_files_are_containers && n_tracks < 2)
|
||||||
return nullptr;
|
return list;
|
||||||
|
|
||||||
/* Construct container/tune path names, eg.
|
auto tail = list.before_begin();
|
||||||
Delta.sid/tune_001.sid */
|
for (unsigned i = 1; i < n_tracks; ++i) {
|
||||||
if (tnum <= n_tracks) {
|
char track_name[32];
|
||||||
return FormatString(SUBTUNE_PREFIX "%03u.sid", tnum);
|
/* Construct container/tune path names, eg.
|
||||||
} else
|
Delta.sid/tune_001.sid */
|
||||||
return nullptr;
|
sprintf(track_name, SUBTUNE_PREFIX "%03u.sid", i);
|
||||||
|
tail = list.emplace_after(tail, track_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *const sidplay_suffixes[] = {
|
static const char *const sidplay_suffixes[] = {
|
||||||
|
|
Loading…
Reference in New Issue