Quiero extraer / archivar toda mi colección de música en un formato de archivo sin pérdidas pero comprimido, es decir, los archivos deben ser perfectos , representaciones sin pérdida de los datos originales, pero debería consumir menos espacio que WAV (E) sin comprimir.

WAV (E) no es válido, ya que «s no es gratuito (material propiedad de Microsoft), la compresión multiplataforma es engorrosa o no es posible y el tamaño del archivo está limitado a 4 GB. Por lo tanto, elijo FLAC (Free Lossless Audio Codec).

Dado que digitalizar una colección completa es una tarea gigantesca y FLAC ofrece 9 niveles de compresión (0 a 8), surge la pregunta de oro :

¿Qué nivel de compresión debo elegir sabiamente?

Comentarios

  • esta pregunta no ‘ t aborda el diseño de sonido en absoluto, pero sí toca una elección que enfrentan algunos diseñadores de sonido, que es, cómo manejar de la mejor manera nuestras bibliotecas de grabaciones en constante crecimiento. Personalmente, ‘ prefiero FLAC sobre WAVE simplemente por el problema de almacenamiento, pero ‘ me temo que no ‘ no tengo ninguna idea sobre el nivel de compresión.
  • Curiosamente publiqué esto en Música primero, pero la gente recomendó moverlo a Diseño de sonido.

Responder

Los niveles de compresión FLAC son (solo) un intercambio entre tiempo de codificación y tamaño de archivo . El tiempo de decodificación es prácticamente independiente de la tasa de compresión. A continuación, me referiré a los niveles de compresión 0, …, 8 como FLAC-0, …, FLAC-8.

En resumen : recomiendo FLAC-4 !


Las soluciones fáciles

Obviamente:

  • Si no me importa codificar el tiempo y dado que el espacio es dinero, tomo el nivel de compresión más alto FLAC-8 .

  • Si no me importa el espacio pero quiero estar detrás de esto lo más rápido posible, tomo el nivel de compresión más bajo FLAC-0 .


La solución difícil

¿Dónde está la justo en el medio entre el tamaño del archivo y el tiempo de codificación? Me encontré con el artículo de Nathan Zachary sobre esta pregunta, pero él compara solo dos archivos, los codifica solo una vez (el tiempo de codificación varía enormemente según la carga lateral de la computadora ) y las tablas son difíciles de leer en comparación con los gráficos.

Entonces, inspirado por esto, rehice sus medidas con cinco álbumes completos cada uno en un género diferente y codificado cada archivo / pista 10 veces .

Procedimiento:

  • Extraiga el álbum con abcde y configuración adecuada cdparanoia a WAV sin comprimir.
  • Convierta cada archivo 10 veces para cada nivel de compresión (FLAC-0 a FLAC-8) y tome el tiempo medio de codificación relativo a FLAC-0 y el tamaño de archivo relativo a F LAC-0 .
    • Para esto, desactivé la conexión a Internet, todos los trabajos periódicos (cronjobs) y casi todo lo demás para que la mayor parte de la compresión se ejecute y la menor cantidad de interferencias posibles.

Esta medida debería ser prácticamente independiente del hardware utilizado. Usé flac versión 1.3.2 en Arch Linux usando flac <infile> --compression-level-X -f -o flacX.flac.

Eficiencia

Si multiplica tamaño relativo con tiempo de compresión / codificación relativo , obtienes un valor por la maldad . Pero dado que esta maldad se rige principalmente por el tiempo relativo, los gráficos se superpondrían enormemente. Entonces, para aclarar el gráfico, simplemente reflejé la maldad en una bondad , llamo eficiencia aquí.

Hallazgos

A partir de FLAC-4, el tiempo de compresión se dispara PERO hay dos sorpresas:

  1. Hay una reducción significativa en el tamaño del archivo entre FLAC-3 y FLAC-4 según el género musical: la música clásica tiene una compresión mucho menor con FLAC-4. Supongo que esto se debe a que FLAC utiliza un modelo de predicción lineal para la compresión que funciona peor con música más compleja (menos lineal).

  2. Para música no clásica, FLAC-3 es incluso significativamente peor que FLAC-2 en términos de tamaño de archivo.

flac_rank

Recomendaciones

