TagLib - Segfault when fetching tag - c++

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 File (file);
std::string Artist = File.tag()->artist().to8Bit(true);
std::string Album = File.tag()->album().to8Bit(true);
std::string Genre = File.tag()->genre().to8Bit(true);
std::string Title = File.tag()->title().to8Bit(true);
std::string Comment = File.tag()->comment().to8Bit(true);
std::string Path = file.ToStdString();
std::string Filename = file.AfterLast('/').BeforeLast('.').ToStdString();
int Bitrate = File.audioProperties()->bitrate();
int Channels = File.audioProperties()->channels();
int Length = File.audioProperties()->lengthInMilliseconds();
int LengthSec = File.audioProperties()->lengthInSeconds();
int SampleRate = File.audioProperties()->sampleRate();
Data.clear();
Data.push_back(false);
Data.push_back(Filename);
Data.push_back(Artist);
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(Comment);
SampleListView->AppendItem(Data);
db.InsertSample(0, Filename, Artist, Channels, Length,
SampleRate, Bitrate, Comment, Path);
}
I can provide more information if needed.

Related

How do I print the generated QR code using Nayku's library in a pdf file?

I am using a third party library : https://github.com/nayuki/QR-Code-generator using c++.
So far what I have reached in my code is printing the QR code in the console.
My app generates a pdf file that I write the data entered in some line editors to. I want to add a QR code in that pdf file being generated as well.
QString Widget::generateQRCode(QString name, QString date, QString address, QString email)
{
QString data = name + date + address + email
;
const char *text = data.toUtf8().constData(); // User-supplied text
const QrCode::Ecc errCorLvl = QrCode::Ecc::LOW; // Error correction level
// Make and print the QR Code symbol
const QrCode qr = QrCode::encodeText(text, errCorLvl);
printQr(qr);
std::cout << toSvgString(qr, 4) << std::endl;
return QString::fromStdString(toSvgString(qr, 4));
}
What I want is to take the output of this function and change it into something I could use the Qpainter class with to insert it into the PDF file.
/*[7] Generate QR Code */
QString qrcode = generateQRCode(name,date,address,email);
qDebug()<<"QRCODE QRCODE QRCODE\n"<<qrcode;
painter.setPen(qRgb(0,0,0));
painter.setFont(QFont("Arial", 15, QFont::Bold));
painter.drawText(500,5000,qrcode);
}

Quicktime 7 API for Windows - couldNotResolveDataRef

I'm trying to use the Quicktime 7 API for Windows (I know) because eventually I'm going to try to change the audio channel layout flags in Quicktime files, but right now I'm simply trying to create a "Movie" object.
I'm very familiar with languages like Python and JavaScript, but very new to C++. Despite that, I'm able to get the following code to all link up and compile nicely:
#include <iostream>
#include <Movies.h>
#include <QTML.h>
int main()
{
std::string mystring = "D:/CodingProjects/testfiles/mytestfile.mov";
OSErr initerr = InitializeQTML(0L);
OSErr entererr = EnterMovies();
Movie myMovie;
short myResID;
Size mySize = (Size)strlen(mystring.c_str()) + 1;
Handle myHandle = NewHandleClear(mySize);
BlockMove(mystring.c_str(), *myHandle, mySize);
OSErr newmovieerr = NewMovieFromDataRef(&myMovie, 0, &myResID, myHandle, URLDataHandlerSubType);
}
It all seems to run well, with initerr and entererr returning 0, and the entire program also exiting with 0. The problem is in the NewMovieFromDataRef function. newmovieerr seems to be returning code -2000 and not assigning anything (0x00000000) to myMovie. After looking this up, it turns out that this error code is a Quicktime error that means "couldNotResolveDataRef".
I've also tried creating a Movie using the function NewMovieFromHandle and got the same error code.
Can anyone help me figure out what I'm doing wrong?
For anyone interested. I finally got it to work with this code.
#include <iostream>
#include <Movies.h>
#include <QTML.h>
int main()
{
std::string mystring = "D:\\CodingProjects\\_ffmpeg\\test.mov";
OSErr initerr = InitializeQTML(0L);
OSErr entererr = EnterMovies();
CFStringRef inPath = CFStringCreateWithCString(CFAllocatorGetDefault(), mystring.c_str(), CFStringGetSystemEncoding());
Movie myMovie;
short myResID;
Size mySize = (Size)strlen(mystring.c_str()) + 1;
Handle myHandle = NewHandle(mySize);
OSType myDataRefType = NULL;
OSErr datareferr = QTNewDataReferenceFromFullPathCFString(inPath, kQTWindowsPathStyle, 0, &myHandle, &myDataRefType);
OSErr newmovieerr = NewMovieFromDataRef(&myMovie, 0, &myResID, myHandle, myDataRefType);
}
A big part of it was using \\ in the path instead of /, and also using CFStringCreateWithCString to get a CFStringRef to pass into QTNewDataReferenceFromFullPathCFString to get the proper Handle and OSType to then pass into NewMovieFromDataRef.

