SDL Mixer Sound Not Playing - c++

I am making a game using SDL and my SoundHandler class is not working and I cannot figure out why. The file paths are definatly correct and I have SDL_Mixer set up properly as I have had sound work correctly before, I also get no errors or warnings the game runs fine there is just no music.
SoundHandler.h:
enum Sounds
{
BACKGROUND_MUSIC, STICK_COLLECT
};
class SoundHandler
{
public:
SoundHandler();
void PlaySound(Sounds sound);
private:
Mix_Music *backMusic;
Mix_Music *stickCollect;
};
SoundHandler.cpp:
SoundHandler::SoundHandler()
{
Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096);
this->backMusic = Mix_LoadMUS("Data//Music//Background.mp3");
this->stickCollect = Mix_LoadMUS("Data//Sounds//StickCollect.mp3");
Mix_VolumeMusic(128);
}
void SoundHandler::PlaySound(Sounds sound)
{
if(sound == BACKGROUND_MUSIC)
{
Mix_PlayMusic(this->backMusic, -1);
}
if(sound == STICK_COLLECT)
{
Mix_PlayMusic(this->stickCollect, 1);
}
}
Relevant Lines in main.cpp:
// Initialise Sound
SoundHandler soundHandler;
// Play Background Music
soundHandler.PlaySound(BACKGROUND_MUSIC);
// Play Sound
soundHandler.PlaySound(STICK_COLLECT);

I think that problem is in double slashes in file path, try to use single slash.
You will have long time of debugging without error checking.

Related

Getting External Headphones (8): EXC_BAD_ACCESS (code=1, address=0x0) error when I am trying to use maximilian

I am testing out using the maximilian library with JUCE. I am trying to use the maxiSample feature and I have implemented it exactly how the example code says to. Whenever I run the standalone app, I get the error "External Headphones (8): EXC_BAD_ACCESS (code=1, address=0x0)" and it gives me a breakpoint at line 747 of maximilian.cpp. It's not my headphones as it does the same thing with any playback device. Truly at a loss.
I've attached my MainComponent.cpp below. Any advice would be great, thank you!
#include "MainComponent.h"
#include "maximilian.h"
//==============================================================================
MainComponent::MainComponent()
{
// Make sure you set the size of the component after
// you add any child components.
setSize (800, 600);
// Some platforms require permissions to open input channels so request that here
if (juce::RuntimePermissions::isRequired (juce::RuntimePermissions::recordAudio)
&& ! juce::RuntimePermissions::isGranted (juce::RuntimePermissions::recordAudio))
{
juce::RuntimePermissions::request (juce::RuntimePermissions::recordAudio,
[&] (bool granted) { setAudioChannels (granted ? 2 : 0, 2); });
}
else
{
// Specify the number of input and output channels that we want to open
setAudioChannels (2, 2);
}
}
MainComponent::~MainComponent()
{
// This shuts down the audio device and clears the audio source.
shutdownAudio();
sample1.load("/Users/(username)/JuceTestPlugins/maxiSample/Source/kick.wav");
}
//==============================================================================
void MainComponent::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
{
// This function will be called when the audio device is started, or when
// its settings (i.e. sample rate, block size, etc) are changed.
// You can use this function to initialise any resources you might need,
// but be careful - it will be called on the audio thread, not the GUI thread.
// For more details, see the help for AudioProcessor::prepareToPlay()
}
void MainComponent::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill)
{
// Your audio-processing code goes here!
// For more details, see the help for AudioProcessor::getNextAudioBlock()
// Right now we are not producing any data, in which case we need to clear the buffer
// (to prevent the output of random noise)
//bufferToFill.clearActiveBufferRegion();
for(int sample = 0; sample < bufferToFill.buffer->getNumSamples(); ++sample){
//float sample2 = sample1.
//float wave = tesOsc.sinewave(200);
//double sample2 = sample1.play();
// leftSpeaker[sample] = (0.25 * wave);
// rightSpeaker[sample] = leftSpeaker[sample];
double *output;
output[0] = sample1.play();
output[1] = output[0];
}
}
void MainComponent::releaseResources()
{
// This will be called when the audio device stops, or when it is being
// restarted due to a setting change.
// For more details, see the help for AudioProcessor::releaseResources()
}
//==============================================================================
void MainComponent::paint (juce::Graphics& g)
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
// You can add your drawing code here!
}
void MainComponent::resized()
{
// This is called when the MainContentComponent is resized.
// If you add any child components, this is where you should
// update their positions.
}
Can't say for sure, but couple of things catch my attention.
In getNextAudioBlock() you are dereferencing invalid pointers:
double *output;
output[0] = sample1.play();
output[1] = output[0];
The pointer variable output is uninitialised and will probably be filled with garbage or zeros, which will make the program read from invalid memory. This problem is most likely to cause the EXC_BAD_ACCESS. This method is called from the realtime audio thread, so you probably get a crash on a non-main thread (in this case the thread of External Headphones (8)).
It also is no clear to me what exactly it is you're trying to do here, so it's hard for me to say how it should be. What I can say is that assigning the result of sample1.play() to a double value looks suspicious.
Normally, when dealing with juce::AudioSourceChannelInfo you would get pointers to the audio buffers like so:
auto** bufferPointer = bufferToFill.buffer->getArrayOfWritePointers()
Further, you are loading a file inside the destructor of MainComponent. This at least is suspicious, why would you load a file during destruction?
MainComponent::~MainComponent()
{
// This shuts down the audio device and clears the audio source.
shutdownAudio();
sample1.load("/Users/(username)/JuceTestPlugins/maxiSample/Source/kick.wav");
}