Recomiendo usar el nivel de compresión FLAC-4 .

Subir aumenta significativamente el tiempo de codificación con una mejora marginal en la reducción del tamaño del archivo (reducción media de FLAC-4 a FLAC-8 en esta prueba es 1,2% con un 182% aumento en el tiempo medio de compresión).


Apéndice

Álbumes

Acabo de tomar los primeros cinco CD aleatorios (enumerados a continuación) que pensé representar diferentes campos de la música. Los enlaces van intencionalmente a Amazon para proporcionar una posibilidad fácil de echar un vistazo a la música / para tener una idea de la música, ya que hace una diferencia significativa en la compresión.

Programa

Para esta tarea escribí un python programa que recorre todas las subcarpetas (los álbumes) en una carpeta determinada () para probar todos los archivos .wav y agruparlos / trazarlos por su nombre de subcarpeta.

<folder> Album 1 Album 2 ... 

El análisis se guardará en un archivo --outfile <file1>. Para trazar, use --infile <file1> y --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) 

Comentarios

  • Vaya … ¡Este es un análisis cuantitativo impresionante que hiciste allí! Realmente aprecio que se haya tomado el tiempo para hacer todo esto. No se pudo ‘ t han sido rápidos, pero realmente excelentes resultados. ¡Gracias!

Respuesta

Flac 0. El almacenamiento es tan barato en estos días, me parece una obviedad … también es menos probable que Flac 0 tenga problemas en un sistema más lento, ya que decodificarlo es menos exigente.

Respuesta

Como seguimiento a la respuesta de Suuuehgi, también me gustaría agregar que si está comenzando desde un CD y copiarlo directamente a FLAC, el tiempo de codificación puede no importar en absoluto porque tienes que primero extraer la música, lo que lleva tiempo.

Esto es lo que probé:

Usando dbPowerAmp CD Ripper, rasgué mi copia de Mariah Carey «s » Merry Álbum de Navidad «. Lo rasgué una vez en el nivel de compresión FLAC 8, una vez en el nivel 5 (dbPowerAmps predeterminado) y una vez en el nivel 0.

Aquí está el total veces para cada copia, desde que hace clic en el inicio, hasta que finaliza con todos los archivos FLAC listos:

Nivel 0 = 6:19

Nivel 5 = 6:18

Nivel 8 = 6:23

Como puede ver, la variación entre los 3 es mínima, dentro < 5 segundos el uno del otro. Mientras lo veía copiar y codificar, el estado de codificación era un simple destello en la pantalla registrado. Y al ver el sistema de archivos mientras se copiaba, parecía estar codificando sobre la marcha mientras se estaba copiando. YMMV en sistemas más lentos, sin embargo.

En cuanto a los tamaños de archivo, aquí están los tamaños de archivo producidos:

Nivel 0 = 278 MB

Nivel 5 = 257 MB

Nivel 8 = 256 MB

ingrese la descripción de la imagen aquí

Mientras que el total rip y enc Los tiempos de oda eran básicamente los mismos, los tamaños de los archivos no lo eran, SIN EMBARGO, definitivamente hay rendimientos decrecientes en los niveles de compresión posteriores (como alude la respuesta de Suuuehgi).

Para mí, parece que si Si está comenzando desde CD y tiene una PC decente, el tiempo que lleva copiar y codificar no cambiará mucho en función del nivel de compresión FLAC. Sin embargo, el tamaño del archivo cambia. Creo que la sugerencia de dbPowerAmps del nivel 5 de FLAC por defecto es buena. Solo 1 MB de diferencia entre FLAC 5 y FLAC 8, mientras que, como si fuera FLAC 0, mi ejemplo muestra 21 MB en exceso de almacenamiento que podrían guardarse. Puede que no parezca mucho, pero cuando estás extrayendo grandes colecciones, se acumula rápidamente (una sola canción FLAC puede tener aproximadamente ese tamaño).

Esto se hizo en una computadora de escritorio con una unidad de DVD USB 2 , rasgando en promedio a una velocidad de 7x. Las especificaciones de mi PC de escritorio son una CPU Intel Core i5-6500 a 3.2Ghz, 16GB de RAM y una unidad SSD Samsung 860 EVO Sata.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *