Jeg vil rippe / arkivere hele musikksamlingen min til et tapsfritt, men komprimert filformat, dvs. at filene alle skal være perfekte , tapsfrie representasjoner av de opprinnelige dataene, men bør ta mindre plass enn ukomprimert WAV (E).

WAV (E) er et no-go, siden det er ikke-gratis (proprietære Microsoft-ting), er plattformkompresjon tungvint eller ikke mulig, og filstørrelsen er begrenset til 4 GB. Derfor velger jeg FLAC (Free Lossless Audio Codec).

Siden digitalisering av en hel samling er en enorm oppgave og FLAC tilbyr 9 kompresjonsnivåer (0 til 8), kommer det gyldne spørsmålet :

Hvilket kompresjonsnivå skal jeg klokt velge?

Kommentarer

  • dette spørsmålet ' t adresserer lyddesign i det hele tatt, men det berører et valg som noen lyddesignere står overfor, som er, hvordan vi best kan håndtere våre stadig voksende biblioteker med opptak. Personlig går jeg ' FLAC over WAVE bare på grunn av lagringsproblemet, men jeg ' er redd jeg ikke har ' t noe innblikk i kompresjonsnivået.
  • Interessant jeg postet dette på Musikk først, men folkene der anbefalte å flytte det til lyddesign.

Svar

FLAC-kompresjonsnivåer er (bare) en handel mellom kodingstid og filstørrelse . Dekodingstiden er ganske uavhengig av kompresjonshastigheten. I det følgende vil jeg referere til kompresjonsnivåene 0, …, 8 som FLAC-0, …, FLAC-8.

Kort fortalt : Jeg anbefaler FLAC-4 !


De enkle løsningene

Tydeligvis:

  • Hvis jeg ikke bryr meg om kodingstid og siden plass er penger, tar jeg det høyeste kompresjonsnivået FLAC-8 .

  • Hvis jeg ikke bryr meg om plass, men ønsker å komme bak dette så fort som mulig, tar jeg det laveste kompresjonsnivået FLAC-0 .


Den vanskelige løsningen

Hvor er høyre midt mellom filstørrelse og kodingstid? Jeg snublet over Nathan Zacharys artikkel om dette spørsmålet, men han sammenligner bare to filer, koder dem bare en gang (kodingstiden varierer veldig i henhold til sidelasten på datamaskinen ) og tabeller er vanskelige å lese i forhold til grafer.

Så, inspirert av dette, rediderte jeg målingene hans med fem komplette album hver i en annen sjanger og kodet hver fil / spor 10 ganger .

Fremgangsmåte:

  • Riv album med abcde og riktig cdparanoia innstillinger til ukomprimert WAV.
  • Konverter hver fil 10 ganger for hvert kompresjonsnivå (FLAC-0 til FLAC-8) og ta gjennomsnittlig kodingstid i forhold til FLAC-0 og filstørrelse i forhold til F LAC-0 .
    • For dette deaktiverte jeg internettforbindelsen, alle periodiske jobber (cronjobs) og nesten alt annet, slik at komprimeringen for det meste kjører og så lite som mulig forstyrrer.

Dette tiltaket bør være ganske uavhengig av brukt maskinvare. Jeg brukte flac versjon 1.3.2 på Arch Linux ved hjelp av flac <infile> --compression-level-X -f -o flacX.flac.

Effektivitet

Hvis du multipliserer relativ størrelse med relativ koding / komprimeringstid , får du en verdi for dårligheten . Men siden denne dårskapen for det meste styres av den relative tiden, vil grafene overlappe. Så for å rydde grafen speilet jeg bare dårligheten til en godhet , jeg kaller effektivitet her.

Funn

Fra FLAC-4 på eksploderer komprimeringstiden MEN det er to overraskelser:

  1. Det er en betydelig reduksjon i filstørrelsen mellom FLAC-3 og FLAC-4 avhengig av musikksjangeren: Klassisk musikk har en måte lavere komprimering ved bruk av FLAC-4. Jeg antar at dette er fordi FLAC bruker en lineær prediksjonsmodell for komprimering som gjør det mindre bra med mer kompleks (mindre lineær) musikk.

  2. For ikke-klassisk musikk, FLAC-3 er enda betydelig verre enn FLAC-2 når det gjelder filstørrelse.

