Seite 1 von 1

mehrspuriges Wave-File

Verfasst: 9. Juni 2012 16:55
von RogerWilco
Hallo,

vielleicht könnt Ihr mir einen Tipp geben:
Ich möchte die einzelnen Spuren eines wav auslesen und später als csv Datei ausgeben, also praktisch konvertieren.
Nun ist es ja so, daß die Anzahl der Spuren erst zur Laufzeit bekannt ist.
Aus lange vergangener Zeit weiß ich noch, daß man dafür in C dynamische Arrays mit Zeiger auf Zeiger benutzte.

Bietet mir QVector da eine bessere Alternative? Zumindest eindimensional wäre man durch append unbeschränkt.
Man müßte also einen QVector mit QVector-Elementen erzeugen?
Oder gibt es etwas elegenateres? Vielleicht auch QList? Oder doch wieder etwas selbstgebautes wie damals in C?

Vielen Dank für Eure Tipps.

Re: mehrspuriges Wave-File

Verfasst: 11. Juni 2012 10:34
von Scary Hallo
QVerctor ist angeblich schneller. Aber das ist schon das, was Du suchst. Und eigentlich auch 'easy to use'. Einfach einen QVector anlegen mit dem Typ was in die Liste soll.
z.B. wenn Du eine Liste aus Strings willst oder deiner eigenen Klasse

Code: Alles auswählen

QVector<QString> stringVector;
oder

Code: Alles auswählen

QVector<MeineKlasse> myVector;
Die Elemente kannst (z.B.) Du einfach mit dem '<<'-Operator in die liste schieben.
Zum auslesen kannst Du u.a. das 'foreach'-Makro nehmen:

Code: Alles auswählen

foreach (QString str, stringVector)
     qDebug() << str;

Re: mehrspuriges Wave-File

Verfasst: 11. Juni 2012 13:20
von RogerWilco
Vielen Dank!
Aber eine Frage bleibt:
Ich weiss vorher nicht, wie viele Kanäle das Wavefile hat.
D.h. ich müßte ein dynamisches Array von QVector anlegen, oder?

Re: mehrspuriges Wave-File

Verfasst: 11. Juni 2012 14:12
von franzf
Banal gesagt: QVector ist ein Wrapper um ein dynamisches Array. QList ist etwas spezieller (lies dir die Doku dazu durch).
Ich verstehe aber nicht, wie du von "mehrspurig" auf "dynamisches Array von QVector" kommst. Ist bei dir eine Spur nicht durch eine eigene Klasse repräsentiert? Dann könntest du doch ganz einfach für die Repräsentation deiner Daten des mehrspurigen WAV-files einen QVector<Spur> verwenden (ein WAV ist doch kein 3-dimensionales Konstrukt, oder?).

Re: mehrspuriges Wave-File

Verfasst: 11. Juni 2012 15:07
von Scary Hallo
RogerWilco hat geschrieben: Ich weiss vorher nicht, wie viele Kanäle das Wavefile hat.
Genau dafür gibt es ja QVector. Du musst nur den Typ wissen, den Du im Vector speichern willst.
Oder willst Du auch Deine einzelnen Kanäle in einen Vector speichern? Dann musst Du einen Vector aus Vectoren nehmen.
Also in etwa so:

Code: Alles auswählen

QVector<QVector<int> > myList
oder

Code: Alles auswählen

 QVector<QVector<int>* > myList
Neue Werte kannst Du zur Laufzeit mit append oder mit '<<' einfach hinten anhängen.

Re: mehrspuriges Wave-File

Verfasst: 11. Juni 2012 23:13
von RogerWilco

Code: Alles auswählen

QVector<QVector<int> > myList
Das ist dann das was ich meinte.
So könnte jeder Kanal einen eigenen QVector haben, in dem dann die Einzelwerte als QVector gespeichert sind...

Wenn man nur Stereodateien verwenden würde, wäre das alles kein Problem. Das Problem ist, dass ein Wavefile mehr als nur 2 Stereokanäle enthalten kann.

Ganz klar ist mir das aber noch nicht.
Denn wenn ich jetzt append benutze, hänge ich doch an den äußeren Vektor ein Element an.
Wie komme ich denn dann an den Vektor mit den Int-Werten?

Re: mehrspuriges Wave-File

Verfasst: 12. Juni 2012 09:36
von Scary Hallo
Ich denke so. Z.B. Willst Du etwas in der 3. Spur anfügen.

Code: Alles auswählen

myList.at(2).append(myInt)
Also 'at()' liefert Dir den inneren Vector und dort kannst Du was anhängen.

Verbessert mich bitte jemand, falls ich Mist verzapfe. ;-)

Re: mehrspuriges Wave-File

Verfasst: 12. Juni 2012 10:13
von franzf
Scary Hallo hat geschrieben:Verbessert mich bitte jemand, falls ich Mist verzapfe. ;-)
Gerne. at() liefert nur nen const T, ein append() darauf wird der Compiler anmeckern.

