Metadata of audio file - c++

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?

Related

TagLib - Segfault when fetching tag

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.

Json serializing in C++ (ESP32)

I'm writing some script for ESP32 and struggling to serialize a json.
Used libraries are HTTPClient and ArduinoJson.
String payload = http.getString();
Serial.println(payload);
deserializeJson(result, payload);
const char* usuario = result["user"];
Serial.println("##########");
Serial.println(usuario);
The received payload is:
{"ip":"10.57.39.137","area":"[{\"id\":\"3\",\"text\":\"BOX\"}]","user":"[{\"id\":\"6270\",\"text\":\"ANDRE LARA OLIVEIRA E SILVA\"}]","teamId":6,"id":4,"siteId":2,"userCreate":"100059527","dateCreate":"2020-11-19T08:49:03.957","userUpdate":null,"dateUpdate":null}
I need to retrieve id and text from "user" key. It's fine to deserialize and retrieve user object. But result["user"] returns: [{"id":"6270","text":"ANDRE LARA OLIVEIRA E SILVA"}] to the char array. So it's something like a json nested in an array... and it's not working out to deserialize.
Can anyone help me how to properly get the "id" and "text" values from "user" object?
The library doesn't know the content of that string is valid JSON, so you have re-parse it. This code worked for me on my PC, though I don't have an Arduino to test it on:
auto payload = "..."; // JSON content here
StaticJsonDocument<1024> result;
deserializeJson(result, payload);
auto user = result["user"].as<const char*>();
StaticJsonDocument<256> userObj;
deserializeJson(userObj, user);
auto id = userObj[0]["id"].as<int>();
auto text = userObj[0]["text"].as<const char*>();
"Can anyone help me how to properly get the "id" and "text" values from "user" object?" You can access them with
const char *id = result["user"]["id"];
const char *text = result["user"]["text"];
Try:
const int id = result["user"]["id"];
const char* text = result["user"]["text"];

protobuf C++ SQLite handle blob data

