Commit fcd89683 authored by Stefan Westerfeld's avatar Stefan Westerfeld

Report mp3 loading error (if any).

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent c9cb4f7d
...@@ -23,16 +23,34 @@ struct ScopedMHandle ...@@ -23,16 +23,34 @@ struct ScopedMHandle
} }
}; };
void
mp3_init()
{
static bool mpg123_init_ok = false;
if (!mpg123_init_ok)
{
int err = mpg123_init();
if (err != MPG123_OK)
{
fprintf (stderr, "audiowmark: init mpg123 lib failed\n");
exit (1);
}
mpg123_init_ok = true;
}
}
/* there is no really simple way of detecting if something is an mp3 /* there is no really simple way of detecting if something is an mp3
* *
* so we try to decode a few frames; if that works without error the * so we try to decode a few frames; if that works without error the
* file is probably a valid mp3 * file is probably a valid mp3
*/ */
static bool bool
mp3_detect (const string& filename) mp3_detect (const string& filename)
{ {
int err = 0; int err = 0;
mp3_init();
mpg123_handle *mh = mpg123_new (NULL, &err); mpg123_handle *mh = mpg123_new (NULL, &err);
if (err != MPG123_OK) if (err != MPG123_OK)
return false; return false;
...@@ -49,6 +67,13 @@ mp3_detect (const string& filename) ...@@ -49,6 +67,13 @@ mp3_detect (const string& filename)
smh.need_close = true; smh.need_close = true;
long rate;
int channels;
int encoding;
err = mpg123_getformat (mh, &rate, &channels, &encoding);
if (err != MPG123_OK)
return false;
size_t buffer_bytes = mpg123_outblock (mh); size_t buffer_bytes = mpg123_outblock (mh);
unsigned char buffer[buffer_bytes]; unsigned char buffer[buffer_bytes];
...@@ -72,39 +97,27 @@ mp3_detect (const string& filename) ...@@ -72,39 +97,27 @@ mp3_detect (const string& filename)
return true; return true;
} }
bool string
mp3_try_load (const string& filename, WavData& wav_data) mp3_load (const string& filename, WavData& wav_data)
{ {
int err = 0; int err = 0;
static bool mpg123_init_ok = false; mp3_init();
if (!mpg123_init_ok)
{
err = mpg123_init();
if (err != MPG123_OK)
return false;
mpg123_init_ok = true;
}
const bool is_mp3 = mp3_detect (filename);
if (!is_mp3)
return false;
mpg123_handle *mh = mpg123_new (NULL, &err); mpg123_handle *mh = mpg123_new (NULL, &err);
if (err != MPG123_OK) if (err != MPG123_OK)
return false; return "mpg123_new failed";
auto smh = ScopedMHandle { mh }; // cleanup on return auto smh = ScopedMHandle { mh }; // cleanup on return
err = mpg123_param (mh, MPG123_ADD_FLAGS, MPG123_QUIET, 0); err = mpg123_param (mh, MPG123_ADD_FLAGS, MPG123_QUIET, 0);
if (err != MPG123_OK) if (err != MPG123_OK)
return false; return "setting quiet mode failed";
// allow arbitary amount of data for resync */ // allow arbitary amount of data for resync */
err = mpg123_param (mh, MPG123_RESYNC_LIMIT, -1, 0); err = mpg123_param (mh, MPG123_RESYNC_LIMIT, -1, 0);
if (err != MPG123_OK) if (err != MPG123_OK)
return false; return "setting resync limit parameter failed";
// force floating point output // force floating point output
{ {
...@@ -118,13 +131,13 @@ mp3_try_load (const string& filename, WavData& wav_data) ...@@ -118,13 +131,13 @@ mp3_try_load (const string& filename, WavData& wav_data)
{ {
err = mpg123_format (mh, rates[i], MPG123_MONO|MPG123_STEREO, MPG123_ENC_FLOAT_32); err = mpg123_format (mh, rates[i], MPG123_MONO|MPG123_STEREO, MPG123_ENC_FLOAT_32);
if (err != MPG123_OK) if (err != MPG123_OK)
return false; return mpg123_strerror (mh);
} }
} }
err = mpg123_open (mh, filename.c_str()); err = mpg123_open (mh, filename.c_str());
if (err != MPG123_OK) if (err != MPG123_OK)
return false; return mpg123_strerror (mh);
smh.need_close = true; smh.need_close = true;
...@@ -134,7 +147,7 @@ mp3_try_load (const string& filename, WavData& wav_data) ...@@ -134,7 +147,7 @@ mp3_try_load (const string& filename, WavData& wav_data)
err = mpg123_getformat (mh, &rate, &channels, &encoding); err = mpg123_getformat (mh, &rate, &channels, &encoding);
if (err != MPG123_OK) if (err != MPG123_OK)
return false; return mpg123_strerror (mh);
/* ensure that the format will not change */ /* ensure that the format will not change */
mpg123_format_none (mh); mpg123_format_none (mh);
...@@ -158,7 +171,9 @@ mp3_try_load (const string& filename, WavData& wav_data) ...@@ -158,7 +171,9 @@ mp3_try_load (const string& filename, WavData& wav_data)
} }
else if (err == MPG123_DONE) else if (err == MPG123_DONE)
{ {
break; wav_data = WavData (samples, channels, rate, 24);
return ""; /* success */
} }
else if (err == MPG123_NEED_MORE) else if (err == MPG123_NEED_MORE)
{ {
...@@ -166,10 +181,7 @@ mp3_try_load (const string& filename, WavData& wav_data) ...@@ -166,10 +181,7 @@ mp3_try_load (const string& filename, WavData& wav_data)
} }
else else
{ {
return false; return mpg123_strerror (mh);
} }
} }
wav_data = WavData (samples, channels, rate, 24);
return true;
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "wavdata.hh" #include "wavdata.hh"
bool mp3_try_load (const std::string& filename, WavData& wav_data); bool mp3_detect (const std::string& filename);
std::string mp3_load (const std::string& filename, WavData& wav_data);
#endif /* AUDIOWMARK_MP3_HH */ #endif /* AUDIOWMARK_MP3_HH */
#include "mp3.hh" #include "mp3.hh"
using std::string;
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
WavData wd; WavData wd;
if (argc >= 2) if (argc >= 2)
{ {
if (mp3_try_load (argv[1], wd)) if (mp3_detect (argv[1]))
{
string error = mp3_load (argv[1], wd);
if (error == "")
{ {
int sec = wd.n_values() / wd.n_channels() / wd.sample_rate(); int sec = wd.n_values() / wd.n_channels() / wd.sample_rate();
...@@ -19,7 +24,13 @@ main (int argc, char **argv) ...@@ -19,7 +24,13 @@ main (int argc, char **argv)
} }
else else
{ {
printf ("mp3 try load %s failed\n", argv[1]); printf ("mp3 load %s failed: %s\n", argv[1], error.c_str());
return 1;
}
}
else
{
printf ("mp3 detect %s failed\n", argv[1]);
return 1; return 1;
} }
} }
......
...@@ -36,10 +36,18 @@ WavData::load (const string& filename) ...@@ -36,10 +36,18 @@ WavData::load (const string& filename)
int error = sf_error (sndfile); int error = sf_error (sndfile);
if (error) if (error)
{ {
if (mp3_try_load (filename, *this)) if (mp3_detect (filename))
{ {
// ok, if its an mp3, take it string error = mp3_load (filename, *this);
return true; if (error == "")
{
return true; // mp3 loaded successfully
}
else
{
m_error_blurb = "mp3 load error: " + error;
return false;
}
} }
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment