загоню блок(25800 - 4300A4) целиком в эксель
По мне, так легче найти необходимые таблицы в любом хексредакторе по внешнему виду. Ведь они не плохо документированы в SDK.
повторяются подряд много раз
Да, у некоторых регистраторов отдельные значения действительно повторяются по 5-7 раз, у других - нет. Это не критично и связано отчасти с округлением дробей до целых, о чем ниже, а отчатси - умыслом программиста.
такая же последовательность данных в секундах или она, последовательность/метод определения различаются?
Различаются, там многое считается через логарифм по основанию 2. Но разобраться не сложно если, опять же, посмотреть в SDK.
Например, в одной из таблиц (точнее в двумерном массиве) в каждой строке содержатся по два 16-разрядных значения, трактуемых как:
{time, log[sub]2[/sub](time)*1000}.
Если с вычислением log[sub]2[/sub](time) * 1000 все более менее понятно, то time записывается в битовом формате, где:
- bit[sub]15[/sub] - sign или знак (0 - это "плюс", а 1 это "минус");
- bit[sub]14[/sub] - содержит экспоненту числа записанного в 14-и младших битах (дело в том, что для повышения точности записываемого числа, некоторые из них могут быть умножены на 10, что позволяет сохранить и первый знак после запятой при округлении до целого. Некоторые числа умножить нельзя, т.к. в этом случае они могут не поместиться в 14-и младших битах. В общем случае, если число может быть умножено на 10 и при этом помещается в 14 битах, оно ДОЛЖНО быть умножено. Т.о. 1 означает, что число умножено на 10, 0 - не умножено);
- bits[sub]13:0[/sub] - это и есть округленная до 14-битного значения выдержка.
Попробуем по описанному алгоритму сформировать строку таблицы для выдержки 1/60 с.
Воспользовавшись формулой для второго члена этой строки
log[sub]2[/sub](time)*1000, получим log[sub]2[/sub]( 1 / 60 ) * 1000 =
-5906 =
0xE8EE (при умножении на тысячу мы берем целочисленный результат просто отбрасывая дробную часть, а не округляя само число).
Для вычисления первого члена
time нам придется перейти к двоичной системе счисления.
Поскольку второй член, как мы расчитали, равен -5906 и это
отрицательное число, то старший бит первого члена (sign или bit[sub]15[/sub]) равен 1, т.е. "минус".
Т.к. в дробном виде значение нашей выдержки выглядит как 1/60, то для нас не важно, где записана единица (в нашем случае в числителе, но может быть и в знаменателе, например, выдержку 2 секунды можно представить как 2/1), поэтому нас будет интересовать только число 60 (как при выдержке 2/1 секунды нас бы интересовало число 2).
По-скольку при вычислении второго члена, мы отбрасывали дробную часть (что неизбежно, т.к. в конечном виде это число записывается в виде 16-битового целого 0хE8EE), то мы уже имеем выдержку не точно 1/60, какую-то другую и нам придется ее вычислить, тем более что мы еще умножили результат на 1000.
Делается это путем обратных вычислений так:
- делим наше число -5906 на 1000, чтобы получить исходный логорифм в чистом виде, получаем -5.906;
- возводим число 2 (основание логарифма) в степень -5.906 с помощью обычного виндозного калькулятора и получаем 0,0166769584068743750913310103395 - это время экспозиции одного кадра;
- чтобы перейти от времени экспозиции к выдержке делим единицу на это число :
1 / 0,0166769584068743750913310103395 = 59,962972599835233429468097533335.
Получили число с кучей знаков после запятой и выдержку не 1/60, а 1/59,962972..., т.е. чуть меньше, чем заказывали, но по иному не получится.
Мы с вами помним, что машинка оперирует целыми числами и по умолчанию при переводе этой дроби в шестнадцатеричный вид просто отбросит дробную часть т.е. в конечном виде это будет целое число 59.
Проверим можно ли повысить точность числа при сохранении его в 14 битах, ведь мы отбросили 0,96297... т.е. почти целую диницу. Для этого умножим наше число на 10 (сейчас самое время вспомнить про bit[sub]14[/sub]) и переведем его в двоичный вид опять же отбросив после умножения дробную часть:
59,962972599835233429468097533335 * 10 = 599 = b
10 0101 0111.
Мы видим, что число занимает 10 бит, что меньше 14-и, но при этом мы на порядок повысили его точность. Можно бы было умножить и на 100, сохранив четыре значащие цифры, т.е. 5996 и оно по- прежнему помещалось бы в 14-и битах, но нас ограничивает то, что информация о том, на сколько мы умножили наше число, хранится в одном-единственном бите bit[sub]14[/sub], который указывает, что число умножено на 10, если бит установлен в единицу, или не умножено, если значение этого бита 0.
Мы никак не можем показать, что число умножено, например, 2 раза на 10, т.е. на 100. Нам негде сохранить эту информацию.
Поэтому выполняем однократное умножение на 10 и делаем пометку об этом в bit[sub]14[/sub], выставив его в единицу.
Итак мы знаем, что наше значение 599 в 14-битном двоичном виде будет записываться как
00 0010 0101 0111.
Знаем что бит sign должен иметь значение 1, как и бит признака повышения точности числа (ведь мы умножили его на 10).
Теперь собираем все биты вместе, расставив их на свои позиции и получаем b
1100 0010 0101 0111 или
0xC257.
Таким образом наша строка будет иметь вид:
{0xC257, 0xE8EE} Ясно, что если строки в таблице будут собраны другим образом, то что-то будет работать нерправильно.
Другой массив данных, связанный с выдержками, содержит 32-битные значения выдержек в формате Q9, я его уже описывал раньше, повторяться не буду.
Третью таблицу я тоже описывал раньше.
Как-то так, если есть желание