I have a SQLite database which has a table which contains some fields of BLOB type.
What I am trying to do is fetch the field (in fact all other fields too) from the database into C++ send it through protobuf and receive the protobuf .
I have defined the blob fields as bytes in the .proto file
For example
message fields{
...
bytes myBlobField = 1;
}
My c++ file contains
sqlite3_initialize();
rc = sqlite3_open_v2(db_url, &db,SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,NULL);
std::ostringstream oss;
oss << "select * from attribtable ";
std::string query = oss.str();
rc = sqlite3_prepare_v2(db,query.c_str(),-1,&stmt,NULL
while(sqlite3_step(stmt) == SQLITE_ROW){
sqlite3_column_blob(stmt,10) //This is the blob field
}
How do I store the sqlite3_column_blob(stmt,10) in C++ and how do I set myBlobField using
say reply->set_myblobfield(??)
and receive on the client side using
say receive->get_myblobfield()
So in simple words my question is how do I send the blobfield fetched from database, through protobuf, from server to client in a C++ application?
Using this .proto file
syntax = "proto2";
package prototest;
message fields{
required bytes myBlobField = 1;
}
You initialize the blob using the set_myblobfield() call with the blob pointer and the byte size of the blob which you get from SQLite and then call the SerializeToOstream() method to write it to a stream or to a file.
std::ofstream myoutput("myoutput.bin");
while (sqlite3_step(stmt) == SQLITE_ROW)
{
if (size_t blobSize = sqlite3_column_bytes(stmt, 10))
{
if (const void* blob = sqlite3_column_blob(stmt, 10))
{
prototest::fields myfields;
myfields.set_myblobfield(blob, blobSize);
myfields.SerializeToOstream(&myoutput);
}
}
}

CSV File to Salesforce records

I have a custom object Employee with fields below. The employee data is maintained in an external system which is sending a base64 encoded string of the csv extract by calling a web service.
I am able to decode the string by using EncodingUtil.base64Decode(). My question is how can I prepare inserts from the decoded base64 string in Salesforce custom object.
String File = 'U25vLE5hbWUsTGFzdCBOYW1lLEVtcCBJZCxKb2IgRnVuY3Rpb24NCjEsU2FjaGluLENob3VyYXNpeWEsMzMwLEJ1c2luZXNzDQoyLFJhamF0ICxTYXhlbmEgLDMzNCxGdW5jdGlvbmFsDQo=';
String myFile = EncodingUtil.base64Decode(file).toString();
System.debug('Sachin'+'['+ myFile + ']');
Debug logs
I found an answer by myself. Please take a look and provide feedback.
String File = 'U25vLE5hbWUsTGFzdCBOYW1lLEVtcCBJZCxKb2IgRnVuY3Rpb24NCjEsU2FjaGluLENob3VyYXNpeWEsMzMwLEJ1c2luZXNzDQoyLFJhamF0ICxTYXhlbmEgLDMzNCxGdW5jdGlvbmFsDQo=';
String myFile = EncodingUtil.base64Decode(file).toString();
System.debug('Sachin'+'['+ myFile + ']');
List<String> EmployeeList = new List<String>();
EmployeeList = myFile.split('\n');
List<Employee__c> employeeInsertList = new List<Employee__c>();
for (String employee : EmployeeList)
{
List<String> fields = new List<String>();
fields = employee.split(',');
Employee__c empRecord = new Employee__c();
empRecord.LastName__c = fields[2];
empRecord.Name = fields[1];
empRecord.EmpId__c = fields[3];
empRecord.Job_Function__c = fields[4];
employeeInsertList.add(empRecord);
}
System.debug('Employee List is '+employeeInsertList);
insert employeeInsertList;

c++ How to serialize class to json and parse the json file?

I have an xObject Class which basically is a trivial "Person" Class and I want to be able to serialize the whole class to a .json file, and then read that file in order to be able to extract the variables from the file and link those variables to the name of the class.
So for example:
xObject Class Code:
class xObject{
string name;
string lastname;
int age;
public:
string getName(){
return name;
}
string getLastname(){
return lastname;
}
int getAge(){
return age;
}
}
And then I create an object with some attributes on it.
int main(){
xObject homer;
homer.name = "Homer";
homer.lastname = "Simpson";
homer.age = 30;
//SERIALIZATION OF HOMER.
homer.serialExport("File.json")
return 0;
}
So now, my File.json should look like this:
{"homer" :
{"name" : "Homer"
"lastname" : "Simpson"
"age" : 30
}
}
and then, I want to be able to read from the file to extract data from it with something like this:
int main(){
xObject bart;
bart.name = "Bart";
//ACTUAL USE OF THE .JSON FILE HERE
myFile = ("File.json");
bart.lastname = Deserializer(myFile).getLastname(); //It is supossed to assign "Simpson"
//to the lastname reading from the serialized
//homer class file described above.
bart.age = Deserializer(myFile).getAge() - 20; //Sets homer's age minus 20 years.
return 0;
}
So, how can I do that on c++? (Libraries implementation accepted)
And how could I retrieve the class name that has been serialized?
For example Deserialize(myFile).getClassName() should return "homer"
I've done something similar in java with XML serialization, and it was pretty straight forward, but it seems that in C++ this is not very easy to do, and I'm relatively new to C++.
In c++ there is not introspection/reflection, so you can't automatically serialize a class without explicitly write your member variables in your stream. For the same reason, you can't retrieved the class name that have been serialized.
So the solution is to write a function in your class that serializes the member variables you want.
Of course you will not reinvent the wheel to format your file in json. You can use: https://github.com/open-source-parsers/jsoncpp.
For instance you can write:
Json::Value root;
root["homer"]["name"]="Homer";
root["homer"]["lastname"]="Simpson";
//etc
ofstream file;
file.open("File.json");
file << root;
file.close();
However, for the read, you can do as you wanted:
Json::Value root2;
ifstream file2;
file2.open("File.json");
file2 >> root2;
file2.close();
xObject homer;
homer.lastname = root2["homer"]["lastname"].toStyledString();
//etc
Of course your attribute has to be public. Otherwise you need to add a setter function.