Ich möchte hier aber meinen Hinweis nach einer ordentlichen objektorientierten Herangehensweise unterstreichen. Es ist aufwändig, unübersichtlich und fehleranfällig, solche Konstrukte (mehrdimensionale Arrays) zu verwenden. Dass du rigendwann über die Grenzen eines Arrays (QVector) hinausschießt ist äußerst wahrscheinlich.

Re: mehrspuriges Wave-File

Verfasst: 12. Juni 2012 12:02
von Scary Hallo
franzf hat geschrieben: Gerne. at() liefert nur nen const T, ein append() darauf wird der Compiler anmeckern.
OK, sorry, geht wohl doch nicht ganz so einfach.
franzf hat geschrieben: Ich möchte hier aber meinen Hinweis nach einer ordentlichen objektorientierten Herangehensweise unterstreichen.
Da gebe ich Dir zu 100% recht.

Re: mehrspuriges Wave-File

Verfasst: 12. Juni 2012 12:14
von franzf
Scary Hallo hat geschrieben:
franzf hat geschrieben: Gerne. at() liefert nur nen const T, ein append() darauf wird der Compiler anmeckern.
OK, sorry, geht wohl doch nicht ganz so einfach.
operator [ ] gibts als const und nonconst :)

Re: mehrspuriges Wave-File

Verfasst: 12. Juni 2012 14:12
von RogerWilco
Beruhigend, dass meine Anfängerfrage die Profis spaletet...
:)
Aber was mach ich jetzt mit der Info? :cry:

Re: mehrspuriges Wave-File

Verfasst: 12. Juni 2012 16:34
von Scary Hallo
Falsch! Ich bin KEIN Profi. Und es spaltet auch nicht, franzf hat recht. Deshalb auch mein Fehler.
Also wenn Du es unbedigt mit einem QVector machen willst. Dann in etwa so:

Code: Alles auswählen

   QVector<QVector<int> > vecOfVecs;

    vecOfVecs << QVector<int>() << QVector<int>() << QVector<int>(); // soviele Du willst

    vecOfVecs[0].push_back(123);
    vecOfVecs[0].push_back(23452345);
    //...
    vecOfVecs[1].push_back(2345);

    vecOfVecs[2].push_back(8654);
    vecOfVecs[2].push_back(8644);
    vecOfVecs[2].push_back(454);
    vecOfVecs[2].push_back(453544);

    //... << Hier mal ein breakpoint setzen und anschauen was Du hast
Aber franzf hat auch recht, dass ein ein objektorientierter Ansatz besser ist.

Re: mehrspuriges Wave-File

Verfasst: 13. Juni 2012 18:14
von RHBaum
du kannst getrost mit vectoren arbeiten, aber du musst einiges bedenken.
Deine Wav files koennen sehr gross werden ... es passt nicht alles in den Speicher.(32 Bit BS sind meist auf 2GB (0x7FFFFFFF Bytes) beschränkt)
auch wenn Du 2GB RAM frei hasst, heisst es nicht das du den am Stueck bekommst ^^
Speicher in groessenordnungen!im RAM umherkopieren kostet auch Zeit !!!

Deswegen bei der Speicherverwaltung vorsicht walten lassen ....

Arrays die Mengen schlucken niemals "reallokieren" lassen !
Also immer gleich in der richtigen groesse Bauen ... push_back aus sicherheitsgruenden vermeiden ...

Beispiel,

Code: Alles auswählen

std::vector<char> myBuffer(4096,0); // 4096 Byte voll mit 0 ! 
mystream.read(&myBuffer[0],myBuffer.size()); /// liest 4096 byte, falls vorhanden, in den Buffer
Wobei richtige Typen schon besser sind wie das generische char ...

Code: Alles auswählen

struct myStructT
{
     __int16 v1;
     __int16 v2;
};
std::vector<myStructT> myBuffer(4096,myStructT()); // 4096 Structs  befuellt mit was nicht initialisierten, also datenmuell  ! 
mystream.read(&myBuffer[0],myBuffer.size() * sizeof(myStructT)); /// liest 4096 Structs  , falls vorhanden, in den Buffer ! 
statt std::vector kannst auch QVector nehmen, das impliziete sharing sollte dir keine probleme machen, aber auch nix bringen, weil von haus aus kopien vermeiden solltest.
statt QVector<char> (unspezifiziertes array mit daten, oder ASCII bytestrom) solltest aber die Spezialierung QByteArray nehmen ...
Bei der Arbeit mit QFile versuchen das read vermeiden, sondern lieber in nen typisierten vector reinschreiben lassen ...

einmal allocierte Vectoren nicht immer gleich wieder verwerfen, sondern ueberschreiben und wiederverwenden ...

So kommst auch mit grossen datenmengen zurecht ...

Ob du es brauchst iss ne andere frage ...
fuers "Konvertieren" in einzelne Werte und rauschreiben ins csv kannst aber genau so gut auf dem File rumrutschen ...
und nur kleine "datenaetze" einlesen ... ist ned sooo viel langsamer, aber die sparst hauptspeicher. der lesezugriff ist eh gepuffert ... da die daten am stueck im file liegen, musst sowieso nicht oft neu positionieren (seekg)

Ciao ...