Jag vill rippa / arkivera hela min musiksamling till ett förlustfritt men komprimerat filformat, dvs. filerna ska alla vara perfekta , förlustfria representationer av originaldata men bör ta mindre plats än okomprimerad WAV (E).

WAV (E) är ett no-go, eftersom det är icke-gratis (egna Microsoft-grejer), komprimering på flera plattformar är besvärlig eller inte möjlig och filstorleken är begränsad till 4 GB. Därför väljer jag FLAC (Free Lossless Audio Codec).

Eftersom digitalisering av en hel samling är en enorm uppgift och FLAC erbjuder 9 kompressionsnivåer (0 till 8), kommer den gyllene frågan :

Vilken kompressionsnivå ska jag klokt välja?

Kommentarer

  • den här frågan adresserar inte ' ljuddesign alls men den berör ett val som vissa ljuddesigners står inför, vilket är, hur man bäst hanterar våra ständigt växande inspelningsbibliotek. Personligen går jag ' FLAC över WAVE helt enkelt på grund av lagringsproblemet, men jag ' är rädd att jag inte ' inte har någon inblick i komprimeringsnivån.
  • Intressant har jag lagt upp detta på Musik först men folket där rekommenderade att flytta det till ljuddesign.

Svar

FLAC-komprimeringsnivåer är (endast) en handel mellan kodningstid filstorlek . Avkodningstiden är ganska oberoende av kompressionshastigheten. I det följande kommer jag att hänvisa till kompressionsnivåerna 0, …, 8 som FLAC-0, …, FLAC-8.

Kort sagt : Jag rekommenderar FLAC-4 !


De enkla lösningarna

Uppenbarligen:

  • Om jag inte bryr mig om kodningstid och eftersom utrymme är pengar tar jag den högsta komprimeringsnivån FLAC-8 .

  • Om jag inte bryr mig om utrymme men vill komma bakom detta så snabbt som möjligt tar jag den lägsta komprimeringsnivån FLAC-0 .


Den svåra lösningen

Var är rätt mitt mellan filstorlek och kodningstid? Jag snubblade på Nathan Zacharys artikel om denna fråga men han jämför bara två filer, kodar dem bara en gång (kodningstiden varierar enormt beroende på datorns sidoladdning ) och tabeller är svåra att läsa jämfört med grafer.

Så, inspirerat av detta, gjorde jag hans mått med fem kompletta album var och en i en annan genre och kodade varje fil / spår tio gånger .

Procedur:

  • Rippa album med abcde och korrekt cdparanoia inställningar för okomprimerad WAV.
  • Konvertera varje fil tio gånger för varje komprimeringsnivå (FLAC-0 till FLAC-8) och ta genomsnittlig kodningstid relativt FLAC-0 och filstorlek i förhållande till F LAC-0 .
    • För detta inaktiverade jag internetanslutningen, alla periodiska jobb (cronjobs) och nästan allt annat så att komprimeringen verkligen går och så mindre som möjligt stör.

Denna åtgärd borde vara ganska oberoende av den använda hårdvaran. Jag använde flac version 1.3.2 på Arch Linux med flac <infile> --compression-level-X -f -o flacX.flac.

Effektivitet

Om du multiplicerar relativ storlek med relativ kodning / komprimeringstid får du ett värde för dåligheten . Men eftersom denna dålighet mestadels styrs av den relativa tiden, skulle graferna överlappa kraftigt. Så för att rensa upp grafen speglade jag bara dåligheten till en godhet , jag kallar effektivitet här.

Resultat

Från FLAC-4 på exploderar komprimeringstiden MEN det finns två överraskningar:

  1. Filstorleken minskar avsevärt mellan FLAC-3 och FLAC-4 beroende på musikgenre: Klassisk musik har ett sätt lägre komprimering med FLAC-4. Jag antar att detta beror på att FLAC använder en linjär förutsägelsemodell för komprimering som går mindre bra med mer komplex (mindre linjär) musik.

  2. För icke-klassisk musik, FLAC-3 är till och med betydligt sämre än FLAC-2 vad gäller filstorlek.

