The Battle for Wesnoth  1.19.14+dev
sound_music_track.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2025
3  by David White <dave@whitevine.net>, Iris Morelle <shadowm2006@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "sound_music_track.hpp"
17 
18 #include "config.hpp"
19 #include "filesystem.hpp"
20 #include "log.hpp"
22 #include "vorbis/vorbisfile.h"
23 
24 static lg::log_domain log_audio("audio");
25 #define ERR_AUDIO LOG_STREAM(err, log_audio)
26 #define LOG_AUDIO LOG_STREAM(info, log_audio)
27 
28 namespace sound
29 {
30 namespace
31 {
32 std::string title_from_file(const std::string& track_path)
33 {
34  OggVorbis_File vf;
35  if(ov_fopen(track_path.c_str(), &vf) < 0) {
36  LOG_AUDIO << "Error opening file '" << track_path << "' for track identification";
37  return "";
38  }
39 
40  vorbis_comment* comments = ov_comment(&vf, -1);
41  char** user_comments = comments->user_comments;
42 
43  std::string title;
44  for(int i = 0; i < comments->comments; i++) {
45  const std::string comment_string(user_comments[i]);
46  const auto comment_list = utils::split_view(comment_string, '=');
47 
48  if(comment_list[0] == "TITLE" || comment_list[0] == "title") {
49  title = comment_list[1];
50  break;
51  }
52  }
53 
54  ov_clear(&vf);
55  return title;
56 }
57 
58 utils::optional<std::string> resolve_track_path(const std::string& track_file)
59 {
60  if(!track_file.empty()) {
62  }
63 
64  LOG_AUDIO << "empty track filename specified for track identification";
65  return utils::nullopt;
66 }
67 
68 } // namespace
69 
70 std::shared_ptr<music_track> music_track::create(const config& cfg)
71 {
72  if(auto path = resolve_track_path(cfg["name"])) {
73  return std::make_shared<music_track>(*path, cfg);
74  }
75 
76  LOG_AUDIO << "could not find track '" << cfg["name"] << "'";
77  return nullptr;
78 }
79 
80 std::shared_ptr<music_track> music_track::create(const std::string& file)
81 {
82  if(auto path = resolve_track_path(file)) {
83  return std::make_shared<music_track>(*path, file);
84  }
85 
86  LOG_AUDIO << "could not find track '" << file << "'";
87  return nullptr;
88 }
89 
90 music_track::music_track(const std::string& file_path, const config& node)
91  : id_(node["name"])
92  , file_path_(file_path)
93  , title_(node["title"])
94  , ms_before_(node["ms_before"].to_int())
95  , ms_after_(node["ms_after"].to_int())
96  , once_(node["play_once"].to_bool())
97  , append_(node["append"].to_bool())
98  , immediate_(node["immediate"].to_bool())
99  , shuffle_(node["shuffle"].to_bool(true))
100 {
101  if(title_.empty()) {
102  title_ = title_from_file(file_path_);
103  }
104 }
105 
106 music_track::music_track(const std::string& file_path, const std::string& file)
107  : id_(file)
108  , file_path_(file_path)
109  , title_(title_from_file(file_path_))
110 {
111 }
112 
113 void music_track::write(config &parent_node, bool append) const
114 {
115  config& m = parent_node.add_child("music");
116  m["name"] = id_;
117  m["ms_before"] = ms_before_;
118  m["ms_after"] = ms_after_;
119  if(append) {
120  m["append"] = true;
121  }
122  //default behaviour is to shuffle
123  m["shuffle"] = shuffle_;
124 }
125 
126 } /* end namespace sound */
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
config & add_child(config_key_type key)
Definition: config.cpp:436
std::chrono::milliseconds ms_before_
void write(config &parent_node, bool append) const
static std::shared_ptr< music_track > create(const config &cfg)
music_track(const std::string &file_path, const config &node)
std::chrono::milliseconds ms_after_
Definitions for the interface to Wesnoth Markup Language (WML).
const config * cfg
Declarations for File-IO.
std::size_t i
Definition: function.cpp:1032
Standard logging facilities (interface).
utils::optional< std::string > get_binary_file_location(const std::string &type, const std::string &filename)
Returns a complete path to the actual file of a given type, if it exists.
utils::optional< std::string > get_localized_path(const std::string &file, const std::string &suff)
Returns the localized version of the given filename, if it exists.
std::string path
Definition: filesystem.cpp:106
Audio output for sound and music.
Definition: sound.cpp:39
std::vector< std::string_view > split_view(std::string_view s, const char sep, const int flags)
static lg::log_domain log_audio("audio")
#define LOG_AUDIO