Я пытаюсь передать двоичные данные с одного устройства на другое по аудиоканалу (динамик / микрофон). Я использую AFSK (Audio Frequency Shift Keying), как в Packet Radio, с и двумя частотами и . Я немного поиграл в Ruby, и моя первая реализация просто имитирует классический некогерентный демодулятор, который пока работает отлично.
Проблема в том, что я пытаюсь перенести это на мобильную платформу, где важна производительность, а мое текущее решение слишком медленное. Я нашел множество способов демодуляции AFSK в программном обеспечении:
- Скользящий DFT (БПФ)
- Скользящий фильтр Герцеля
- Фазовая петля
- Пересечение нуля
Каков будет путь? Есть слишком много вариантов для выбора. Я уверен, что есть еще больше вариантов. Возможно, существуют даже лучшие решения, чем те, которые я назвал выше? У кого-нибудь есть примеры кода для меня? Я обеспокоен
- Производительность (должна работать на мобильной платформе, скажем, на устройстве iOS или Android)
- Стабильность (должна быть в состоянии справиться с некоторым шумом)
Любые предложения и советы с благодарностью!
источник
Ответы:
Я думаю, что вы могли бы получить лучшую производительность с точки зрения частоты ошибок по битам демодулятора (BER) с фазовой автоподстройкой частоты. Вам нужно, чтобы это было быстро, хотя. Я думаю, что ваш лучший выбор для быстрого алгоритма, который все еще работает достаточно хорошо, - это пересечение нуля.
Кстати, я хотел бы предложить вам изменить 2200 Гц на 2400 Гц. Наивная реализация схемы 1200/2200 Гц привела бы к разрывам, как видно примерно на две трети на графике ниже, где 2200 Гц переходит к 1200 Гц.
Чтобы минимизировать используемую полосу пропускания и избежать разрывов, которые будут искажать сигнал, вам потребуется сделать фазу непрерывной. Даже если вы сделаете фазу передатчика непрерывной, все равно будет проблема в том, что символы 2200 Гц не всегда будут иметь одинаковое количество пересечений нуля из-за разных фаз. Обычно у них будет четыре пересечения нуля, но иногда у них будет три. С другой стороны, символы 1200 Гц всегда будут иметь два пересечения нуля, поскольку скорость передачи данных равномерно делится на частоту FSK.
Вы можете решить обе эти проблемы, изменив 2200 Гц на 2400 Гц. Тогда символы всегда будут начинаться и заканчиваться при 0 градусах (таким образом, автоматически делая их непрерывными по фазе), и они всегда будут иметь одинаковое количество пересечений нуля - два и четыре.
источник
Я сделал декодер для AFSK (стандарт Bell 202), используя корреляционные приемники для 1200 Гц и 2200 Гц, с очень хорошими результатами.
Результирующая амплитуда совершенно не зависит от фазы сигнала, а выходное SNR очень хорошее.
источник
В случае RTTY 45.45 бод у вас также будут символы, которые не являются целым числом выборок, поэтому вам нужна функция, которую можно вызывать для каждой выборки, а затем сигнализировать в ее возвращаемом значении, когда этот символ закончится. И вам нужен фазовый аккумулятор, который постоянно подсчитывает, где находится фаза синусоиды.
Чтобы отправить символы, длина которых не кратна частоте дискретизации, вам нужна эта функция ...
Чтобы использовать его, сгенерируйте следующую выборку синусоидальной волны и вызовите эту функцию, а затем проверьте, не является ли возвращаемое значение НЕ равным двум. Если оно не равно двум, перейдите к следующему символу и решите, отправляете ли вы метку пробела, а затем снова вызовите эту функцию внутри блока кода, который выполняется, когда вы обнаружили, что возвращаемое значение не равно двум.
А вот фазовый аккумулятор из прошивки Rockbox, с возможностью изменения амплитуды (полная громкость равна 32767, полная громкость 180 градусов по фазе равна -32768).
источник