QtGstreamer camerabin2 usage

I'm working on olimex a13 board with just eglfs i.e, no windowing system. Because of this Qt Multimedia stuff video and camera aren't working as Qt uses Gstreamer which in turn needs X. So I'm using QtGstreamer library which is here.
I've followed the examples and created a media player which is working as expected. Now, I want to do a camera and using camerabin2 which is from bad plugins.
This is my code:
//init QGst
QGst::init(&argc, &argv);
//create video surface
QGst::Quick::VideoSurface* videoSurface = new QGst::Quick::VideoSurface(&engine);
CameraPlayer player;
player.setVideoSink(videoSurface->videoSink());
//cameraplayer.cpp
void open()
{
if (!m_pipeline) {
m_pipeline = QGst::ElementFactory::make("camerabin").dynamicCast<QGst::Pipeline>();
if (m_pipeline) {
m_pipeline->setProperty("video-sink", m_videoSink);
//watch the bus for messages
QGst::BusPtr bus = m_pipeline->bus();
bus->addSignalWatch();
QGlib::connect(bus, "message", this, &CameraPlayer::onBusMessage);
//QGlib::connect(bus, "image-done", this, &CameraPlayer::onImageDone);
} else {
qCritical() << "Failed to create the pipeline";
}
}
}
//-----------------------------------
void CameraPlayer::setVideoSink(const QGst::ElementPtr & sink)
{
m_videoSink = sink;
}
//-----------------------------------
void CameraPlayer::start()
{
m_pipeline->setState(QGst::StateReady);
m_pipeline->setState(QGst::StatePlaying);
}
I then call cameraPlayer.start() which isn't working i.e, no video. Am I missing something here? Has anyone used QtGstreamer to stream webcam? Thanks in advance.
I realised some plugins (multifilesink) were missing. Started my Qt application with --gst-debug-level=4 argument and gstreamer then reported about missing plugins.

SDL_mixer stop playing music on certain event

My program needs to stop playing sound if certain point is in range, for that I have class with function run() which runs on seperate thread and plays sound using SDL.h and SDL_mixer.h:
void SoundCheck::run()
{
Mix_PlayMusic(music, 1);
while(1)
{
if(normalize(sound[0], range_->getPos()))
{
printf("stop sound\n");
Mix_HaltChannel(-1);
}
sleep(1);
}
}
but when if condition returns true it prints "stop sound" but sound still plays, what seems to be the problem?
Mix_HaltChannel is used to stop a Mix_Chunk after being started with Mix_PlayChannel.
To stop a Mix_Music after being started with Mix_PlayMusic, you must use Mix_HaltMusic.

How do I get Fmod to work from a class?

