Ik wil al mijn muziekcollectie rippen / archiveren naar een verliesvrij maar gecomprimeerd bestandsformaat, dwz de bestanden moeten allemaal perfect zijn , verliesvrije weergaven van de originele gegevens, maar zouden minder ruimte in beslag moeten nemen dan ongecomprimeerde WAV (E).
WAV (E) is een no-go, aangezien het niet-vrij is (propriëtair Microsoft-materiaal), platformonafhankelijke compressie omslachtig of niet mogelijk is en de bestandsgrootte is beperkt tot 4 GB. Daarom kies ik voor FLAC (Free Lossless Audio Codec).
Aangezien het digitaliseren van een hele collectie een gigantische taak is en FLAC 9 compressieniveaus biedt (0 tot 8), komt daar de gouden vraag :
Welk compressieniveau moet ik verstandig kiezen?
Reacties
- deze vraag heeft geen ' t betrekking op geluidsontwerp, maar het raakt wel een keuze waar sommige geluidsontwerpers mee te maken hebben, namelijk: hoe we het beste kunnen omgaan met onze steeds groter wordende bibliotheken met opnames. Persoonlijk ' ga FLAC over WAVE alleen vanwege het opslagprobleem, maar ik ' ben bang dat ik ' geen inzicht heb in het compressieniveau.
- Interessant genoeg heb ik gepost dit eerst op Music , maar de mensen daar raadden aan om het naar Sound Design te verplaatsen.
Antwoord
FLAC-compressieniveaus zijn (slechts) een wisselwerking tussen coderingstijd en bestandsgrootte . De decoderingstijd is vrijwel onafhankelijk van de compressiesnelheid. In het volgende zal ik verwijzen naar de compressieniveaus 0, …, 8 als FLAC-0, …, FLAC-8.
In het kort : ik raad FLAC-4 !
De eenvoudige oplossingen
Uiteraard:
-
Als het me niet uitmaakt om het coderen van tijd en aangezien ruimte geld is, neem ik het hoogste compressieniveau FLAC-8 .
-
Als ik niet om ruimte geef, maar hier zo snel mogelijk achter wil komen, neem ik het laagste compressieniveau FLAC-0 .
De moeilijke oplossing
Waar is de precies midden tussen bestandsgrootte en coderingstijd? Ik kwam het artikel van Nathan Zachary “s artikel tegen over deze vraag, maar hij vergelijkt slechts twee bestanden, codeert ze slechts één keer (de coderingstijd varieert enorm afhankelijk van de sideload van de computer ) en tabellen zijn moeilijk te lezen in vergelijking met grafieken.
Dus, hierdoor geïnspireerd, heb ik zijn metingen opnieuw gemaakt met vijf volledige albums elk in een ander genre en codeerde elk bestand / track 10 keer .
Procedure:
- Album rippen met
abcde
en propercdparanoia
instellingen naar ongecomprimeerde WAV. - Converteer elk bestand 10 keer voor elk compressieniveau (FLAC-0 naar FLAC-8) en neem de gemiddelde coderingstijd ten opzichte van FLAC-0 en de bestandsgrootte ten opzichte van F LAC-0 .
- Hiervoor heb ik de internetverbinding uitgeschakeld, alle periodieke taken (
cronjobs
) en bijna al het andere, zodat de compressie eigenlijk grotendeels wordt uitgevoerd en zo min mogelijk interferenties.
- Hiervoor heb ik de internetverbinding uitgeschakeld, alle periodieke taken (
Deze maatregel zou vrijwel onafhankelijk moeten zijn van de gebruikte hardware. Ik heb flac versie 1.3.2 gebruikt op Arch Linux met flac <infile> --compression-level-X -f -o flacX.flac
.
Efficiëntie
Als je de relatieve grootte met de relatieve codering / compressietijd , krijg je een waarde voor de slechtheid . Maar aangezien deze slechtheid grotendeels wordt bepaald door de relatieve tijd, zouden de grafieken elkaar enorm overlappen. Dus om de grafiek duidelijker te maken, heb ik de slechtheid gewoon gespiegeld in een goedheid , ik noem hier efficiëntie .
Bevindingen
Vanaf FLAC-4 explodeert de compressietijd MAAR er zijn twee verrassingen:
-
Er is een aanzienlijke vermindering van de bestandsgrootte tussen FLAC-3 en FLAC-4 afhankelijk van het muziekgenre: Klassieke muziek heeft een veel lagere compressie met FLAC-4. Ik neem aan dat dit komt doordat FLAC een lineair voorspellingsmodel voor compressie gebruikt dat het minder goed doet met complexere (minder lineaire) muziek.
-
Voor niet-klassieke muziek, FLAC-3 is zelfs aanzienlijk slechter dan FLAC-2 in termen van bestandsgrootte.
Aanbevelingen
Ik raad het gebruik van compressieniveau FLAC-4 .
Hoger gaan verhoogt de coderingstijd aanzienlijk met een marginale verbetering in de verkleining van de bestandsgrootte (gemiddelde vermindering van FLAC-4 naar FLAC-8 in deze test is 1,2% met een 182% toename van de gemiddelde compressietijd).
Bijlage
Albums
Ik heb zojuist de eerste vijf willekeurige cds genomen (hieronder vermeld) waarvan ik dacht dat het een ander muziekgebied vertegenwoordigde. De links gaan opzettelijk naar Amazon om een gemakkelijke mogelijkheid te bieden om een glimp op te vangen van de muziek / om een idee te krijgen van de muziek, aangezien het een significant verschil maakt in de compressie.
- Emil Gilels – Beethoven: pianosonates nrs. 21 “Waldstein”, 26 “Les Adieux” & 23 “Appassionata” ( classic)
- Karl Jenkins – The Armed Man – A Mass for Peace (klassiek, mis)
- Unni Wilhelmsen – 7 (pop, jazz, folk)
- Alin Coen Band – Wij ” re Not the Ones We Thought We Were (indie, folk, singer-songwriter)
- Bukahara – Bukahara Trio ( neofolk , balkanfolk )
Programma
Voor deze taak schreef ik een python
programma dat door alle submappen (de albums) in een bepaalde map gaat () om alle .wav-bestanden te testen en ze te groeperen / plotten op hun submapnaam.
<folder> Album 1 Album 2 ...
De analyse wordt opgeslagen in een bestand --outfile <file1>
. Gebruik --infile <file1>
en --outfile <file2>
om te plotten.
#!/usr/bin/python3 #encoding=utf8 import os, sys, subprocess, argparse from datetime import datetime, timedelta from os.path import isfile, isdir, join import numpy as np import matplotlib.pyplot as plt import pickle as pkl parser = argparse.ArgumentParser(description="Analyse flac compression and conversion time") group = parser.add_mutually_exclusive_group() group.add_argument("-d", "--directory", help="Input folder", type=str) group.add_argument("-if", "--infile", help="Plot saved stats (pickle file)", type=str) parser.add_argument("-of", "--outfile", help="Output file", type=str, required=True) parser.add_argument("-c", "--cycles", help="Number of cycles for each file", type=int, default=5) parser.add_argument("-C", "--maxcompression", help="Max compression level", type=int, default=8) args = parser.parse_args() args.maxcompression += 1 ############################################################ xlabel = "FLAC Compression Factor" ylabel_size = "Size Relative to FLAC-0" ylabel_time = "Mean Compression Time\nOver {} Cycles Relative to FLAC-0 [s]".format(args.cycles) ylabel_efficiency = r"Efficiency: $(-1)\cdot$ Fraction Time $\cdot$ Fraction Size $+ 2$" ############################################################ # Analyse and write mode if not args.infile: if isdir(args.directory): mypath = args.directory else: raise ValueError("Folder {} does not exist!".format(args.directory)) folders = [f for f in os.listdir(mypath) if isdir(join(mypath, f))] print("Found folders: {}".format(folders)) # Create temporary working folder temp_folder = "temp_{}".format(os.getpid()) if not os.path.exists(temp_folder): os.makedirs(temp_folder) # Every analysis will be storen in stats stats = {} remove = [] for folder in folders: stats[folder] = {} stats[folder]["files"] = [f for f in os.listdir(mypath+folder) if isfile(join(mypath+folder, f)) and f.endswith(".wav")] if len(stats[folder]["files"]) == 0: print("No .wav files found in {}. Skipping.".format(folder)) remove.append(folder) stats.pop(folder, None) else: stats[folder]["stats"] = np.empty([len(stats[folder]["files"]),args.maxcompression], dtype=object) # Remove empty (no .wav) folders from list for folder in remove: folders.remove(folder) totalfiles = [] for folder in folders: totalfiles += stats[folder]["files"] totalfiles = len(totalfiles) if totalfiles == 0: raise RuntimeError("No .wav files found!") totalcycles = totalfiles * args.cycles * args.maxcompression counter_cycles = 0 time_start = datetime.strptime(str(datetime.now()), "%Y-%m-%d %H:%M:%S.%f") for folder in folders: # i: 0..Nfiles # n: 0..8 files = stats[folder]["files"] for i in range(len(files)): infile = "{}/{}".format(mypath+folder,files[i]) for n in range(args.maxcompression): Dtime = [] for j in range(args.cycles): time1 = datetime.strptime(str(datetime.now()), "%Y-%m-%d %H:%M:%S.%f") subprocess.run(["flac", infile, "--compression-level-{}".format(n), "-f", "-o", "{}/flac{}.flac".format(temp_folder,n)]) time2 = datetime.strptime(str(datetime.now()), "%Y-%m-%d %H:%M:%S.%f") Dtime.append((time2-time1).total_seconds()) counter_cycles += 1 # Percentage of totalcycles status = counter_cycles/totalcycles remain_factor = (1 - status)/status time_current = datetime.strptime(str(datetime.now()), "%Y-%m-%d %H:%M:%S.%f") time_elapsed = (time_current - time_start).total_seconds() print("========================================") print("Status: {} %".format(int(100*status))) print("Estimated remaining time: {}".format(str(timedelta(seconds=int(remain_factor * time_elapsed))))) print("========================================") Dtime = np.mean(Dtime) size = os.path.getsize("{}/flac{}.flac".format(temp_folder,n)) # Array if size (regarded as constat) and mean compression time # (file1, FLAC0)(file1, FLAC1)...(file1, FLACmaxcompression) # (file2, FLAC0)(file2, FLAC1)...(file2, FLACmaxcompression) # ... stats[folder]["stats"][i,n] = (size, Dtime) for folder in folders: # Taking columnwise (for each compression level) means of size... stats[folder]["ploty_size"] = [np.mean([e[0] for e in stats[folder]["stats"][:,col]]) for col in range(np.shape(stats[folder]["stats"])[1])] # (relative to FLAC-0) stats[folder]["ploty_size"] = [i/stats[folder]["ploty_size"][0] for i in stats[folder]["ploty_size"]] # ... and mean time. stats[folder]["ploty_time"] = [np.mean([e[1] for e in stats[folder]["stats"][:,col]]) for col in range(np.shape(stats[folder]["stats"])[1])] # (relative to FLAC-0) stats[folder]["ploty_time"] = [i/stats[folder]["ploty_time"][0] for i in stats[folder]["ploty_time"]] # Rough "effectivity" estimation -size*time + 2 # Expl.: Starts at (0,1), therefore flipping with (-1) requires # + 2. Without (-1) would be "badness" stats[folder]["ploty_eff"] = [ 2 + (-1) * stats[folder]["ploty_size"][i] * stats[folder]["ploty_time"][i] for i in range(len(stats[folder]["ploty_size"]))] with open(args.outfile, "wb") as of: data = {} data["stats"] = stats data["folders"] = folders data["cycles"] = args.cycles data["maxcompression"] = args.maxcompression pkl.dump(data, of, protocol=pkl.HIGHEST_PROTOCOL) if os.path.isdir(temp_folder): subprocess.run(["rm", "-r", temp_folder]) else: with open(args.infile, "rb") as f: data = pkl.load(f) stats = data["stats"] folders = data["folders"] args.maxcompression = data["maxcompression"] args.cycles = data["cycles"] fig = plt.figure() plotx = range(args.maxcompression) pos = range(len(plotx)) ax_size = fig.add_subplot(111) ax_size.set_xticks(pos) ax_size.set_xticklabels(plotx) ax_size.set_title("FLAC compression comparison") ax_time = ax_size.twinx() ax_efficiency = ax_size.twinx() colorfracs = [i / (len(folders)-0.9) if i > 0 else 0 for i in range(len(folders))] # Actual plotting lns = [] for cfrac, folder in zip(colorfracs, folders): color = plt.cm.viridis(cfrac) l_size, = ax_size.plot(plotx, stats[folder]["ploty_size"], color=color, linestyle=":", label="Size Ratio: {}".format(folder)) l_time, = ax_time.plot(plotx, stats[folder]["ploty_time"], color=color, linestyle="--", label="Time Ratio: {}".format(folder)) l_eff, = ax_efficiency.plot(plotx, stats[folder]["ploty_eff"], color=color, linestyle="-", label="Efficiency: {}".format(folder)) lns.append(l_size) lns.append(l_time) lns.append(l_eff) ax_efficiency.spines["right"].set_position(("outward", 60)) ax_size.xaxis.grid(color=".85", linestyle="-", linewidth=.5) ax_size.set_xlabel(xlabel) ax_size.set_ylabel(ylabel_size) ax_efficiency.set_ylabel(ylabel_efficiency) ax_time.set_ylabel(ylabel_time) lgd = ax_time.legend(handles=lns, loc="upper center", bbox_to_anchor=(0.5, -.15), facecolor="#FFFFFF", prop={"family": "monospace","size": "small"}) fig.savefig(args.outfile, bbox_inches="tight", dpi=300)
Reacties
- Whoa … dit is een geweldige kwantitatieve analyse die je daar hebt gedaan! Ik waardeer het echt dat je de tijd hebt genomen om dit allemaal te doen. Kon ' t zijn niet snel geweest, maar echt geweldige resultaten. Bedankt!
Answer
Flac 0. Opslag is tegenwoordig zo goedkoop, lijkt me een goed idee … ook Flac 0 zal minder snel hikken op een langzamer systeem, omdat het decoderen minder veeleisend is om te decoderen.
Antwoord
Als vervolg op het antwoord van Suuuehgi zou ik dit ook graag willen toevoegen als je begint met een CD en het direct naar FLAC rippen, de coderingstijd doet er misschien helemaal niet toe, omdat je eerst de muziek moet rippen, wat tijd kost.
Dit is wat ik heb geprobeerd:
Met dbPowerAmp CD Ripper heb ik mijn exemplaar van Mariah Carey “s " Vrolijk Kerstalbum ". Ik heb het een keer geript op FLAC-compressieniveau 8, eenmaal op niveau 5 (standaard dbPowerAmps) en eenmaal op niveau 0.
Hier is het totaal keer voor elke rip, vanaf het klikken op start tot het einde met alle FLAC-bestanden klaar:
Level 0 = 6:19
Level 5 = 6:18
Niveau 8 = 6:23
Zoals je kunt zien, is de variantie tussen alle 3 minimaal, binnen < 5 seconden van elkaar. Terwijl ik het zag rippen en coderen, was de coderingsstatus slechts een flits op het scherm, nauwelijks geregistreerd. En terwijl ik naar het bestandssysteem keek terwijl het aan het rippen was, leek het tijdens het rippen te coderen. YMMV echter op langzamere systemen.
Wat betreft bestandsgroottes, hier zijn de geproduceerde bestandsgroottes:
Level 0 = 278 MB
Level 5 = 257 MB
Level 8 = 256 MB
Terwijl de totale rip en enc ode-tijden waren in principe hetzelfde, de bestandsgroottes waren dat niet, ECHTER, er is zeker een afnemend rendement in de latere compressieniveaus (zoals het antwoord van Suuuehgi verwijst).
Voor mij lijkt het erop dat als je beginnen met cds en hebben een degelijke pc, de tijd die nodig is om te rippen en coderen zal niet veel veranderen op basis van het FLAC-compressieniveau. De bestandsgrootte verandert echter. Ik denk dat de suggestie van dbPowerAmps van FLAC-niveau 5 als standaard een goede is. Slechts 1 MB verschil tussen FLAC 5 en FLAC 8, waar – alsof je FLAC 0 gaat, mijn voorbeeld 21 MB overtollige opslag laat zien die zou kunnen worden opgeslagen. Dat lijkt misschien niet veel, maar als je grote verzamelingen aan het rippen bent, klopt het snel (een enkel FLAC-nummer kan ongeveer die grootte hebben).
Dit werd gedaan op een desktop met een USB 2 dvd-station , gemiddeld rippen met 7x de snelheid. De specificaties van mijn desktop pc zijn een Intel Core i5-6500 CPU @ 3,2 Ghz, 16 GB RAM en een Samsung 860 EVO Sata SSD-schijf.