David Andersson skrev:Om du berättar vad den egentliga problemet är kanske vi kan ge ett bättre svar.
Jag brukar undvika att göra det, eftersom en del tolkar det som att man vill att andra ska skriva ens program åt en… Därför brukar jag bara försöka skapa något enkelt exempel som belyser just den del av det hela där jag för tillfället har svårt att hitta en optimal lösning.
Men eftersom du frågar tänker jag skriva ett litet program som läser in en ljudfil (valfritt format så länge det stöds av libsndfile, men i mitt fall kommer det till nästan 100% att röra sig om FLAC-filer) och agerar brickwall-limiter på den (bland annat).
Programmet ska leta efter toppar som överskrider en viss nivå. När en sådan hittas, ska en ”envelope” påföras signalen så att den högsta nivån istället landar PÅ den givna nivån. Så när jag hittar en topp kommer ett antal värden före toppen att påverkas, likaså ett antal värden efter toppen.
Oftast skulle det funka bra att bara läsa in hela filen i bufferten, men det KAN ju hända att man någon gång har spelat in en hel konsert som en enda FLAC-fil eller av någon annan anledning har att göra med riktigt långa filer.
I och för sig spelar det kanske inte någon större roll, mer än att datorn börjar skriva på hårddisken när internminnet inte räcker till. Hade kanske för höga ambitioner, men buffertlösningen känns ändå som att man gör rätt från början, även om det kan vara lite klurigt att få till det…
Jag skulle kanske i teorin kunna använda en länkad lista, men de funktioner som står till förfogande i libsndfile går ut på att man anger en pekare till en buffert som parameter samt buffertens storlek med mera, och funktionen fyller då på bufferten. Tänkte att det var lämpligt att försöka utnyttja detta…
Jag kan inte i dagsläget se att det finns något sätt att i förväg ta reda på hur stor bufferten behöver vara för att hela filens ljuddata ska få plats, med mindre än att läsa igenom hela filen i förväg, och det är ju kanske inte det första man kommer att tänka på när man är ute efter en snabb och effektiv lösning. Jag har studerat WAV-filer lite, även om det var ett tag sedan, och i dessa framgår hur många bytes ljuddata som finns sparade, men det är möjligt att motsvarande information inte finns tillgängliga i filer av övriga format som stöds av libsndfile.
Man kan ju förstås ha en viss buffertstorlek till att börja med som man sedan utökar i steg tills man nått filslutet. Då har man hela låten i minnet och kan göra vad tusan man vill fram och tillbaka hur som helst, men man måste ju helst då ha tillräckligt mycket minne i burken så att den inte börjar larva sig med hårddisken.
En låt på 5 minuter, två kanaler, tre bytes per sampel (24 bitar) och 44,1 kHz samplingsfrekvens tar ju upp cirka 79 MB (riktiga MB alltså, det vill säga 79·10⁶ bytes) så det borde ju inte vara några problem så länge det gäller vanliga låtar och inte exempelvis inspelning av Beethovens nia eller liknande.
Det är ju rena ljuddata man hanterar, det vill säga sampel för sampel, så det spelar ingen roll vilket format filen har, Ogg Vorbis, mp3, FLAC, vad som helst, allt ”extraheras” automatiskt av libsndfile till rena ljuddata. Så klart. Annars var det ju inte mycket bevänt med det hela…
Och apropå Beethovens nia, om någon inte redan visste, så var den den som utgjorde ett av kraven när de olika parametrarna för CD skulle fastställas en gång i tiden. Det var inte ljudkvaliteten som kom först, utan det var tydligen väldigt viktigt att Beethovens nia skulle få plats på en CD. Beroende på hur fort man spelar brukar den ligga på runt 70 minuter, så jag antar att man ville ta till några minuter extra för säkerhets skull, när de bestämde sig för 74 minuter (något som sedan dess utökats efter hand). Sedan var det bara att ta hänsyn till vad dåtidens teknik tillät, därav att skivan blev 120 mm i diameter (Sonys variant – Philips variant var faktiskt bara 115 mm), 16 bitars upplösning (Philips: 14 bitar) och 44,1 kHz samplingsfrekvens.