2015-12-21 3 views
2

У меня есть аудиосигнал, на котором есть какой-то FM-кодированный сигнал. Кодированный сигнал использует this Biphase mark coding technique < - см. В конце этой страницы.Пытается декодировать FM-сигнал, закодированный на аудио

Этот сигнал является цифровым представлением временного кода в часах, минутах, секундах и кадрах. Он в основном работает следующим образом:

  1. позволяет считать, что мы работаем со скоростью 25 кадров в секунду;
  2. мы знаем, что код передает 80 бит информации каждый кадр (это 80 бит на кадр х 25 кадров в секунду = 2000 бит в секунду);
  3. Волна отбирается со скоростью 44100 выборок в секунду. Итак, если мы разделим 44100/2000, мы увидим, что каждый бит использует 22,05 выборок;
  4. Немного происходит, когда сигнал меняет знак.
  5. Если волна меняет знак и сохраняет свой знак в течение всего периода бит, это ZERO. Если волна меняет знак два раза за один бит, это ОДИН;

Что мой код делает это:

  1. обнаруживает первое прохождение через нуль, то есть начало часов (в)
  2. измеряет уровень для к = к + 0,75 * bitPeriod ... 0,75 для обеспечения допуска.
  3. если этот второй уровень отличается, у нас есть 1, если не у нас 0;

Это код:

// data is a C array of floats representing the audio levels 

float bitPeriod = ceil(44100/2000); 
int firstZeroCrossIndex = findNextZeroCross(data); 
// firstZeroCrossIndex is the value where the signal changed 
// for example: data[0] = -0.23 and data[1] = 0.5 
// firstZeroCrossIndex will be equal to 1 

// if firstZeroCrossIndex is invalid, go away 
if (firstZeroCrossIndex < 0) return 

float firstValue = data[firstZeroCrossIndex]; 
int lastSignal = sign(firstValue); 

if (lastSignal == 0) return; // invalid, go away 

while (YES) { 

    float newValue = data[firstZeroCrossIndex + 0.75* bitPeriod]; 
    int newSignal = sign(newValue); 

    if (lastSignal == newSignal) 
     printf("0"); 
    else 
     printf("1"); 

    firstZeroCrossIndex += bitPeriod; 

    // I think I must invert the signal here for the next loop interaction 
    lastSignal = -newSignal; 

    if (firstZeroCrossIndex > maximuPossibleIndex) 
     break; 

} 

Этот код представляется логичным для меня, но результат приходит от него это полная ерунда. Что мне не хватает?

ПРИМЕЧАНИЕ: этот код выполняется над живым сигналом и считывает значения из кольцевого буфера. sign возвращает -1, если значение отрицательное, 1, если значение положительное или 0, если значение равно нулю.

+4

Вы забыли задать вопрос. Вы были в середине рассказывать историю, а затем вы просто остановились. –

+0

Вы пытаетесь найти синхронизирующее слово? И вы должны повторить синхронизацию следующего нуля в начале каждого кадра временного кода, по крайней мере. LTC можно считывать с разной скоростью. https://en.wikipedia.org/wiki/Linear_timecode – Roddy

+0

@Roddy - в этот момент я просто пытаюсь обнаружить биты. Меня не интересует слово синхронизации. OK Я буду повторять синхронизацию после каждого бит. Почему кто-то голосует, чтобы закрыть этот вопрос? – SpaceDog

ответ

2

Прохладная проблема! :-)

Код терпит неудачу в двух независимых способах:

  1. Вы ищете первый (любое) пересечение нуля. Это хорошо. Но тогда есть вероятность 50%, что этот переход является тем, который происходит до каждый бит (0 или 1), или этот переход является тем, который отмечает бит 1. Если вначале вы ошибаетесь, вы получаете бессмысленность.

  2. Вы продолжаете добавлять bitPeriod (float, 22.05) в firstZeroCrossIndex (int). Это означает, что ваши точки выборки будут постепенно выходить из строя с вашим аналоговым сигналом, и вы увидите странные эффекты, когда точка отсчета приближается к переходу сигнала. По крайней мере, вы получите бессмыслицу.

Решение 1: Вы должны искать, по крайней мере, один 0 первый, так что вы знаете, какой переход указывает только на следующий бит и который указывает 1 немного. На практике вам нужно будет повторно синхронизировать ваш сэмплер на каждом «0» бите.

Решение 2: Не добавляйте bitPeriod в точку отбора проб. Вместо этого найдите следующий переход, как и в начале. Следующий переход либо «наполовину», либо «полный бит» прочь, что дает вам необходимую информацию. После полумиллиардного периода вы должны должен увидеть еще один «пол-бит». Если нет, вы должны выполнить повторную синхронизацию, так как вы случайно сделали переход для перехода к старту. Это точно повторная синхронизация, о которой я говорил в 1.

+0

ХОРОШИЕ ПУНКТЫ! Мне не хватало обоих! Я думаю, что это решит проблему. Я вернусь через несколько минут, чтобы принять ваш ответ или нет. – SpaceDog

+0

+1 Измеряя «бит-период» динамически, а также настраивая точку отсчета, вы можете декодировать LTC с широким диапазоном скоростей воспроизведения. – Roddy

+0

просто отлично !!!!!!!!! БЛАГОДАРЯ – SpaceDog

Смежные вопросы