Redare fisiere u-law in qt
-
wrote on 24 Jun 2014, 05:44 last edited by
Multumesc pentru raspuns. Am folosit-o insa se aude distorsionat. Aparent ar trebui sa fac o conversie din pcm logaritmic in liniar, insa nu am nici o idee cum as putea sa fac asta :(
-
wrote on 24 Jun 2014, 08:06 last edited by
Uite "aici":https://www.opensource.apple.com/source/tcl/tcl-87/tcl_ext/snack/snack/generic/g711.c gasesti implementare a conversiei ulaw (e si alaw, dar iei tu de acolo doar ce ai nevoie)
-
wrote on 24 Jun 2014, 12:09 last edited by
Multumesc mult!! You made my day :)
Ai idee cum as putea apela functiile acestea? Ar trebui sa le bag sub un for si sa convertesc bit cu bit?
-
wrote on 24 Jun 2014, 12:26 last edited by
Nu m-am uitat prea atent, dar asa rapid nu am vazut numai functiile cu un parametru unsigned char sau short, deci ai nevoie de un loop si in el convertesti byte cu byte (sau cate doi bytes), sau iti scri tu loop-ul intr-o functie care ia pointer la date, marime si eventual pointer la un buffer prealocat pt rezultat (ca sa nu ai new intr-o parte si delete in alta parte)
Dar uita-te si tu atent ca poate mi-a scapat mie. -
wrote on 24 Jun 2014, 13:15 last edited by
Ok. Sper sa reusesc. Multumesc mult!!
-
wrote on 25 Jun 2014, 05:55 last edited by
Am incercat sa convertesc fisierele .raw insa desi nu apar erori nu se aude nimic. Stii cumva care ar putea fi problema? Multumesc
@
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{char mResourcePath[] ="/home/linux/records/opt2.raw"; for(int i = 0;i < 256;i++){ __ast_alaw[i] = ulaw2Lin(mResourcePath[i]); } const char* data; int size; QByteArray ba(data, size); for (int i = 0; i < sizeof(__ast_alaw); i++) { ba.append((const char*)(&__ast_alaw[i]), sizeof(__ast_alaw[i])); } QBuffer audio_buffer(&ba); audio_buffer.open(QIODevice::ReadOnly); qDebug() << audio_buffer.size(); QAudioFormat format; format.setSampleSize(8); format.setSampleRate(8000); format.setChannelCount(1); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::BigEndian); format.setSampleType(QAudioFormat::UnSignedInt); QAudioOutput output(format); output.start(&audio_buffer); // ...then wait for the sound to finish QEventLoop loop; QObject::connect(&output, SIGNAL(stateChanged(QAudio::State)), &loop, SLOT(quit())); do { loop.exec(); } while(output.state() == QAudio::ActiveState);//audio_buffer.size(); }
}
short Dialog::ulaw2Lin(unsigned char u_val)
{
short t;/* Complement to obtain normal u-law value. */ u_val = ~u_val; /* * Extract and bias the quantization bits. Then * shift up by the segment number and subtract out the bias. */ t = ((u_val & QUANT_MASK) << 3) + BIAS; t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
}
@
-
wrote on 25 Jun 2014, 19:15 last edited by
Nu m-am uitat la tot codul, dar prima greseala e aici:
@ for(int i = 0;i < 256;i++){
__ast_alaw[i] = ulaw2Lin(mResourcePath[i]);
}@ in loc sa citesti din fisierul de la acel path, tu pasezi pe rand fiecare caracter al path-ului. Trebuie sa citesti datele din fisier, si datele din fisier sa le pasezi pe rand cate un byte functiei ulaw2lin.
Si mai trebuie sa ai grija cum aloci __ast_alaw (trebuie sa aloci acelasi numar ca si marimea datelor citite, dar din cate vad eu, trebuie sa fie de tipul short) -
wrote on 26 Jun 2014, 08:20 last edited by
Am reusit sa il fac sa functioneze. Singura problema e ca se aude un carait. Ai idee de ce se intampla asta?
@
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{char mResourcePath[] ="/home/dominic/testAudio/records/opt2.raw"; QFile audio_file(mResourcePath); if(audio_file.open(QIODevice::ReadOnly)) { QByteArray audio_data; QByteArray play; QBuffer audio_buffer(&play)
;
while (!audio_file.atEnd())
{audio_data = audio_file.read((qint64)160); int position = audio_file.pos(); int i = 0; for(i;i <= 160;i++){ __ast_alaw[i] = ulaw2Lin(audio_data[i]); qDebug() << i; play.append((const char*)(&__ast_alaw[i]), sizeof(__ast_alaw[i])); } } audio_file.close(); audio_buffer.open(QIODevice::ReadOnly); qDebug() << audio_buffer.size(); QAudioFormat format; format.setSampleSize(16); format.setSampleRate(8000); format.setChannelCount(1); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); QAudioOutput output(info,format); output.start(&audio_buffer); // ...then wait for the sound to finish QEventLoop loop; QObject::connect(&output, SIGNAL(stateChanged(QAudio::State)), &loop, SLOT(quit())); do { loop.exec(); } while(output.state() == QAudio::ActiveState);//audio_buffer.size(); }
}
short Dialog::ulaw2Lin(unsigned char u_val)
{
short t;
u_val = ~u_val;
t = ((u_val & QUANT_MASK) << 3) + BIAS;
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
}
@ -
wrote on 28 Jun 2014, 15:40 last edited by
Eu am testat cu un fisier dar dupa ce am aplicat functia se aud doar distorsiuni (fara functie erau ceva distorsiuni dar se auzea si ce era in fisier) - dar e posibil ca fisierul sa nu fie mu-law, pt ca acel algoritm l-am gasit in mai multe locuri, deci pare sa fie bun, poti sa postezi un link catre un fisier ok (sau daca poti urca un fisier pe dropbox sau altundeva) si o sa testez si eu.
-
wrote on 29 Jun 2014, 19:20 last edited by
Salut. Am rezolvat problema. Modul corect de apelare este urmatorul:
@
QByteArray play;
if(audio_file.open(QIODevice::ReadOnly))
{
QByteArray audio_data;
{
audio_data = audio_file.read( audio_file.size() );for( int i = 0; i < audio_data.size(); ++i) { unsigned char tmp_data = audio_data[i]; short data = ulaw2Lin(tmp_data); play.append((const char*)&data, sizeof(short)); } } } audio_file.close();
@
Multumesc mult pentru ajutor!!!
12/12