I'm using TagLib
to get tags from audio files for my application that I'm making using wxWidgets. I have set it up to fetch multiple tags like artist, title, album and all, some files load fine, but some when loaded crashes my application and gives error saying,
./build.sh: line 12: 5891 Segmentation fault ./SampleBrowser
I tried running with GDB
,
Thread 1 "SampleBrowser" received signal SIGSEGV, Segmentation fault.
Browser::AddSamples (this=0x555555a73e00, file=...) at ../src/Browser.cpp:248
248 std::string Artist = File.tag()->artist().to8Bit(true);
(gdb)
Here is the function that is responsible for fetching tags,
void Browser::AddSamples(wxString file)
{
TagLib::FileRef f (static_cast<const char*>(file), true, TagLib::AudioProperties::ReadStyle::Average);
if (!f.isNull() && f.tag() && f.audioProperties())
{
TagLib::Tag* tag = f.tag();
TagLib::AudioProperties* properties = f.audioProperties();
TagLib::String Artist = tag->artist();
TagLib::String Album = tag->album();
TagLib::String Genre = tag->genre();
TagLib::String Title = tag->title();
TagLib::String Comment = tag->comment();
int seconds = properties->length() % 60;
int minutes = (properties->length() - seconds) / 60;
int Bitrate = properties->bitrate();
int Channels = properties->channels();
int Length = properties->lengthInMilliseconds();
int LengthSec = properties->lengthInSeconds();
int SampleRate = properties->sampleRate();
wxString Path = file;
wxString Filename = file.AfterLast('/').BeforeLast('.');
Data.clear();
Data.push_back(false);
Data.push_back(Filename);
Data.push_back(wxString::FromUTF8(Artist.toCString(true)));
Data.push_back(wxString::Format("%d", Channels));
Data.push_back(wxString::Format("%d", Length));
Data.push_back(wxString::Format("%d", SampleRate));
Data.push_back(wxString::Format("%d", Bitrate));
Data.push_back(wxString::FromUTF8(Comment.toCString(true)));
SampleListView->AppendItem(Data);
db.InsertSample(0, Filename.ToStdString(), Artist.to8Bit(true),
Channels, Length, SampleRate, Bitrate,
Comment.to8Bit(true), Path.ToStdString());
}
else
{
for (int i = 0; i < f.isNull(); i++)
{
const wxString& msg = wxString::Format("Error! Cannot open file %s", f.file()->name());
wxMessageDialog *msgDialog = new wxMessageDialog(NULL, msg, "Error", wxOK | wxICON_ERROR);
msgDialog->ShowModal();
}
}
}
I have this AddSamples()
, that I call inside 2 other functions, as I have different ways of adding files to my application, via drag and drop and by file browser inside the application, both of which uses this AddSamples()
to get tags and insert them in the wxDataViewListCtrl
and SQLite3
database. file
here is the parameter passed in the function, which is of wxString
type. I am able to successfully add files to the application using AddSamples()
, but say there are 5 files in a directory, 3 will add fine, but other 2 crashes the application and causes segmentation fault.
As you can see, there are 30 files in the directory, Kick 001
and Kick 006
fails to add to the application. I tried opening those 2 files in a audio player, it plays fine, file is not corrupt. Also say user drags and drops 1000+ files at once, a lot of files are going to fail to be added this way.