BaseX XML database in C++ encoding issue

I work with Base X and try to integrate a XML database with c++ on Windows 7. I use the BaseXclient API from https://github.com/JohnLeM/BasexCPPAPI/
it contains the pugixml parser and uses the boost lib. I got it to work but I have issues with the encoding. The xml dokuments in my database are utf-8 and contain some letters and symbols that are not displayed correctly on console output(like ä and °).
I set the console code page with chcp 65001.
I changed the locale with std::setlocale(LC_ALL, ""); in c++ and when I cout these letters and symbols directly in my Programm and not from the database they are displayed correctly. The database output also changed but is still wrong.
I also set the pugi parser with pugi::xml_encoding::encoding_utf8; but the database output is not affected. here is a code example from the string list interface:
virtual ~my_string_list_interface() {};
my_string_list_interface(const std::string& DBHOST, const std::string& DBPORT, const std::string& DBUSER,const std::string& DBPASSWD) : base_type(DBHOST,DBPORT,DBUSER,DBPASSWD) {};
virtual my_string_list get(string query,int stage){
my_string_list my_string_list_;
pugi::xml_encoding::encoding_auto;
pugi::xml_parse_result parse_;
pugi::xml_document doc;
string results = session().execute("XQUERY "+query);
parse_ = doc.load(results.c_str());
pugi::xpath_node_set is = doc.select_nodes("/record/mid");
The API uses boost streambuf to get the data. The code from boost streambuf looks like that:
std::string read_streambuffer(){return read_streambuffer(response_);};
std::string read_streambuffer(boost::asio::streambuf & response)
{
std::string results;
boost::system::error_code error;
boost::asio::streambuf::const_buffers_type bufs = response.data();
std::size_t size(0);
std::string line;
auto ptr_b = boost::asio::buffers_begin(bufs);
for(; ptr_b != boost::asio::buffers_end(bufs); ++ptr_b, ++ size)
{if (*ptr_b != 0) {line.push_back(*ptr_b);} else if (size > 1) break; };
response.consume(size);
return line;
};
Is there a way to specify the encoding for the buffer stream or string? I use a string list for the database output. should I use wstring or is there something i missed?
Thanks!

Printing title of mp3 file

I am trying to read id3 tags with id3v2lib
My code is:
ID3v2_tag* tag = load_tag(argv[1]); // Load the full tag from the file
if(!tag){
tag = new_tag();
}
const char * t = "Matej";
ID3v2_frame* artist_frame = tag_get_artist(tag); // Get the full artist frame
ID3v2_frame* title_frame = tag_get_title(tag);
ID3v2_frame_text_content* title_content = parse_text_frame_content(title_frame);
if( title_content){
cout << title_content->data << endl;
}
This does print title of song. However, for some files it prints unreadable garbage.
I am not sure if the file is somehow corrupted. But using
eyeD3 on files that outputs garbage for title works fine.
Has anyone met with same problem? What could be the cause

Metadata of audio file

hi all i am extracting metadata of an audio file using Taglib library . i am getting many fields properly but not able to extract name of source device by which the audio file has been created. Please suggest any way to get out of it. Code used is as below
MetaData md;
const char * filename = file.c_str();
std::cout<< filename;
FileRef f((FileName(filename)));
md.filepath = file;
//if(f.isNull()) return md;
// if(!f.tag()) return md;
// if(f.tag()->isEmpty()) return md;
string artist = f.tag()->artist().toCString();
string album = f.tag()->album().toCString();
string title = f.tag()->title().toCString();//.to8Bit(true);
uint year = f.tag()->year();
uint track = f.tag()->track();
int bitrate = f.audioProperties()->bitrate();
string comment=f.tag()->comment().toCString();
string genre =f.tag()->genre().toCString();
// length in second
int lenght=f.file()->audioProperties()->length();
int channel = f.file()->audioProperties()->channels();
string name =f.file()->name();
int sampleRate=f.audioProperties()->sampleRate();
What exactly do you mean with "name of source device by which the audio file has been created"? Are you looking for the name of the person or organisation that encoded the audio file, normally saved in the TENC tag?
Could you give us an example, what you want to see?