flac_rank

Rekommendationer

Jag rekommenderar att du använder komprimeringsnivå FLAC-4 .

Att gå högre ökar kodningstiden avsevärt med marginell förbättring av filstorleksminskning (medelreduktion från FLAC-4 till FLAC-8 i detta test är 1,2% med en 182% ökning av genomsnittlig kompressionstid).


Bilaga

Album

Jag tog precis de första fem slumpmässiga CD-skivorna (listade nedan) som jag tänkte på representerar olika musikfält. Länkarna går avsiktligt till Amazon för att ge en enkel möjlighet att få en inblick i musiken / för att få en uppfattning om musiken eftersom det gör en betydande skillnad i komprimeringen.

Program

För denna uppgift skrev jag ett python program som går igenom alla undermappar (albumen) i en viss mapp () för att testa alla .wav-filer och gruppera / plotta dem efter deras undermappsnamn.

<folder> Album 1 Album 2 ... 

Analysen sparas i en fil --outfile <file1>. För att plotta, använd --infile <file1> och --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 … det här är en fantastisk kvantitativ analys du gjorde där! Jag uppskattar verkligen att du tog dig tid att göra allt detta. Kunde inte ' ha varit snabba, men riktigt bra resultat. Tack!

Svar

Flac 0. Förvaring är så billigt idag, det verkar som en bra idé för mig … också att Flac 0 är mindre benägna att hicka på ett långsammare system eftersom avkodning är mindre krävande att avkoda.

Svar

Som en uppföljning av Suuuehgis svar vill jag också lägga till att om du börjar från en CD och rippar den direkt till FLAC, kodningstiden spelar kanske ingen roll eftersom du måste först rippar musiken, vilket tar tid.

Här är vad jag försökte:

Med hjälp av dbPowerAmp CD Ripper slet jag mitt exemplar av Mariah Carey ”s " Merry Jul " album. Jag slet den en gång på FLAC-komprimeringsnivå 8, en gång på nivå 5 (dbPowerAmps standard) och en gång på nivå 0.

Här är totalt gånger för varje ripp, från att klicka på start, till slut med alla FLAC-filer:

Nivå 0 = 6:19

Nivå 5 = 6:18

Nivå 8 = 6:23

Som du kan se är avvikelsen mellan alla 3 minimal, inom < 5 sekunder av varandra. När jag såg det rippa och koda var kodningsstatusen bara en blixt på skärmen, knappt registrerad. Och titta på filsystemet när det rippade, det verkade koda i farten som det rippade. YMMV på långsammare system dock.

När det gäller filstorlekar, här är filstorlekarna som produceras:

Nivå 0 = 278 MB

Nivå 5 = 257 MB

Nivå 8 = 256 MB

ange bildbeskrivning här

Medan total ripp och enc ode-tiderna var i princip samma, filstorlekarna var dock INTE definitivt minskande avkastningar i de senare komprimeringsnivåerna (som Suuuehgis svar antyder).

För mig verkar det som om du startar från CD-skivor och har en anständig dator, den tid det tar att rippa och koda kommer inte att förändras mycket baserat på FLAC-komprimeringsnivån. Filstorleken ändras dock. Jag tycker att dbPowerAmps förslag på FLAC nivå 5 som standard är bra. Endast 1 MB skillnad mellan FLAC 5 och FLAC 8, där-som om du går FLAC 0, mitt exempel visar 21 MB i överskott lagring som kan sparas. Det kanske inte verkar vara så mycket, men när du rippar stora samlingar blir det snabbt (en enda FLAC-låt kan vara ungefär den storleken.)

Detta gjordes på ett skrivbord med en USB 2 DVD-enhet , rippar i genomsnitt med 7x hastighet. Mina specifikationer för stationära datorer är en Intel Core i5-6500 CPU @ 3,2 GHz, 16 GB RAM-minne och en Samsung 860 EVO Sata SSD-enhet.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *