rox

Cue-листы и рипы, которые ведут себя как альбомы

Если вы рипали CD до того, как разбиение стало нормой, часть вашей коллекции — это один FLAC на диск с текстовым файлом рядом. Большинство плееров либо игнорируют лист, либо считают описанное в нём второсортным. Вот что с этим делает rox.

Что такое cue-рип на самом деле

Один звуковой файл на целый диск и лист .cue, где написано, где начинается каждый трек. Это точный способ сохранить CD, потому что промежутки между треками часть диска, а разбиение их выбрасывает. И это же формат, который ломает допущение, на котором построена любая музыкальная медиатека: что один файл — это один трек.

Плееры решают это одним из трёх способов. Игнорируют лист и показывают семидесятиминутный трек. Показывают треки листа, но держат их отдельно от настоящей медиатеки, так что поиск, сортировка и плейлисты ведут себя с ними иначе. Или делают разрыв настоящим и принимают его один раз.

Настоящие строки, а не обломки

rox индексирует каждый участок листа как обычную строку медиатеки, опознаваемую по файлу плюс номеру трека. Всё дальше по цепочке читает его как трек, потому что для всего дальше по цепочке он трек и есть. Плейлисты снимают его снимком, прослушивания цепляются к нему, поиск его находит, столбцы сортировки его сортируют, и ни один из них не знает, что одиннадцать строк указывают на один FLAC.

Альтернатива, которую выбирает большинство реализаций, — это синтетический путь, album.flac#3, который держит базу в порядке и перекладывает задачу на каждый кусок кода, который потом этот путь откроет. Один пропущенный разбор там — это тихая ошибка, которая читает байты тегов из ниоткуда. Медиатека без cue-листов не платит за это ничего: участки живут в отдельной таблице, и на горячих путях их никто не читает.

Участок играет как файл

Движок берёт участок как целый мир для этого трека: точная перемотка к его началу, точная по сэмплам подрезка с обоих краёв и граница конца, которая идёт тем же путём, что и настоящий конец файла. Отсутствие пауз, кроссфейд, «стоп после текущего» и повтор работают, не зная, что участки существуют.

Подрезка головы — это та деталь, которая имеет значение. Точная перемотка попадает на границу пакета, а не на конкретный сэмпл, так что без сброса кадров между попаданием и началом участка каждый трек открывается хвостом предыдущего. Это и есть звук недоделанной реализации cue.

Идущие подряд треки одного рипа делят альбомную группу, и это то, что не даёт кроссфейду размывать собственные бесшовные склейки диска. Рип играет как та запись, с которой его сняли.

Сканирование и смена решения

Лист забирает свой образ. Пока cue упоминает файл, у этого файла нет своей строки, так что вы не получаете одиннадцать треков плюс семидесятиминутный дубликат. Свежесть считается по тому из двух, что менялся позже, так что правка листа или звука заново нарезает рип при следующем сканировании. Удалите лист, и образ свернётся обратно в одну обычную строку.

Метаданные предпочитают лист и откатываются на собственные теги образа. Листы, написанные до того, как дисциплина UTF-8 стала нормой, получают откат на cp1252, потому что старые рипы — это ровно та публика, ради которой эта штука и сделана.

Оценки, которые не штампуют весь диск

rox обычно пишет оценки в сами файлы, и это правильный выбор, когда файл — это трек. На cue-рипе это не так: образ принадлежит всем одиннадцати трекам, так что запись по треку проштамповала бы каждый из них одними и теми же звёздами.

Для таких строк rox отказывается от файловой половины записи, и значение держит база. То же с правкой тегов. Вы получаете оценки по трекам на рипе, а ваш образ выходит из этого байт в байт прежним.

То, что вы заметите только потом

  • Экспорт m3u пишет участки как path#N, а импорт предпочитает точное совпадение пути, так что список ходит туда-обратно через чужой софт, не схлопываясь в образ.
  • Скробблинг и «сейчас играет» дедуплицируются по паре, так что одиннадцать треков диска скробблятся как одиннадцать треков, а не как один очень длинный.
  • Прослушивания заново цепляются к участкам после пересканирования, так что диск сохраняет историю по трекам, даже когда все участки несут одинаковые теги.
  • Переносится только альбомная пара значений ReplayGain. Значения трека, записанные против образа целого диска, описывают диск, поэтому они игнорируются, а не принимаются на веру.

Мерило здесь не в том, играет ли рип. Оно в том, ведёт ли себя хоть что-то в медиатеке месяц спустя иначе только потому, что это пришло из образа.

Направьте его на ту полку, которую вы так и не разрезали

Сканер подхватывает листы на первом же проходе, наравне со всем остальным. Подробнее о том, что ломается на масштабе медиатеки.