flac_rank

Anbefalinger

Jeg anbefaler å bruke kompresjonsnivå FLAC-4 .

Å gå høyere øker kodingstiden betydelig med marginal forbedring av filstørrelsesreduksjon (gjennomsnittlig reduksjon fra FLAC-4 til FLAC-8 i denne testen er 1,2% med en 182% økning i gjennomsnittlig kompresjonstid).


Vedlegg

Album

Jeg tok akkurat de fem første tilfeldige CDene (listet opp nedenfor) som jeg tenkte på representerer forskjellige musikkfelt. Koblingene går med vilje til Amazon for å gi en enkel mulighet til å få et innblikk i musikken / for å få et inntrykk av musikken, siden det gjør en betydelig forskjell i komprimeringen.

Program

For denne oppgaven skrev jeg et python program som går gjennom alle undermappene (albumene) i en gitt mappe () for å teste alle .wav-filer og gruppere / plotte dem etter deres undermappnavn.

<folder> Album 1 Album 2 ... 

Analysen lagres i en fil --outfile <file1>. For å plotte, bruk --infile <file1> og --outfile <file2>.

#!/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) 

Kommentarer

  • Whoa … dette er en fantastisk kvantitativ analyse du gjorde der! Jeg setter stor pris på at du tok deg tid til å gjøre alt dette. Kunne ikke ' t vært raskt, men virkelig gode resultater. Takk!

Svar

Flac 0. Lagring er så billig i disse dager, virker som en no brainer for meg … også Flac 0 er mindre sannsynlig å hikke på et tregere system siden dekoding er mindre krevende å dekode.

Svar

Som en oppfølging av Suuuehgi sitt svar, vil jeg også legge til at hvis du starter fra en CD og rippe den direkte til FLAC, det kan hende kodingstiden ikke betyr noe i det hele tatt fordi du må først rive musikken, noe som tar tid. div>

Her prøvde jeg:

Ved å bruke dbPowerAmp CD Ripper, rev jeg kopien av Mariah Carey «s " Merry Jul " album. Jeg rev den en gang på FLAC-kompresjonsnivå 8, en gang på nivå 5 (dbPowerAmps standard), og en gang på nivå 0.

Her er totalt ganger for hver rip, fra å klikke start, til slutt med alle FLAC-filer gjort:

Nivå 0 = 6:19

Nivå 5 = 6:18

Nivå 8 = 6:23

Som du kan se, er avviket mellom alle 3 minimal, innen < 5 sekunder av hverandre. Da jeg så den rippe og kode, var kodingsstatusen bare et blits på skjermen, knapt registrert. Og så på filsystemet mens det rippet, så det ut til å kodes på farten mens det rippet. YMMV på tregere systemer.

Når det gjelder filstørrelser, her er filstørrelsene produsert:

Nivå 0 = 278 MB

Nivå 5 = 257 MB

Nivå 8 = 256 MB

skriv inn bildebeskrivelse her

Mens total rip og enc ode-tider var i utgangspunktet de samme, filstørrelsene var imidlertid ikke, men det er definitivt avtagende avkastning i de senere kompresjonsnivåene (som Suuuehgis svar antyder).

For meg virker det som om du starter fra CD-er og har en anstendig PC, vil tiden det tar å rippe og kode ikke endre seg mye basert på FLAC-kompresjonsnivået. Filstørrelsen endres imidlertid. Jeg tror dbPowerAmps forslag om FLAC nivå 5 som standard er bra. Bare 1 MB forskjell mellom FLAC 5 og FLAC 8, hvor-som om du går FLAC 0, mitt eksempel viser 21 MB i overkant lagring som kan lagres. Det virker ikke så mye, men når du ripper store samlinger, legger det seg raskt (en enkelt FLAC-sang kan være rundt den størrelsen.)

Dette ble gjort på et skrivebord med en USB 2 DVD-stasjon , ripping i gjennomsnitt med 7 ganger hastighet. Spesifikasjonene for stasjonære PC-er er en Intel Core i5-6500 CPU @ 3,2 GHz, 16 GB RAM og en Samsung 860 EVO Sata SSD-stasjon.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *