/** * \brief Returns whether a music exists. * \param music_id Id of the music to test. Music::none and Music::unchanged * are also considered valid. * \return true If this music exists. */ bool Music::exists(const std::string& music_id) { if (music_id == none || music_id == unchanged) { return true; } std::string file_name; Format format; find_music_file(music_id, file_name, format); return !file_name.empty(); }
/** * @brief Creates a new music. * @param music_id id of the music (file name without extension) */ Music::Music(const std::string& music_id): id(music_id) { if (!is_initialized() || music_id == none) { return; } find_music_file(music_id, file_name, format); if (music_id.empty()) { Debug::die(StringConcat() << "Cannot find music file 'musics/" << music_id << "' (tried extensions .ogg, .it and .spc)"); } for (int i = 0; i < nb_buffers; i++) { buffers[i] = AL_NONE; } source = AL_NONE; }
/** * \brief Loads the file and starts playing this music. * * No other music should be playing. * * \return true if the music was loaded successfully */ bool Music::start() { if (!is_initialized()) { return false; } // First time: find the file. if (file_name.empty()) { find_music_file(id, file_name, format); if (file_name.empty()) { Debug::error(std::string("Cannot find music file 'musics/") + id + "' (tried with extensions .ogg, .it and .spc)" ); return false; } } bool success = true; // create the buffers and the source alGenBuffers(nb_buffers, buffers); alGenSources(1, &source); alSourcef(source, AL_GAIN, volume); // load the music into memory std::string sound_buffer; switch (format) { case SPC: sound_buffer = QuestFiles::data_file_read(file_name); // load the SPC data into the SPC decoding library spc_decoder->load((int16_t*) sound_buffer.data(), sound_buffer.size()); for (int i = 0; i < nb_buffers; i++) { decode_spc(buffers[i], 4096); } break; case IT: sound_buffer = QuestFiles::data_file_read(file_name); // load the IT data into the IT decoding library it_decoder->load(sound_buffer); for (int i = 0; i < nb_buffers; i++) { decode_it(buffers[i], 4096); } break; case OGG: { ogg_mem.position = 0; ogg_mem.loop = this->loop; ogg_mem.data = QuestFiles::data_file_read(file_name); // now, ogg_mem contains the encoded data int error = ov_open_callbacks(&ogg_mem, &ogg_file, nullptr, 0, Sound::ogg_callbacks); if (error) { std::ostringstream oss; oss << "Cannot load music file '" << file_name << "' from memory: error " << error; Debug::error(oss.str()); } else { for (int i = 0; i < nb_buffers; i++) { decode_ogg(buffers[i], 4096); } } break; } case NO_FORMAT: Debug::die("Invalid music format"); break; } // start the streaming alSourceQueueBuffers(source, nb_buffers, buffers); int error = alGetError(); if (error != AL_NO_ERROR) { std::ostringstream oss; oss << "Cannot initialize buffers for music '" << file_name << "': error " << error; Debug::error(oss.str()); success = false; } alSourcePlay(source); // The update() function will then take care of filling the buffers return success; }
/** * \brief Loads the file and starts playing this music. * * No other music should be playing. * * \return true if the music was loaded successfully */ bool Music::start() { if (!is_initialized()) { return false; } Debug::check_assertion(current_music == NULL, StringConcat() << "Cannot play music '" << id << "': a music is already playing"); // First time: find the file. if (file_name.empty()) { find_music_file(id, file_name, format); if (file_name.empty()) { Debug::error(StringConcat() << "Cannot find music file 'musics/" << id << "' (tried with extensions .ogg, .it and .spc)"); return false; } } bool success = true; // create the buffers and the source alGenBuffers(nb_buffers, buffers); alGenSources(1, &source); alSourcef(source, AL_GAIN, volume); // load the music into memory size_t sound_size; char* sound_data; switch (format) { case SPC: FileTools::data_file_open_buffer(file_name, &sound_data, &sound_size); // load the SPC data into the SPC decoding library spc_decoder->load((int16_t*) sound_data, sound_size); FileTools::data_file_close_buffer(sound_data); for (int i = 0; i < nb_buffers; i++) { decode_spc(buffers[i], 4096); } break; case IT: FileTools::data_file_open_buffer(file_name, &sound_data, &sound_size); // load the IT data into the IT decoding library it_decoder->load(sound_data, sound_size); FileTools::data_file_close_buffer(sound_data); for (int i = 0; i < nb_buffers; i++) { decode_it(buffers[i], 4096); } break; case OGG: { ogg_mem.position = 0; ogg_mem.loop = true; FileTools::data_file_open_buffer(file_name, &ogg_mem.data, &ogg_mem.size); // now, ogg_mem contains the encoded data int error = ov_open_callbacks(&ogg_mem, &ogg_file, NULL, 0, Sound::ogg_callbacks); if (error) { Debug::error(StringConcat() << "Cannot load music file '" << file_name << "' from memory: error " << error); } else { for (int i = 0; i < nb_buffers; i++) { decode_ogg(buffers[i], 4096); } } break; } case NO_FORMAT: Debug::die("Invalid music format"); break; } // start the streaming alSourceQueueBuffers(source, nb_buffers, buffers); int error = alGetError(); if (error != AL_NO_ERROR) { Debug::error(StringConcat() << "Cannot initialize buffers for music '" << file_name << "': error " << error); success = false; } alSourcePlay(source); // now the update() function will take care of filling the buffers current_music = this; return success; }
/** * \brief Loads the file and starts playing this music. * * No other music should be playing. * * \return true if the music was loaded successfully */ bool Music::start() { if (!is_initialized()) { return false; } // First time: find the file. if (file_name.empty()) { find_music_file(id, file_name, format); if (file_name.empty()) { Debug::error(std::string("Cannot find music file 'musics/") + id + "' (tried with extensions .ogg, .it and .spc)" ); return false; } } bool success = true; // create the buffers and the source alGenBuffers(nb_buffers, buffers); alGenSources(1, &source); alSourcef(source, AL_GAIN, volume); // load the music into memory std::string sound_buffer; switch (format) { case SPC: sound_buffer = QuestFiles::data_file_read(file_name); // Give the SPC data into the SPC decoder. spc_decoder->load((int16_t*) sound_buffer.data(), sound_buffer.size()); for (int i = 0; i < nb_buffers; i++) { decode_spc(buffers[i], 16384); } break; case IT: sound_buffer = QuestFiles::data_file_read(file_name); // Give the IT data to the IT decoder it_decoder->load(sound_buffer); for (int i = 0; i < nb_buffers; i++) { decode_it(buffers[i], 16384); } break; case OGG: sound_buffer = QuestFiles::data_file_read(file_name); // Give the OGG data to the OGG decoder. success = ogg_decoder->load(std::move(sound_buffer), this->loop); if (success) { for (int i = 0; i < nb_buffers; i++) { decode_ogg(buffers[i], 16384); } } break; case NO_FORMAT: Debug::die("Invalid music format"); break; } if (!success) { Debug::error("Cannot load music file '" + file_name + "'"); } // start the streaming alSourceQueueBuffers(source, nb_buffers, buffers); int error = alGetError(); if (error != AL_NO_ERROR) { std::ostringstream oss; oss << "Cannot initialize buffers for music '" << file_name << "': error " << error; Debug::error(oss.str()); success = false; } alSourcePlay(source); // The update() function will then take care of filling the buffers return success; }