CDROM, F2 Коды Рида-Соломона P Q в кодировщике CIRC

Я исследую информацию о принципах CDROM. В стандарте http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-130.pdf На странице 35 (45 в формате pdf) я вижу кодировщик CIRC. И у него есть Q-код и P-коды, которые рассчитываются по алгоритму Рида-Соломона. Я пытаюсь подтвердить это и делаю несколько образцов звуковых дорожек (аудиодорожка не использует скрембер в качестве дорожки данных), одну заполняем шаблоном 0x01, а другую — 0xA5 (байты CIRC Interlive в пакете, а не биты, и я вижу Q и P в кадре F3) . После этого я считываю этот сектор с CD (напрямую с Laser out) логическим анализатором и расшифровываю скриптом. У меня есть эти данные для трека с шаблоном 0x01

S1 01 01 01 01 01 01 01 01 01 01 01 01 e5 6e 4e c5 01 01 01 01 01 01 01 01 01 01 01 01 ff ff ff ff

S2 01 01 01 01 01 01 01 01 01 01 01 01 e5 6e 4e c5 01 01 01 01 01 01 01 01 01 01 01 01 ff ff ff ff

В этом образце первый байт является суммой субкода SYNC_1 и SYNC_2.

Для трека с шаблоном 0xA5

S1 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 6b bc a5 72 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ff ff ff ff

S1 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 6b bc a5 72 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ff ff ff ff

Если вы видите на CIRC, все правильно, 12-15 байтов его инвертированная четность Q и 28-32 P четности (первый байт его sybcode его добавляется в F3).

Но я не могу найти алгоритм для вычисления этих байтов, у меня очень плохие математические способности. Я пробую калькулятор из cdrecord, он делает другие коды, пробую другую реализацию Рида-Соломона, но я не могу получить идентичный код из этого образца. Где я могу получить проработанную реализацию этого кода.


person Vulcanator    schedule 16.01.2019    source источник
comment
Аудиодорожка не используется Q, P в секторе, аудио не имеет секторов. Аудио записывает 24 байта (6 выборок) своих кадров F1 и напрямую переходит к кадру F2, F2 - это перемежитель CIRC и его использование Q и P. Но не то же самое, что Q и P для сектора данных на уровне F1. Q 4 байта для 24-байтового кадра F1 и P — 4 байта для чередующегося кадра F1 плюс Q.   -  person Vulcanator    schedule 17.01.2019
comment
Я нашел ссылку на edc_ecc.c, которая должна быть полезной. Я посмотрю код позже и посмотрю, могу ли я что-нибудь объяснить.   -  person rcgldr    schedule 17.01.2019
comment
Я пробую этот калькулятор и нажимаю получить другие коды.   -  person Vulcanator    schedule 17.01.2019
comment
В edc_ecc функции encode_L1_Q и encode_L1_P сначала делают из 24 байт 28 байт, добавляя 4 байта кода RS (и добавляя его между 12-13 исходными байтами), затем из 28 байт делают 32 байта. Это как энкодер CIRC на первом и втором этапе. Но значение, которое он вычисляет, не равнозначно тому, что я читал с настоящего компакт-диска. Я нашел этот документ ece.uvic.ca/~agullive/reedsolomon405- 511-2016.pdf и на странице 23 описание алгоритма расчета, но я не вижу там никакого уточнения.   -  person Vulcanator    schedule 18.01.2019
comment
Я удалил предыдущие комментарии, так как они были о L2. Функции кодирования L1 реализуют умножение на alog[(log(data) + log(RS term)) % 255]. Журнал терминов RS хранится в таблицах AQ и AP, но оказывается, что в таблице AQ отсутствуют записи для AQ[0], AQ[1], AQ[2]. Позже я попытаюсь выяснить, каковы фактические полиномы генератора P и Q. В этом PDF-файле NASA есть руководство по RS ECC. .   -  person rcgldr    schedule 18.01.2019


Ответы (1)


Я помещаю то, что нахожу в этом ответе, по мере продвижения, на основе файлов edc_ecc.c веб-github. RSL12 - это GF (2 ^ 8), многочлен x ^ 8 + x ^ 4 + x ^ 3 + x ^ 2 + 1 => hex 11d. Все ненулевые числа в поле можно рассматривать как степени шестнадцатеричного числа 02.

Полином генератора P в шестнадцатеричном виде:

(x+01)(x+02)(x+04)(x+08) = 01 x^4 + 0f x^3 + 36 x^2 + 78 x + 40

Если вы посмотрите на 4 записи для AP[...][31], вы увидите значения 75, 249, 78, 6, это десятичные логарифмы шестнадцатеричных чисел 0f, 36, 78, 40. Обратите внимание, что AP должен быть AP[4][28] (не [4][32]), исправление показано ниже.

Основываясь на вашем (теперь удаленном) комментарии, я не инвертировал Q в примерах, которые вы дали в исходном вопросе, и, используя мою собственную демонстрационную программу RS для расчета четности P, теперь я получаю 00 00 00 00:

01 01 01 01 01 01 01 01 01 01 01 01 1a 91 b1 3a 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00
a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 94 43 5a 8d a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 00 00 00 00

Полином генератора Q такой же, как полином генератора P. Он используется для RS(28,24), но байты четности находятся посередине, поэтому обычное кодирование необходимо изменить, как описано ниже.

AQ[][] неверен, используя AQ[3][], чтобы получить Q[3], я получаю 69 вместо 3a:

01 01 01 01 01 01 01 01 01 01 01 01 -- -- -- 69 01 01 01 01 01 01 01 01 01 01 01 01

Кроме того, для AQ[0] определено только 21 байт, для AQ[1] определено только 22 байта, для AQ[2] определено только 23 байта, для AQ[3] определено 24 байта, но они явно неверны.

Существует обходной путь, используйте 4 декодирования стирания с ячейками с 12 по 15, помеченными как стирания (xx xx xx xx), чтобы выполнить Q-кодирование:

01 01 01 01 01 01 01 01 01 01 01 01 xx xx xx xx 01 01 01 01 01 01 01 01 01 01 01 01
a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 xx xx xx xx a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5

После 4 коррекции стирания кодируются Q байтов четности:

01 01 01 01 01 01 01 01 01 01 01 01 1a 91 b1 3a 01 01 01 01 01 01 01 01 01 01 01 01
a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 94 43 5a 8d a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5

Используя метод декодирования с 4 стираниями, я сгенерировал фиксированный AQ[][]:

static const unsigned char AQ[4][24] =
  {{58,152,173,95,88,43,134,205,143,131,163,75,249,66,151,116,125,184,110,16,58,62,137,113},
   {30,214,148,138,112,154,157,96,49,198,189,249,69,47,147,235,156,47,209,183,138,232,205,120},
   {162,244,13,171,213,236,71,177,253,162,59,78,243,180,186,34,78,136,130,85,108,115,178,246},
   {158,179,101,94,49,140,211,149,137,169,81,6,72,157,122,131,190,116,22,64,68,143,119,22}};

Однако, если вы планируете написать декодер (который исправляет стирания и/или ошибки), вы можете использовать тот же метод, что и я, используя декодирование с 4 стираниями вместо кодирования. Если я правильно помню, именно так реализовали это некоторые ранние приводы DAT (цифровые аудиокассеты), поскольку они также имели свои байты четности в середине данных.


AP должен быть AP[4][28]. P - это RS(32,28), 28 байтов данных, используемых для генерации 4 байтов четности. Первые 4 значения из каждой строки AP[...][32] должны быть удалены, поэтому он становится AP[4][28], а encode_L1_P() должен кодировать 28 байтов данных (исправление одной строки, как указано ниже).

static const unsigned char AP[4][28] =
  {{249,142,180,197,5,155,153,132,143,244,101,76,102,155,203,104,58,152,173,95,88,43,134,205,143,131,163,75},
   {205,252,218,199,202,41,136,106,119,238,193,103,123,242,83,178,30,214,148,138,112,154,157,96,49,198,189,249},
   {67,11,131,40,7,41,80,147,151,17,245,253,208,66,228,116,162,244,13,171,213,236,71,177,253,162,59,78},
   {148,186,203,11,161,159,138,149,250,107,82,108,161,209,110,64,158,179,101,94,49,140,211,149,137,169,81,6}};

encode_L1_P() требует исправления одной строки:

