SFML community forums
Help => Audio => Topic started by: CBenni::O on March 05, 2010, 08:36:06 pm
-
Hy,
Why doesn't this code work:
int main()
{
sf::SoundBuffer MSB;
MSB.LoadFromFile("nice_music.ogg");
sf::Sound MySound2(MSB);
MySound2.Play();
if(MySound2.GetStatus() != sf::Sound::Playing)
{
// Debugging shows that this spot is executed...
}
sf::Sleep(10.0f);
return 0;
};
I am using the SFML 2.0 from the trunk...
Is it because I dont create a Window, or why else?
bye, CBenni::O
-
Does LoadFromFile("nice_music.ogg") succeed?
-
Now it does... And the status is set correctly, too...
But still, I don't hear the sound...
EDIT: I put this piece of code into a working piece of code, which creates a window, and still, it didn't play!
EDIT2: Sry, i am an idiot :D It wasn't a soft- but a hardwareproblem :roll:
:? another Problem... in a bigger program, it loads the SoundBuffer all right, but when i call it using my ResourceManager, it can't play the soundbuffer anymore... I haven't found a place where a soundbuffer is copied, only sf::SoundBuffer* pointers are passed to the user... What ist the problem here?
bye, CBenni::O
-
see EDIT above...
sry for confusing posts...
bye, CBenni::O
-
Show your code ;)
-
I'll try to make it as small as possible...
-
So, these are the important parts:
Creating the Resource:
SoundBuffer_Resource* NewSoundBuffer = new SoundBuffer_Resource(TopJob.filename);
ResourcePair = std::make_pair(TopJob.filename,NewSoundBuffer);
MyResources.insert(ResourcePair);
(topjob is a job out of the loading queue...)
Loading the Buffer:
SoundBuffer_Resource::SoundBuffer_Resource(const std::string filename)
{
MySoundBuffer = new sf::SoundBuffer();
MySoundBuffer->LoadFromFile(filename);
}
Aquiring the Resource:
template<typename T>
T* BBB::ResourceManager::Acquire(std::string name, DWORD maxloadingtime, DWORD sleeptime)
{
DWORD StartTime = timeGetTime();
while(MyResources.find(name) == MyResources.end() || MyResources.find(name)->second == NULL)
{
DWORD eltime = timeGetTime()-StartTime;
if(eltime < maxloadingtime)
{
Sleep(sleeptime);
}
else
{
return NULL;
}
}
}
return static_cast<T*>(MyResources.find(name)->second);
};
Using the SoundBuffer:
BBB::SoundBuffer_Resource* MyRes2 = MyResMgr.Acquire<BBB::SoundBuffer_Resource>("../Data/nice_music.ogg",1000000,10);
if(MyRes2 != NULL)
{
MySoundIsLoaded = true;
sf::SoundBuffer test = *MyRes2->Get();
MySound.SetBuffer(*MyRes2->Get());
MySound.Play();
}
I don't see a single copy in there...
The Buffer returned by Aquire ist not NULL, but it isn't played either...
bye, CBenni::O
-
You still don't check whether LoadFromFile succeeds or not.
-
I test it, i just put that out, because it is quite a lot of testing etc.
I have added this into the constructor of SoundBuffer_Resource:
sf::Sound test(*MySoundBuffer);
test.play();
Sleep(10000);
And it played the sound! (only for 10 seconds, of course ;))
bye, CBenni::O
-
Sorry for multiple Post,
but I have tested some more and found out that inside of SoundBuffer_Resource::Get(), the buffer is okay... So the problem is somewhere in the way from Get() to the usage uf my Buffer...
does anyone see the error I'm making?
Or is it (eventually) a bug in the copy semantics? But actually, I don't pass Instances, only pointers...
bye, CBenni::O
-
If I were you, I'd write a minimal example that reproduces this problem. Your code is too complex and contains too many lines unrelated to the problem, you'll waste more time trying to debug it directly than writing a simpler similar code.
-
I've been trying that, but I never achieved to build a code that reproduces my Problem... I am not able to isolate the Problem...
I'll try again, or else I upload the complete source, if that helps...
bye, CBenni::O
-
It works now...
I didn't get what was wrong, but this worked:
sf::Sound* MySound;
if(!MySoundIsLoaded)
{
BBB::SoundBuffer_Resource* MyRes2 = MyResMgr.Acquire<BBB::SoundBuffer_Resource>("../Data/nice_music.ogg",false,BBB::Res_None,0,0);
if(MyRes2 != NULL)
{
MySound = new sf::Sound(*MyRes2->Get()));
MySound->Play();
MySoundIsLoaded = true;
}
}
But this didn't:
sf::Sound* MySound = new sf::Sound();
if(!MySoundIsLoaded)
{
BBB::SoundBuffer_Resource* MyRes2 = MyResMgr.Acquire<BBB::SoundBuffer_Resource>("../Data/nice_music.ogg",false,BBB::Res_None,0,0);
if(MyRes2 != NULL)
{
MySound->SetBuffer(*MyRes2->Get()));
MySound->Play();
MySoundIsLoaded = true;
}
Any mistakes left? ;)
I would check the semantics of SetBuffer...
bye, CBenni::O
-
Your second piece of code is totally wrong, can you show the actual code? ;)
-
I'm sorry... did a few mistakes -.-
Correcting them rightaway...
bye, CBenni::O
-
What if you remove your manager from this code, and use a sf::SoundBuffer directly?
-
This worked...
sf::SoundBuffer* SB = new sf::SoundBuffer;
if(!SB->LoadFromFile("nice_music.ogg"))return 1;
sf::Sound* MS = new sf::Sound();
MS->SetBuffer(*SB);
MS->Play();
sf::Sleep(1.0f);
But I'm too lazy to test it in deph :) I think that I did a mistake somewhere, because it works now...
bye, CBenni::O
-
Why do you allocate everything with new? There's no need for that. I already pointed out, what problems come with dynamic allocations and why alternatives like RAII and automatic memory management are really worthwhile. ;)
If you encapsulated the low-level parts of your code, then you'll have to worry far less about errors, memory leaks and undefined behaviour in your programs. I even guess this problem here might not have happened with a clearly structured design... :)
-
What I have above, is just a short snippet of a Program I used for testing... in my example Program (that I will release tonight :D), I use auto_ptr's if not local variables...
One good thing: my Framework does not have any memoryleaks and is exeption-safe (I hope so ;) ) thanks to "Effektiv C++ Programmieren"
Thank you for that tipp :)
bye, CBenni::O
-
I use auto_ptr
std::auto_ptr is a dangerous beast with its move semantics, I personnaly never use it. Are you sure that you use it properly?
-
Yes, I only use it in my example program, in all other cases I use some kind of RAII :D
Download (http://www.ottenfamily.de/CBFramework_v100.zip) of my Framework
bye, CBenni::O
-
One good thing: my Framework does not have any memoryleaks and is exeption-safe (I hope so ;) ) thanks to "Effektiv C++ Programmieren"
Ah okay, I didn't know that. Congratulations then! :)
std::auto_ptr is a dangerous beast with its move semantics, I personnaly never use it. Are you sure that you use it properly?
At the moment, std::auto_ptr is the only smart-pointer that's really part of the standard library (shared_ptr is in TR1, scoped_ptr only in Boost (I still don't understand why)). Of course, one has to work with auto_ptr carefully, because as you said, it doesn't have common value semantics and can't be used like other objects, for example in STL-containers. Also things like that can be very tricky:
void func(std::auto_ptr<X> ptr);
I like std::auto_ptr because it is one of the few ways to employ move-semantics in current C++. For example, it works well with factory methods. Raw possessing pointers are rather unconvenient (especially regarding exception safety), shared_ptr would be the alternative. But why share ownership when we need to transfer it? ;)
-
Is your demo supposed to show the problem? It seemed to work fine when I tested it, I mean sounds played properly.
By the way, I looked at your code and there are indeed too many pointers and dynamic allocations ;)
None of them are really necessary, and you have many leaks because you don't destroy all the objects that you create with new.
-
No, It's the final version of my framework...
All I need to add is the Release ()-Function in ResourceManager, but this is no Problem...
And:
By the way, I looked at your code and there are indeed too many pointers and dynamic allocations ;)
None of them are really necessary, and you have many leaks because you don't destroy all the objects that you create with new.
Are you sure? I didn't find any Hidden memory leaks using vld, and auto_ptr or whatever does nothing else but to allocate and free Memory... And I Hate to return auto_ptr's, because you get More and more get()'s etc...
bye, CBenni::O
-
No, It's the final version of my framework...
Sorry, I'm lost. Is your problem solved now?
Are you sure? I didn't find any Hidden memory leaks using vld, and auto_ptr or whatever does nothing else but to allocate and free Memory...
I'm talking about your framework, not the demo (which is the only place where you use std::auto_ptr, right?). An example of memory leak is in FloatingObj: the image used by the sprite is allocated with new but never deleted.
You should really not allocate everything dynamically ;)
-
No, It's the final version of my framework...
Sorry, I'm lost. Is your problem solved now?
Yes, it is... But I don't know what the error was... It had something to do what I do with my Resource after Aquiring it...
I'm talking about your framework, not the demo (which is the only place where you use std::auto_ptr, right?). An example of memory leak is in FloatingObj: the image used by the sprite is allocated with new but never deleted.
You should really not allocate everything dynamically ;)
Yes, thank you... I've changed it... There ist only 1 dynamic Allocation per FloatingObj-Constructor now...
bye, CBenni::O