mehrspuriges Wave-File

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
RogerWilco
Beiträge: 61
Registriert: 26. November 2009 00:08
Kontaktdaten:

mehrspuriges Wave-File

Beitrag 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.
Scary Hallo

Re: mehrspuriges Wave-File

Beitrag 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;
RogerWilco
Beiträge: 61
Registriert: 26. November 2009 00:08
Kontaktdaten:

Re: mehrspuriges Wave-File

Beitrag 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?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: mehrspuriges Wave-File

Beitrag 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?).
Scary Hallo

Re: mehrspuriges Wave-File

Beitrag 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.
RogerWilco
Beiträge: 61
Registriert: 26. November 2009 00:08
Kontaktdaten:

Re: mehrspuriges Wave-File

Beitrag 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?
Scary Hallo

Re: mehrspuriges Wave-File

Beitrag 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. ;-)
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: mehrspuriges Wave-File

Beitrag 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.
Scary Hallo

Re: mehrspuriges Wave-File

Beitrag 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.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: mehrspuriges Wave-File

Beitrag 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 :)
RogerWilco
Beiträge: 61
Registriert: 26. November 2009 00:08
Kontaktdaten:

Re: mehrspuriges Wave-File

Beitrag von RogerWilco »

Beruhigend, dass meine Anfängerfrage die Profis spaletet...
:)
Aber was mach ich jetzt mit der Info? :cry:
Scary Hallo

Re: mehrspuriges Wave-File

Beitrag 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.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: mehrspuriges Wave-File

Beitrag 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 ...
Antworten