Allegro5 C++: Audio sample can't be loaded - c++

I'm trying to insert a song that plays on a loop in my c++ Allegro 5 game. It keeps saying that it can't load the audio.
I have:
tried to use .wav and .ogg files, both did not work.
put the audio file in the correct directory.
created a function to detect the error.
initialized al_init_acodec_addon() and al_install_audio()
ALLEGRO_SAMPLE* song = al_load_sample("liar.ogg");
void game_begin()
{
if (!song)
{
printf( "Audio clip sample not loaded!\n" );
show_err_msg(-6);
}
//Loop the song until the display closes
al_play_sample(song, 1,0,1,ALLEGRO_PLAYMODE_LOOP, NULL);
Basically the console almost always prints out the error message no matter what I do.
Is this a known Allegro 5 problem? I still can't think of a way to fix this...
On a side note, I have tested loading & playing audio in another project file and it worked. Is my file cursed? :(

:)
Try to put it in THIS ORDER before loading samples:
if(!al_init())
return -1;
if(!al_install_audio())
return -2;
if!(!al_init_acodec_addon()) // after installing audio
return -3;
if(!al_reserve_samples(1))
return -4;
And what do you mean by correct directory?

Related

SDL_Image loading a png returns nullptr

Alright so I'm trying to make a game engine for myself, and I've decided that it would be best to start loading images as files other than bitmaps using the SDL Image library. I've set up the library correctly according to conversations online, include set up and linker set up, and yet when I try to load a file that does indeed exist it just returns an empty surface.
Heres the code loading the file...
SDL_Surface* background = IMG_Load("Assets/bg.png");
background = SDL_ConvertSurface(background, mtrx->format, 0);
if (!background) {
ofstream file("text.txt");
file << IMG_GetError() << endl;
file.close();
}
...And the error I get in "text.txt"...
Parameter 'surface' is invalid
At the beginning of the script I have included SDL.h, then SDL_image.h, and the window initiation has IMG_Init(IMG_INIT_PNG) after SDL_Init. Visual studio shows no errors whatsoever, and everything BUT IMG_Load works fine.
All help would be appreciated, and I can provide any other code that might be helpful!

How do I know the format of audio file?

I want to make a music player and I want to filter out files not audio file on opening.
Should I use QAudioDecoder?
But every file I checked with QAudioDecoder tells me the same codec "audio/pcm".
QAudioDecoder decoder;
decoder.setSourceFilename(fileUrl.toLocalFile());
qDebug() << decoder.audioFormat().codec();
How do I know if the audio file's format is supported by Qt media player by not just checking if the file's name ends with ".mp3" or ".wav"?
And I found that some files' duration incorrect when playing on my music player.
But when I play the file with other music player apps, it gives correct duration on other music players.
Or my app can't play some files but others can.
the console says :
DirectShowPlayerService::doSetUrlSource: Unresolved error code
0x80070002 (?t?Χ??????w?????C)
but after I change the file name, it can be opened.
How should I fix those on my music player instead of fixing the files' probably wrong or unsupported formats one by one?
I wrote this code to check if the file I opened is a supported audio file.
QMediaPlayer audioChecker;
audioChecker.setMedia(fileUrl);
qDebug() << audioChecker.media().canonicalUrl().fileName();
qDebug() << audioChecker.isAudioAvailable();
if(audioChecker.error() == QMediaPlayer::NoError) {
qDebug() << "no error";
}
if(audioChecker.error() == QMediaPlayer::FormatError) {
qDebug() << "format error";
}
and it tells me no error no matter what file I tested.
console:
"musicplayer.exe"
false
no error
"musicplayer.exe"
false
no error
"musicplayer.ilk"
false
no error
"musicplayer.exe"
false
no error
"a song.mp3"
false
no error
But how can files not audio file get no error?
Why do audio file's audio not available?
Never mind. I just read that setMedia() return immediately and doesn't wait for the media to be loaded. so it's normal it gets no audio and no error because it's not loaded.
I guess I'll make a thread class to check my file.
By the way, incorrect duration of the file is fixed somehow. Does it relate to LAV Splitter?
From Qt's documentation:
For playing media or audio files that are not simple, uncompressed audio, you can use the QMediaPlayer C++ class […] The compressed audio formats supported does depend on the operating system environment, and also what media plugins the user may have installed.
A simple example of how to use the QMediaPlayer class:
player = new QMediaPlayer;
// ...
player->setMedia(QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3"));
player->setVolume(50);
player->play();
To verify that the codec is supported, you can use the error() method of the QMediaPlayer class which will return you an error code (see the documentation).
So, after calling setMedia(), you can do something like:
if (player->error() == QMediaPlayer::FormatError)
{
// Codec/format unsupported
}
About the error code you get when opening files:
check that you have no \ characters in your path (if you have some, escape them with another \)
check if you have spaces, special characters, etc.
About how to check audio format in file without check its suffix, there's a tool names mediainfo, with the command line tool run as below:
mediainfo -f [filepath]
You'll get the full information about the file, both video and audio if they exists. And among these parameters, there's a "format" value under "Audio" category, that indicates the actual audio format inside. eg. AAC/AC3
About the file can be played after name changed, I consider maybe there are some space characters in the filename, or the Player just can't access the file specified by name.

PlaySound() function won't play sound

First question, sorry if I don't do something right :S. I'm attempting to loop a background audio track while a game created in the console window is played. This is part of a group project. The game runs fine but I simply can't get the audio track to play using the PlaySound() function. This is a test program I made to try to figure out the problem.
#include <iostream>
#include <windows.h>
#include <mmsystem.h>
using namespace std;
int main()
{
PlaySound(TEXT("D:\\CodeBlocks:\\Programming Work:\\SoundTest:\\castor.wav"), NULL, SND_FILENAME|SND_ASYNC|SND_LOOP);
if(PlaySound(TEXT("D:\\CodeBlocks:\\Programming Work:\\SoundTest:\\castor.wav"), NULL, SND_FILENAME|SND_ASYNC|SND_LOOP))
{
cout << "It's Working." << endl;
}
else
{
cout << "It's not working." << endl;
}
cout << "Hello world!" << endl;
return 0;
}
My test case returns true (or "It's working."), and when I tried it in the school computer lab, it would loop the default windows error tone, which plays when the function can't find the file you specified, even though I've given it the whole file path. I can't figure out why it can't find the file, I've quadruple checked that it is in fact located where I wrote the file path, and it still seems unable to find it. I've tried using both .mp3 and .wav formats for the audio file. Anyone know what's going on?
(note: The linker needs to be given the winmm library for this)
Thanks guys, I found the actual problem, it wasn't even code all along. Turns out my audio file (castor.wav) was not actually in wav format, which is required by the PlaySound() function, even though the computer was telling me it was .wav (Even when I showed the properties of the file, it said it was in wav format).
This is because I attempted to convert it from a .mp3 by simply changing .mp3 to .wav, should have known better. After using an actual conversion program (and removing the exact file path and simply giving it TEXT("castor.wav") it works like a charm. Thanks for the help!

How to use ffmpeg faststart flag programmatically?

I try to convert videos for playback on Android using H264, AAC codecs and mp4 container. Video plays normaly with non-system players. But system player shows error "Can't play this video".
I found out that the problem is in moov atom, which is writed in the end of the file.
When I use "-movflags +faststart" ffmeg flag to convert video, it plays normal, but when I try to do that programmatically, it gives no result. I use following code:
av_dict_set( &dict, "movflags", "faststart", 0 );
ret = avformat_write_header( ofmt_ctx, &dict );
This code works fine:
av_dict_set( &dict, "movflags", "faststart", 0 );
ret = avformat_write_header( ofmt_ctx, &dict );
But problem is not solved. I still can't play converted videos on Android devices.
I assume that this answer is very late, but still, for anyone who might still be facing the same issue: this might be caused by the AV_CODEC_FLAG_GLOBAL_HEADER not being set in the audio/video AVCodecContext. A lot of guides show that it needs to be set in the AVFormatContext, but it needs to be set in the AVCodecContext before opening it using avcodec_open2.
if (format_context->oformat->flags & AVFMT_GLOBALHEADER) {
video_codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
avcodec_open2(video_codec_context, video_codec, nullptr);
Maybe the video is not compatible with your android phone? Try to convert with h264 baseline profile.
TL;DR
Set url field of AVFormatContext before avformat_write_header.
Why
I hit same issue today, and I found there is a log when calling av_write_trailer:
Unable to re-open output file for the second pass (faststart)
In the movenc.c implementation, we can see it needs s->url to re-open the file:
avio_flush(s->pb);
ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
"the second pass (faststart)\n", s->url);
goto end;
}

OpenNi: set Player node for OpenFileRecording

I searched on web for this problem but I didn't find a solution.
I'm starting to use samples of OpenNI to develop my application. I have not much experience with C++: I am a beginner.
I'm using SimpleSkeleton sample of OpenNI 1.5.4 which returns head position. I need it but using an ONI file which I got recording using NiViewer, and not the stream data from kinect.
Searching on web I found:
xn::Context context;
xn::Player player;
nRetVal = context.Init();
nRetVal=context.OpenFileRecording("Myfile.oni",player);
if (nRetVal != XN_STATUS_OK)
{
printf("Can't open recording file: %s\n",xnGetStatusString(nRetVal));
return 1;
}
My code enter the if loop, print 'Can't open my file.oni ...' and doesn't continue running.
I think the problem is to set player object. How can I do? Or what have I to do?
Without the lines:
nRetVal=context.OpenFileRecording("Myfile.oni",player);
if (nRetVal != XN_STATUS_OK)
{
printf("Can't open recording file: %s\n",xnGetStatusString(nRetVal));
return 1;
}
it runs correctly but use data stream from kinect and not from file.
Even if it seems like it's not, this is a path issue.
I had a similar problem, you're either passing it to OpenNI in a way it does no like, or the path is not valid.
How are you retrieving the path? Trying using boost to get the current-directory and then appending the .oni file name to that string