SFML не воспроизводится звук
Я захотел написать свой менеджер для управлением звуками, и получилось так, что по завершению программы звук не воспроизводится, но если я уберу добавление 2 и 3-его звука, все будет работать (причем неважно, какой будет файл walking_1.wav или walking_2.wav).
Audio.hpp
#pragma once
#include <SFML/Audio.hpp>
#include "specialtools.hpp"
class Audio{
public:
vector<sf::SoundBuffer> sBuffers;
vector<shared_ptr<sf::Sound>> sh_ptr_sounds;
vector<string> names;
void newSound(string name, string fname){
sBuffers.push_back(sf::SoundBuffer{});
sBuffers[sBuffers.size()-1].loadFromFile(fname);
cout<<"[ADD NEW SOUND] last buffer index: "<<sBuffers.size()-1<<endl;
sh_ptr_sounds.push_back(make_shared<sf::Sound>(sf::Sound{}));
sh_ptr_sounds[sh_ptr_sounds.size()-1]->setBuffer(sBuffers[sBuffers.size()-1]);
cout<<"[ADD NEW SOUND] last sound index: "<<sh_ptr_sounds.size()-1<<endl;
names.push_back(name);
cout<<"[ADD NEW SOUND] name: "<<name<<endl;
cout<<endl;
}
void playSound(string name){
cout<<"Index of sound: "<<index(names, name)<<endl;
sh_ptr_sounds[index(names, name)]->play();
}
Audio(){}
};
main.cpp
#include "Audio.hpp"
int main(){
Audio aud;
aud.newSound("1", "res/Sounds/walking_1.wav");
aud.newSound("2", "res/Sounds/walking_2.wav");
aud.newSound("3", "res/Sounds/walking_3.wav");
aud.playSound("1");
cin.get();
}
Вывод:
[ADD NEW SOUND] last buffer index: 0
[ADD NEW SOUND] last sound index: 0
[ADD NEW SOUND] name: 1
[ADD NEW SOUND] last buffer index: 1
[ADD NEW SOUND] last sound index: 1
[ADD NEW SOUND] name: 2
[ADD NEW SOUND] last buffer index: 2
[ADD NEW SOUND] last sound index: 2
[ADD NEW SOUND] name: 3
Index of sound: 0
В specialtools.hpp хранится только функция index, и подключаются библиотеки iostream, memory и vector.
Ответы (1 шт):
Экземпляры sf::Sound сохраняют ссылку на передаваемые в них экземпляры sf::SoundBuffer, соответственно переданные экземпляры sf::SoundBuffer должны оставаться валидными, пока используются. Однако при добавлении новых объектов в sBuffers все ссылки на хранившиеся там ранее объекты протухают
Тут имеет смысл держать один контейнер, который не будет инвалидировать ссылки на свои элементы.
class t_Sound
{
sf::SoundBuffer m_buffer;
sf::Sound m_sound;
::std::string m_name;
public: explicit
t_Sound(::std::string const & name, ::std::string const & fname)
: m_buffer{LoadFromFile(fname)}
, m_sound{m_buffer}
, m_name{name}
{}
private:
t_Sound(t_Sound const &) = delete;
private: void
operator =(t_Sound const &) = delete;
private: static sf::SoundBuffer
LoadFromFile(::std::string const & fname)
{
sf::SoundBuffer buffer{};
if (not buffer.loadFromFile(fname))
{
throw ::std::runtime_error{fname};
}
return buffer;
}
};
::std::vector<::std::shared_ptr<t_Sound>> m_sounds;
void
newSound(::std::string const & name, ::std::string const & fname)
{
m_sounds.emplace_back(::std::make_shared<t_Sound>(name, fname));
}