[Delphi] WAV file inlezen en splitten

Pagina: 1
Acties:

  • Jeroennl
  • Registratie: Januari 2004
  • Laatst online: 09:07
Na aanleiding van een stukje software ben ik aan het uitzoeken hoe ik dit het beste kan doen. Ik moet namelijk de WAV file afknippen op een aantal seconden. En erna een aantal stille seconden achter plakken. Dit lukt allemaal wel.

Alleen ik kan dus nergens iets vinden over hoe ik een WAV file split en deze opsla in een var tijdelijk.

Iemand die weet hoe dit moet of waar ik dat wel kan vinden?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Jeroennl schreef op maandag 12 februari 2007 @ 18:12:
Na aanleiding van een stukje software ben ik aan het uitzoeken hoe ik dit het beste kan doen. Ik moet namelijk de WAV file afknippen op een aantal seconden. En erna een aantal stille seconden achter plakken. Dit lukt allemaal wel.
Maar je weet niet hoe je 'm opslaat in een var? Hoe doe je het dan? En waarom kun je die methode dan niet toepassen met "splitten"?

Ten eerste wil je een wav waarschijnlijk niet in "een var" maar wil je werken met een file pointer ofzo (omdat wav's nogal eens groot kunnen worden) ;)
Als je toch met "een var" wil werken, wat dacht je dan van gewoon het juiste type gebruiken? Een WAV is (zo uit m'n blote bol) een bult signed integers, dus een array van integers? ;)

Nog mooier is het natuurlijk als je met een combinatie van die twee werkt met een struct ofzo (geen idee hoe dat in Delhi heet).

Tot slot is er voldoende te vinden over het WAV formaat lijkt me?

[ Voor 24% gewijzigd door RobIII op 13-02-2007 00:43 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Jeroennl
  • Registratie: Januari 2004
  • Laatst online: 09:07
Het opslaan weet ik wel var is natuurlijk verkeerd gekozen. Alleen het splitten is nu juist het probleem. Dit weet ik niet en kan ik ook niet vinden.

De info over het WAV formaat is me ook gewoon duidelijk. Alleen hoe splits ik zo'n file...

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Jeroennl schreef op maandag 12 februari 2007 @ 18:43:
Het opslaan weet ik wel var is natuurlijk verkeerd gekozen.
Nou, mij ben je kwijt, ik snap er niets van :D
Jeroennl schreef op maandag 12 februari 2007 @ 18:43:
Alleen het splitten is nu juist het probleem. Dit weet ik niet en kan ik ook niet vinden.
Met splitten bedoel je toch gewoon "in x stukken hakken naar y files" ofzo, niet?
Jeroennl schreef op maandag 12 februari 2007 @ 18:43:
De info over het WAV formaat is me ook gewoon duidelijk. Alleen hoe splits ik zo'n file...
Je spreekt jezelf tegen? Je weet hoe zo'n file in elkaar steekt, maar weet niet dat je dan her en der wat headers moet aanpassen met de nieuwe lengte (na splitsen dus) e.d.?
Je kunt toch gewoon x.wav inlezen en de helft wegschrijven in a.wav en de andere helft in b.wav met gecorrigeerde headers? Of mis ik nu iets?

[ Voor 7% gewijzigd door RobIII op 12-02-2007 18:47 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Depress
  • Registratie: Mei 2005
  • Laatst online: 24-11 21:01
Dat bedoelt hij denk ik. Maar hij heeft geen idee hoe hij dat moet doen denk ik.

Je hebt een read-stream nodig, en write stream. En daarbij is het volgens mij ook nog eens zo dat delphi dat automagisch doet, het aanpassen van de headers. Want ik splitste laatst een mp3tje en alle gesplitte stukken kon ik gewoon nog afspelen.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Depress schreef op maandag 12 februari 2007 @ 19:28:
En daarbij is het volgens mij ook nog eens zo dat delphi dat automagisch doet, het aanpassen van de headers. Want ik splitste laatst een mp3tje en alle gesplitte stukken kon ik gewoon nog afspelen.
Dat hangt er vanaf waarmee je gesplit hebt; een standaard stream zal dat niet doen. Dat een wav/mp3 zonder correcte headers toch nog goed afspeelt wil niet zeggen dat je bestand (technisch) correct in elkaar steekt ;) Je kunt idd een MP3/wav doodleuk in 2-en hakken en doorgaans zal dat prima afspelen (misschien een tikje op 't begin/eind). Maar dat maakt het niet juist ;) Daarnaast is een MP3 geen WAV en kun je dat simpelweg niet vergelijken.

[ Voor 4% gewijzigd door RobIII op 12-02-2007 19:31 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Depress
  • Registratie: Mei 2005
  • Laatst online: 24-11 21:01
True.

Maar dan word ik ook nieuwsgierig. Hoe ga je die headers dan weer bijvoegen?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Depress schreef op maandag 12 februari 2007 @ 19:41:
True.

Maar dan word ik ook nieuwsgierig. Hoe ga je die headers dan weer bijvoegen?
Het formaat is bekend :? Dan schrijf je die toch zelf in het bestand :?
We zitten hier toch in PRG of ben ik nou verdwaald? :X

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Depress
  • Registratie: Mei 2005
  • Laatst online: 24-11 21:01
Ja goh, dat snap ik. Maar hoe achterhaal je die.
Neem niet aan dat 'filestream.GetHeaders' volstaat.

Hier trouwens de splitter waar ik toen mee werkte.
http://www.nldelphi.com/Forum/showthread.php?t=16771

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Depress schreef op maandag 12 februari 2007 @ 19:43:
Ja goh, dat snap ik. Maar hoe achterhaal je die.
Neem niet aan dat 'filestream.GetHeaders' volstaat.
Ik ben niet bekend met Delphi ofzo, maar als je gewoon een binair bestand kunt schrijven dan kun je toch gewoon "headers" (is ook gewoon maar een bult bytes) schrijven? En uiteraard is dat per bestandstype nogal afhankelijk van het bestandstype; wiedes dat daar geen standaard method voor is.
Ik heb de code niet bekeken, maar likely dat dit ding inderdaad doodleuk een bestand in 2en hakt.

Als je een bestand hebt (of dat nou wav of MP3 is) met blok-headers (H), file-headers (F) en data (X) dat er zo uit ziet:

code:
1
FHXXXXXXHXXXXXXHXXXXXXHXXXXXXHXXXXXX

Waarbij H (de blockheader) info bevat over het blok X-en (data) dat volgt en F over de complete file en je kapt het bestand in 2-en... dan dien je dus zowieso voor bestand 1 de F header te corrigeren (halve lengte o.a.) en bestand 2 een F header toe te voegen (genereren). In dit geval kun je dan nog de blok-headers in takt laten als je precies op een blok kapt, anders zul je die ook moeten corrigeren.

Zo moeilijk is dat toch niet?
Uiteraard dien je dus wel te weten hoe een binair bestand (en specifiek voor dat bestandstype dus) "onder water" in elkaar steekt; als je een standaard lib ergens "leent" om bestanden te splitten dan ga ik er even voor het gemak van uit dat je nog niet "onder water" bent geweest ;)

[ Voor 67% gewijzigd door RobIII op 12-02-2007 19:53 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Depress
  • Registratie: Mei 2005
  • Laatst online: 24-11 21:01
Ik heb die wel onder water gezien, en zogezegd. Die hakt het inderdaad gewoon in 2e.

Maar het is dus gewoon uitlezen dus. Vind het alleen zwak dat er geen standaard is om de boundery tussen header en data op te vangen. Is die er wel. Dan is het allemaal een stuk makkelijker, want wat ik uit jouw verhaal begrijp is het dus bij elk type anders.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Depress schreef op maandag 12 februari 2007 @ 19:58:
Maar het is dus gewoon uitlezen dus. Vind het alleen zwak dat er geen standaard is om de boundery tussen header en data op te vangen.
Dat is toch logisch dat dat voor ieder bestandstype anders is? Een MP3 is, zoals gezegd, heel iets anders dan een WAV of DOC of WMV. Het bestandstype zelf bepaalt hoeveel (en of) er file/block headers zijn, en boundaries zijn doorgaans makkelijk te berekenen als een block bijvoorbeeld een vaste grootte heeft en anders altijd makkelijk te zoeken door gewoon in het midden te beginnen en dan vooruit/achteruit te zoeken naar de eerste het beste boundary die je tegen komt.

[ Voor 31% gewijzigd door RobIII op 12-02-2007 20:35 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Verwijderd

als het om een standaard pcm-wav gaat: die header bestaat uit een aantal chuncks, en de structs records :P daarvan moeten ergens in delphi al gedefinieerd zijn, maar met google issie ook wel te vinden. moet je ff zoeken ofzo. die gewoon binair uitlezen.
na de header volgen alle samples (bij meerdere kanalen wisselen ze om en om af), zolang als aangegeven in de header. de data erna is in principe niet gespecificeerd, kan je je eigen naam in zetten ofzo :P

//ohja je moet ff opletten. samples zijn normaal signed (shorts of wat je ook wilt igv 16 bits), maar die van 8 bits zijn unsinged (chars is het makkelijkste :P) en de x-as ligt als het ware op 128. dus 128 er vanaf trekken voordat je gaat bewerken en 128 er bijop voordat je hem wegschrijven. puur bij knippen en plakken heb je daar natuurlijk geen last van.


//deze legt het wel goed uit: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/

[ Voor 33% gewijzigd door Verwijderd op 12-02-2007 20:43 ]


  • Depress
  • Registratie: Mei 2005
  • Laatst online: 24-11 21:01
RobIII schreef op maandag 12 februari 2007 @ 20:31:
[...]

Dat is toch logisch dat dat voor ieder bestandstype anders is? Een MP3 is, zoals gezegd, heel iets anders dan een WAV of DOC of WMV. Het bestandstype zelf bepaalt hoeveel (en of) er file/block headers zijn, en boundaries zijn doorgaans makkelijk te berekenen als een block bijvoorbeeld een vaste grootte heeft en anders altijd makkelijk te zoeken door gewoon in het midden te beginnen en dan vooruit/achteruit te zoeken naar de eerste het beste boundary die je tegen komt.
Wat ik bedoel is dat er standaard een boundery is om Header van data te scheiden.

Bijvoorbeeld:
H||DDDD

Waarbij dan '||' de boundery is. Dit bedoeld ik. Ik snap dat de grote van de header in elk type bestand anders is.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 14:32

Creepy

Tactical Espionage Splatterer

Er is geen standaard om een header van de body te onderscheiden. Er zijn zelf bestandsformaten waar geen boundary is maar de header bijv. een vaste grootte heeft waarna direct de data begint. Er is dus ook geen enkele standaard daarvoor te verzinnen. Dat is niet zwak, dat is gewoon zo. Als je een vaste grootte voor bepaalde zaken hebt is een boundary niet nodig en alleen maar ruimte verspilling.

Een bestand splitten en later aan elkaar plakken is vrij eenvoudig. Van een wav of een mp3 of welk ander bestand dan ook twee losse werkende stukken maken is iets anders. Je wilt in bijv. het geval van de wav twee nieuwe wav's met elk hun eigen header moeten genereren.

[ Voor 29% gewijzigd door Creepy op 12-02-2007 22:26 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

klik :)

trouwens vet dat je Delphi gebruikt. We sterven uit :P

succes

  • JochemK
  • Registratie: Maart 2003
  • Laatst online: 25-11 10:41
Ha, een delphi gebruiker :D

Wat je ongeveer wilt doen is dit:

Delphi:
1
2
3
4
5
6
7
8
 Lees RIFF-header, en onthou die ergens
 vind uit de header het aantal samples per seconde en onthou dat 
 repeat
   lees het datablok in tot het gewenste punt (samples / seconde * aantal seconde)
   maak nieuw bestandje aan
   schrijf nieuwe header weg (datalengte is kleiner geworden)
   schrijf data erachteraan
 until geen blokken meer


Wel even rekening houden met het feit dat je dit allemaal binair wilt lezen en schrijven.

Ovrigens grappig om te zien hoe makkelijk audio zich laat bewerken. stel dat je 2 signalen bij elkaar wilt voegen, het enige wat je dan hoeft te doen is de samples bij elkaar optellen, en voila. (natuurlijk wel rekening houden met je bitrate, (0grens vanaf 8bits, naar beneden ligt niet op 0 maar op 128) en met je maximum waarde (anders krijg je continue overspraak))

  • Jeroennl
  • Registratie: Januari 2004
  • Laatst online: 09:07
thnx :) Heeft me zeker een stuk geholpen dit. File leest nu ook mooi in enzo. Alleen nog ff uitvogelen waarom hij een soort "ruis" heeft.
Pagina: 1