In my project written in C++, I have FMOD currently working from my main.cpp. To help organize my engine I want to move my sound code to it's own translation unit. For some reason when I try to run my sound code from within my class, it doesn't play any sound. I'm not sure if it is because of incorrect assignment of the value or if there is a bigger issue that I don't know about. This is my class implementation:
//Sound.h
#ifndef SOUND_H
#define SOUND_H
#include <iostream>
#include "inc\fmod.hpp"
#include "inc\fmod_errors.h"
class Sound
{
public:
Sound(void);
~Sound(void);
void Init();
void FMODErrorCheck(FMOD_RESULT res);
void PlaySound();
void ResumeSound();
void PauseSound();
void Update();
private:
//sound
FMOD::System *sys;
FMOD_RESULT result;
size_t version; //this is just an unsigned int
FMOD_SPEAKERMODE speakerMode;
int numDrivers;
FMOD_CAPS caps;
char name[256];
FMOD::Sound *sound;
FMOD::Channel *channel;
bool quitFlag;
};
#endif
//Sound.cpp
#include "Sound.h"
Sound::Sound(void)
{
Init();
}
Sound::~Sound(void)
{
FMODErrorCheck(sound->release());
FMODErrorCheck(sys->release());
}
void Sound::Init()
{
// Create FMOD interface object
result = FMOD::System_Create(&sys);
FMODErrorCheck(result);
// Check version
result = sys->getVersion(&version);
FMODErrorCheck(result);
if(version < FMOD_VERSION)
{
std::cout << "Error! You are using an old version of FMOD " << version << ". This program requires " << FMOD_VERSION << std::endl;
exit(0);
}
// Get number of sound cards
result = sys->getNumDrivers(&numDrivers);
FMODErrorCheck(result);
// No sound cards (disable sound)
if(numDrivers == 0)
{
result = sys->setOutput(FMOD_OUTPUTTYPE_NOSOUND);
FMODErrorCheck(result);
}
// At least one sound card
else
{
// Get the capabilities of the default (0) sound card
result = sys->getDriverCaps(0, &caps, 0, &speakerMode);
FMODErrorCheck(result);
// Set the speaker mode to match that in Control Panel
result = sys->setSpeakerMode(speakerMode);
FMODErrorCheck(result);
// Increase buffer size if user has Acceleration slider set to off
if(caps & FMOD_CAPS_HARDWARE_EMULATED)
{
result = sys->setDSPBufferSize(1024, 10);
FMODErrorCheck(result);
}
// Get name of driver
result = sys->getDriverInfo(0, name, 256, 0);
FMODErrorCheck(result);
// SigmaTel sound devices crackle for some reason if the format is PCM 16-bit.
// PCM floating point output seems to solve it.
if(strstr(name, "SigmaTel"))
{
result = sys->setSoftwareFormat(48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
FMODErrorCheck(result);
}
}
// Initialise FMOD
result = sys->init(100, FMOD_INIT_NORMAL, 0);
// If the selected speaker mode isn't supported by this sound card, switch it back to stereo
if(result == FMOD_ERR_OUTPUT_CREATEBUFFER)
{
result = sys->setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
FMODErrorCheck(result);
result = sys->init(100, FMOD_INIT_NORMAL, 0);
}
FMODErrorCheck(result);
// Open music as a stream
//FMOD::Sound *song1, *song2, *effect;
//result = sys->createStream("Effect.mp3", FMOD_DEFAULT, 0, &sound);
//FMODErrorCheck(result);
result = sys->createSound("Effect.mp3", FMOD_DEFAULT, 0, &sound);
FMODErrorCheck(result);
// Assign each song to a channel and start them paused
//result = sys->playSound(FMOD_CHANNEL_FREE, sound, true, &channel);
//FMODErrorCheck(result);
// Songs should repeat forever
channel->setLoopCount(-1);
}
void Sound::FMODErrorCheck(FMOD_RESULT res)
{
if(res != FMOD_OK)
{
std::cout << "FMOD ERROR: (" << res << ") - " << FMOD_ErrorString(res) << std::endl;
//quitFlag = true;
}
}
void Sound::PlaySound()
{
sys->playSound(FMOD_CHANNEL_FREE, sound, false, 0);
}
void Sound::ResumeSound()
{
channel->setPaused(false);
}
void Sound::PauseSound()
{
channel->setPaused(true);
}
void Sound::Update()
{
sys->update();
}
//Main.cpp
Sound sound;
// Initialization routine.
void setup(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
sound = &Sound();
}
//------------------------------------------------------------ OnInit()
//
void OnIdle()
{
if(IsKeyPressed(KEY_ESCAPE))
{
exit(EXIT_SUCCESS);
}
if(IsKeyPressed('1'))
{
sound->PlaySound();
}
sound->Update();
// redraw the screen
glutPostRedisplay();
}
Currently it is giving me 2 errors:
Unhandled exception at 0x0F74465A (fmodex.dll) in TestOpenGL.exe: 0xC0000005: Access violation reading location 0x062C5040
and
FMOD error! (36) An invalid object handle was used
Any idea why it isn't working? Any idea how I solve these issues?
From your last comment and looking at your code I see a problem. You have created a pointer by FMOD::System *sys; but this pointer is not initialized to any instance of FMOD::System that is, there should be something like sys = new FMOD::System or sys = new FMOD::System(/* whatever argument you must supply to it's constructor */); somewhere in your code but right before you try to access anything related to FMOD::System object. This is most probably the reason for your program crash. Also since sys is a pointer to FMOD::System there's another problem at line containing result = FMOD::System_Create(&sys); you are passing a pointer by reference. I suggest you read a couple of articles about pointers in C and C++ and also some more about object creation and destruction in object oriented programming languages.
I was able to get help with the issue. I was initializing my sound variable incorrectly.
sound = &Sound();
Should actually be:
sound = new Sound();

Image.loadFromFile() doesn't work?

So I've been looking around in my code for hours now and finally I think I found the issue with the code. An SFML method doesn't work or I am using it wrong.
I am trying to load a PNG file from my disk into the program so I can render it on screen.
But the picture is never even loaded into the program to begin with it seems. As when I check the debugger I see no actual info about the file I am trying to load in.
I'll show the entire Engine.cpp file first, and then explain step by step what happens.
My Engine.cpp looks like this:
#include "Engine.h"
#include <SFML\Graphics.hpp>
Engine::Engine()
{
}
Engine::~Engine()
{
}
bool Engine::Init()
{
LoadImages();
window = new sf::RenderWindow(sf::VideoMode(800,600,32), "RPG");
if(!window)
return false;
return true;
}
void Engine::LoadImages()
{
sf::Image sprite;
sprite.loadFromFile("C:/Users/Vipar/Pictures/sprite1.png");
imageManager.AddImage(sprite);
testTile = new Tile(imageManager.GetImage(0));
}
void Engine::RenderFrame()
{
window->clear();
testTile->Draw(0,0,window);
window->display();
}
void Engine::ProcessInput()
{
sf::Event evt;
//Loop through all window events
while(window->pollEvent(evt))
{
if(evt.type == sf::Event::Closed)
window->close();
}
}
void Engine::Update()
{
}
void Engine::MainLoop()
{
sf::Image sprite;
sprite.loadFromFile("C:/Users/Vipar/Pictures/sprite1.png");
imageManager.AddImage(sprite);
testTile = new Tile(imageManager.GetImage(0));
//Loop until our window is closed
while(window->isOpen())
{
ProcessInput();
Update();
RenderFrame();
testTile->Draw(0,0,window);
}
}
void Engine::Go()
{
if(!Init())
throw "Could not initialize Engine";
MainLoop();
}
I call this method:
void Engine::LoadImages()
{
sf::Image sprite;
sprite.loadFromFile("C:/Users/Vipar/Pictures/sprite1.png");
imageManager.AddImage(sprite);
testTile = new Tile(imageManager.GetImage(0));
}
It adds the Image to my ImageManager for later use if need be. This is done for a bit of efficiency. Then I apply the Image to my custom class called Tile. It looks like this:
#include "Tile.h"
#include <SFML\Graphics.hpp>
#include <iostream>
Tile::Tile(sf::Image& image)
{
sf::Texture tex;
tex.loadFromImage(image);
baseSprite.setTexture(tex,true);
}
Tile::~Tile()
{
}
void Tile::Draw(int x, int y, sf::RenderWindow* rw)
{
baseSprite.setPosition(x,y);
rw->draw(baseSprite);
}
void Tile::Destroy()
{
delete &baseSprite;
}
Then I draw the Tile on screen to test it out.
Why does this png file not even load into my program to begin with? If you need additional code, please let me know. I am a bit green on this SFML framework and C++ but I am good at Java and C#.
I only work with SFML.net (maybe you should use it?), and I don't like how you're doing things, but...
Throw some debug messages to make sure that all your appropriate
functions/code is getting run.
Clear with a different color and make sure it works.
Your naming is confusing and misleading.
Make sure you've checked the tutorial to see how they draw.