1 /*
2  * Copyright (C) 2006-2019 Christopho, Solarus - http://www.solarus-games.org
3  *
4  * Solarus is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Solarus is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #ifndef SOLARUS_MUSIC_H
18 #define SOLARUS_MUSIC_H
19 
20 #include "solarus/core/Common.h"
21 #include "solarus/audio/Sound.h"
22 #include "solarus/lua/ScopedLuaRef.h"
23 #include <memory>
24 #include <string>
25 #include <vector>
26 
27 namespace Solarus {
28 
29 class ItDecoder;
30 class OggDecoder;
31 class SpcDecoder;
32 
33 /**
34  * \brief Represents a music that can be played.
35  *
36  * A music should be in format .spc (Snes), .it (Impulse Tracker module) or .ogg.
37  * The .mp3 format will probably be supported in a future version.
38  * Only one music can be played at the same time.
39  * Before using this class, the audio system should have been
40  * initialized, by calling Sound::initialize().
41  * Sound and Music are the only classes that depends on audio libraries.
42  *
43  * TODO move the non-static parts to an internal private class.
44  * TODO make a subclass for each format?
45  */
46 class SOLARUS_API Music {
47 
48   public:
49 
50     /**
51      * The music file formats recognized.
52      */
53     enum Format {
54       NO_FORMAT,        /**< No music. */
55       SPC,              /**< Original Snes music. */
56       IT,               /**< Impulse Tracker module. */
57       OGG               /**< Ogg Vorbis. */
58     };
59 
60     static const std::string none;               /**< special id indicating that there is no music */
61     static const std::string unchanged;          /**< special id indicating that the music is the same as before */
62     static const std::vector<std::string>
63         format_names;                            /**< Name of each format. */
64 
65     static void initialize();
66     static void quit();
67     static bool is_initialized();
68     static void update();
69 
70     static Format get_format();
71     static int get_volume();
72     static void set_volume(int volume);
73     static int get_num_channels();
74     static int get_channel_volume(int channel);
75     static void set_channel_volume(int channel, int volume);
76     static int get_tempo();
77     static void set_tempo(int tempo);
78 
79     static void find_music_file(const std::string& music_id,
80         std::string& file_name, Format& format);
81     static bool exists(const std::string& music_id);
82     static void play(
83         const std::string& music_id,
84         bool loop
85     );
86     static void play(
87         const std::string& music_id,
88         bool loop,
89         const ScopedLuaRef& callback_ref
90     );
91     static void stop_playing();
92     static const std::string& get_current_music_id();
93 
94   private:
95 
96     Music();
97     Music(
98         const std::string& music_id,
99         bool loop,
100         const ScopedLuaRef& callback_ref
101     );
102 
103     bool start();
104     void stop();
105     bool is_paused();
106     void set_paused(bool pause);
107     void set_callback(const ScopedLuaRef& callback_ref);
108 
109     void decode_spc(ALuint destination_buffer, ALsizei nb_samples);
110     void decode_it(ALuint destination_buffer, ALsizei nb_samples);
111     void decode_ogg(ALuint destination_buffer, ALsizei nb_samples);
112 
113     bool update_playing();
114 
115     std::string id;                              /**< id of this music */
116     std::string file_name;                       /**< name of the file to play */
117     Format format;                               /**< format of the music, detected from the file name */
118     bool loop;                                   /**< Whether the music should loop. */
119     ScopedLuaRef callback_ref;                   /**< Lua ref to a function to call when the music finishes. */
120 
121     static constexpr int nb_buffers = 8;
122     ALuint buffers[nb_buffers];                  /**< multiple buffers used to stream the music */
123     ALuint source;                               /**< the OpenAL source streaming the buffers */
124 
125     static std::unique_ptr<SpcDecoder>
126         spc_decoder;                             /**< The SPC decoder. */
127     static std::unique_ptr<ItDecoder>
128         it_decoder;                              /**< The IT decoder. */
129     static std::unique_ptr<OggDecoder>
130         ogg_decoder;                             /**< The OGG decoder. */
131     static float volume;                         /**< volume of musics (0.0 to 1.0) */
132 
133     static std::unique_ptr<Music> current_music; /**< the music currently played (if any) */
134 
135 };
136 
137 }
138 
139 #endif
140 
141