static int
encode_L1_P(inout)
    unsigned char inout[L1_RAW + L1_Q + L1_P];
{
    unsigned char *P;
    int i;

    P = inout + L1_RAW + L1_Q;

    memset(P, 0, L1_P);
    for (i = 0; i < L1_RAW + L1_Q; i++) {   /* fix (remove + L1_P) */
        unsigned char data;

        data = inout[i];
        if (data != 0) {
            unsigned char base = rs_l12_log[data];

            P[0] ^= rs_l12_alog[(base+AP[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
            P[1] ^= rs_l12_alog[(base+AP[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
            P[2] ^= rs_l12_alog[(base+AP[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
            P[3] ^= rs_l12_alog[(base+AP[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
        }
    }
    return (0);
}

В ответ на комментарии. Чтобы сгенерировать AQ, я использовал коррекцию стирания, чтобы сгенерировать 24 набора паритетов:

01 00 00 00 00 00 00 00 00 00 00 00 69 60 bf b7 00 00 00 00 00 00 00 00 00 00 00 00
00 01 00 00 00 00 00 00 00 00 00 00 49 f9 fa 4b 00 00 00 00 00 00 00 00 00 00 00 00
...
00 00 00 00 00 00 00 00 00 00 00 00 9e a7 ab 93 00 00 00 00 00 00 00 00 00 00 01 00
00 00 00 00 00 00 00 00 00 00 00 00 1f 3b cf ea 00 00 00 00 00 00 00 00 00 00 00 01

AQ[][ 0] = hex log2{69 60 bf b7} = decimal {058 030 162 158}
AQ[][ 1] = hex log2{49 f9 fa 4b} = decimal {152 214 244 179}
...
AQ[][22] = hex log2{9e a7 ab 93} = decimal {137 205 178 119}
AQ[][23] = hex log2{1f 3b cf ea} = decimal {113 120 246 022}

Альтернативный метод заключается в использовании полного 255-байтового кодового слова со всеми нулями, кроме одного байта, установленного в 01 в соответствующей позиции по модулю 255, для генерации четности стандартным способом: четность = msg * x^4 % генератор. Это генерирует четность на 16 байтов дальше их целевой позиции, поэтому смещение необходимо скорректировать на 255-16 = +239 по модулю 255, чтобы получить целевые четности:

255_byte_message_offset = 28_byte_message_offset + 239 % 255:

msg[239] = 01 => parities = 69 60 bf b7
msg[240] = 01 => parities = 49 f9 fa 4b
...
msg[010] = 01 => parities = 9e a7 ab 93
msg[011] = 01 => parities = 1f 3b cf ea
person rcgldr    schedule 18.01.2019
comment
Спасибо работает нормально! Я мог прочитать некоторые дополнительные шаблоны, и все работало нормально. Может быть кому-то понадобится шаблон секора без байта подкода: 00 00 00 00 00 00 00 00 00 00 00 00 61 58 54 6c 00 00 00 00 00 00 00 00 00 00 01 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 fb 59 83 70 00 00 00 00 00 00 00 00 00 00 ef be ff ff ff ff ff ab ad 00 00 00 00 00 00 00 00 00 00 37 e1 4a 9e 00 0 0 0 00 00 00 00 be ba ff ff ff ff Большое спасибо за помощь! - person Vulcanator; 18.01.2019
comment
@Vulcanator - я обновил свой ответ. AP должен быть AP[4][28], а не AP[4][32] (первые 4 значения в каждой строке не используются). encode_L1_P требует исправления одной строки. Я удалил свои предыдущие комментарии, так как теперь они включены в мой обновленный ответ. Вы также можете удалить свои предыдущие комментарии. Я также предполагаю, что вам нужно будет отменить инвертирование Q перед вычислением P, а затем инвертировать их оба, если так работают компакт-диски. - person rcgldr; 22.01.2019
comment
Супер. Работайте нормально. Большое спасибо. В ближайшее время планирую написать статью о работе СD Могу вас упомянуть в статье как человека который помог, и если да, то как лучше это сделать? - person Vulcanator; 23.01.2019
comment
@Vulcanator - будет достаточно строки или сноски о помощи. Возможно, вы захотите включить человека, который создал edc_ecc.c (несмотря на необходимые исправления). Вы проверили, работает ли механизм отслеживания данных (L2...)? - person rcgldr; 23.01.2019
comment
Нет, L2 не тестировался, но L2 не является аппаратной частью (L1 является аппаратной и может быть потому, что не тестировался, вы не можете читать / записывать данные L1 с компакт-диска), и его использование в cdrecord для создания данных сектора для записи (если он не работает прекрасный cdrecord не может записать хороший компакт-диск). Реализация L2 во всем программном обеспечении для записи компакт-дисков, 100% в cdclone и nero в DLL. Я думаю, что он в порядке. - person Vulcanator; 23.01.2019
comment
Привет, я автор edc_ecc.c. Спасибо за проверку и исправление моего кода! Раньше он не тестировался, потому что у меня не было реальных данных для его проверки. - person hexcoder; 06.02.2019
comment
L2 тестируется с реальными данными с CD-ROM. - person hexcoder; 07.02.2019
comment
@hexcoder может оказаться полезным для вас pastebin.com/QM3iNzbb его кадры f3 считываются непосредственно с компакт-диска. Первый байт — это подкадровые данные, 32 — это байты данных в кадре f3. Его 5 секторов. А первые два кадра из 98 — это байты синхронизации для субканала. - person Vulcanator; 10.02.2019
comment
@Vulcanator: Большое спасибо за тестовые данные! Я буду использовать его для тестирования моего обновленного генератора таблиц кодировщика (который скоро будет выпущен в schilytools/libedc sourceforge.net/projects/schilytools/files/?source=directory). - person hexcoder; 11.02.2019
comment
@Vulcanator: первые 5 кадров f3 (от 16 и 18 января) взяты из часто повторяющегося шаблона данных, верно? Таким образом, разделы задержки 1 и 2 (C.3 и C.5 в ECMA pdf, стр. 43) не имеют значения. С другой стороны, я предполагаю, что кадры f3 от 10 февраля (pastebin.com) должны быть обработаны линиями задержки. С какого диска вы их взяли? Спасибо! - person hexcoder; 12.02.2019
comment
@hexcoder - линии задержки, используемые для чередования, используются ECC для четности AP [4] [32]? - person rcgldr; 12.02.2019
comment
@rcgldr нет для точки доступа, использующей только инверсию. Для AQ используется чередование. - person Vulcanator; 12.02.2019
comment
@rcgldr Я действительно запутался в том, как вы перешли от исправления стирания для Q к созданию массива AQ. Я понимаю концепцию использования декодирования стирания для генерации фактических байтов четности в середине для данного ввода, но я не вижу ссылки на деление, выполненное с использованием AQ. Не могли бы вы немного детализировать эту часть? - person Nicolas Noble; 22.06.2021
comment
@rcgldr Понятно, спасибо. Однако я не вижу математики, стоящей за этим. Я привык к Риду Соломону с разделением сообщения генератором, и с использованием напоминания о делении в качестве байтов четности. Есть ли другой метод, о котором я не знаю? Мне просто любопытно разместить все мои утки в ряд о понимании Рида Соломона в целом. - person Nicolas Noble; 22.06.2021
comment
@NicolasNoble - как упоминалось в моем ответе, если декодер RS обрабатывает стирания, то нет необходимости в надлежащем кодировщике, поскольку кодирование можно выполнить, установив байты четности на ноль, пометив их как стирания, а затем исправив стирания для создания паритеты. Вот как некоторые ленточные накопители DAT реализовали кодирование (без фактического кодирования, просто с использованием коррекции стирания, чтобы уменьшить количество вентилей в аппаратном обеспечении). - person rcgldr; 22.06.2021
comment
@rcgldr Понятно, спасибо. Теперь я знаю, что мне нужно исследовать. Мое исправление стирания намного сложнее, чем то, что вы показали здесь, поскольку оно связано с обнаружением и исправлением ошибок. Есть ли у вас литература о том, как делать только коррекцию стирания? - person Nicolas Noble; 22.06.2021
comment
@rcgldr Я думаю, что это просто щелкнуло для меня: эти таблицы AP и AQ в основном кодируют байты четности сообщения, в основном, мономом с коэффициентом 1 для каждой возможной позиции. Это дает вам матрицу, которую вы можете использовать для кодирования любого дальнейшего сообщения, поскольку они используются в качестве мультипликативной идентичности. Кажется, я вижу, как работает эта кодировка. Спасибо за продолжение :) - person Nicolas Noble; 23.06.2021
comment
@NicolasNoble - я удалил некоторые предыдущие комментарии. Ссылка на пример интерактивной демонстрационной программы RS(2^8) eccdemo8, которая представляет собой код стирания + исправления ошибок , который я использовал только со стираниями для генерации AQ. Код только стирания обычно ориентирован на блоки, используется для исправления стертых блоков данных вместо байтов и в конечном итоге оказывается немного более сложным, включая несколько шагов для создания используемой корректирующей матрицы (умножение матрицы) с нестираемыми блоками для восстановления стертых блоков. - person rcgldr; 23.06.2021