2010/01/12

Modulação AM ilustrada

Rádio é uma coisa com a qual eu gostaria de ter mexido, mas ainda não o fiz. Por diversas razões, este interesse acaba sempre em segundo plano frente a coisas mais urgentes, e quem sabe eu nunca brinque com rádio mesmo.

Para um sinal viajar nas ondas de rádio, ele tem de ser modulado, ou seja, transposto para uma freqüência e formato adequados à transmissão. As técnicas de modulação do rádio têm parentesco próximo com informática e telecomunicações, É possível "brincar" com modulação no computador mesmo. É um tema do qual eu confessadamente não entendo muito, mas acho fascinante. E para ser honesto, acho incrível que técnicas aparentemente simples façam o milagre de modular e demodular um sinal.

Neste post, vou ilustrar as técnicas de modulação AM. Quem tiver interesse em aprofundar-se no tema, tente achar o livro "Modem e transmissão de dados", de Fábio de Azevedo Montoro, editora Érica. Apesar de velho, é um dos poucos livros técnicos escritos por brasileiro que presta.

Bem, vamos começar com um sinal de banda-base, ou seja, que ocupa toda a banda disponível a partir de 0Hz. Uma gravação da minha própria voz, pra sacanear com os ouvidos de todo mundo:

(paralelepipedo.wav)

A propósito, estou usando a tag EMBED para colocar o áudio na página. Se não funcionar, você pode pescar os arquivos em http://epx.com.br/wav.

A modulação AM exige que o sinal original ocupe uma banda limitada, de modo que o sinal modulado também "caiba" dentro da banda desejada. Assim, precisamos pegar o sinal original e passar num filtro passa-baixas, até 1000Hz. O resultado é a mesma voz um pouco mais abafada:

(paralelepipedo_lopass.wav)

Para o próximo post, prometo escrever um filtro em Python. Desta vez bateu a preguiça e usei os recursos do Audacity mesmo para fazer a filtragem. Não é perfeito mas é suficiente para nossos fins.

A modulação AM consiste simplesmente em multiplicar o sinal original por uma onda senoidal, a portadora. No caso, escolhi uma portadora de 3000Hz, bem distante da banda ocupada pela minha voz filtrada (1000Hz). O ruído da portadora em si é:

(carrier3000.wav)

O resultado da modulação (voz x apito) é:

(amsc.wav)

Note que a voz e as vogais ficaram agudas e quase irreconhecíveis. A rigor, esta modulação denomina-se AM-SC (AM com portadora suprimida), por razão que logo esclareço.

A modulação faz minha voz mudar de banda: ela passa a ocupar uma faixa de 2000 a 4000Hz. Na verdade, a modulação AM produz duas "cópias" do sinal original: uma ocupando a banda 2000-3000Hz, e outra ocupando a banda 3000-4000Hz. A modulação AM normal "desperdiça" banda pois o sinal modulado ocupa o dobro de espaço que o original.

Mesmo assim, AM é muito útil, pois obviamente eu consigo "mover" a minha voz para qualquer faixa de freqüências que seja conveniente à transmissão. Mais importante que isso: a modulação permite que diversos sinais ocupem o mesmo meio, bastando que cada sinal tenha uma portadora diferente e as bandas não se sobreponham.

Podemos modular em AM "normal":

(am.wav)

Note que o apito da portadora pode ser claramente ouvido. Esta é a modulação utilizada pela rádio AM tradicional.

Segue o programa Python que gerou as modulações AM-SC e AM "tradicional":


#!/usr/bin/env python

import wave, struct, math

baseband = wave.open("paralelepipedo_lopass.wav", "r")

amsc = wave.open("amsc.wav", "w")
am = wave.open("am.wav", "w")
carrier = wave.open("carrier3000.wav", "w")

for f in [am, amsc, carrier]:
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(44100)

for n in range(0, baseband.getnframes()):
base = struct.unpack('h', baseband.readframes(1))[0] / 32768.0
carrier_sample = math.cos(3000.0 * (n / 44100.0) * math.pi * 2)

signal_am = signal_amsc = base * carrier_sample
signal_am += carrier_sample
signal_am /= 2

amsc.writeframes(struct.pack('h', signal_amsc * 32767))
am.writeframes(struct.pack('h', signal_am * 32767))
carrier.writeframes(struct.pack('h', carrier_sample * 32767))


A modulação AM-SC é simplesmente a multiplicação do sinal original, cuja banda é previamente confinada numa faixa, por uma portadora, que é nada mais que uma onda senoidal.

A modulação AM tradicional é a mesma coisa, exceto que a portadora é adicionada ao sinal modulado, depois da multiplicação. Isto permite que o receptor seja consideravelmente mais simples, conforme veremos.

Bem, agora tá na hora de demodular, ou seja, tentar recuperar o sinal original, usando os arquivos WAV modulados. A demodulação AM-SC consiste em nova multiplicação pela portadora, seguida de um filtro passa-baixas. Segue os resultados, antes e depois do filtro:

(demod_amsc_ok.wav)

(demod_amsc_ok_lopass.wav)

A demodulação AM-SC é essencialmente igual à modulação. O efeito de multiplicar duas vezes pela mesma portadora joga de volta o sinal para sua banda original (0-1000Hz), criando uma nova cópia indesejável em torno de 6000Hz, que removemos com o filtro.

Segue o código do demodulador AM-SC:


modulated = wave.open("amsc.wav", "r")

demod_amsc_ok = wave.open("demod_amsc_ok.wav", "w")
demod_amsc_nok = wave.open("demod_amsc_nok.wav", "w")
demod_amsc_nok2 = wave.open("demod_amsc_nok2.wav", "w")

for f in [demod_amsc_ok, demod_amsc_nok, demod_amsc_nok2]:
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(44100)

for n in range(0, modulated.getnframes()):
signal = struct.unpack('h', modulated.readframes(1))[0] / 32768.0
carrier = math.cos(3000.0 * (n / 44100.0) * math.pi * 2)
carrier_phased = math.sin(3000.0 * (n / 44100.0) * math.pi * 2)
carrier_freq = math.cos(3100.0 * (n / 44100.0) * math.pi * 2)

base = signal * carrier
base_nok = signal * carrier_phased
base_nok2 = signal * carrier_freq

demod_amsc_ok.writeframes(struct.pack('h', base * 32767))
demod_amsc_nok.writeframes(struct.pack('h', base_nok * 32767))
demod_amsc_nok2.writeframes(struct.pack('h', base_nok2 * 32767))


Um problema da demodulação AM-SC é que a portadora do receptor tem de ser EXATAMENTE igual à do transmissor. Qualquer diferença em fase ou frequência causa distorções graves no sinal. No código acima, procurei simular problemas com moduladora fora de fase (usando seno em vez de cosseno) e com frequência errada (3100Hz em vez de 3000). Os resultados desastrosos podem ser ouvidos abaixo, já filtrados pelo passa-baixas:

(demod_amsc_nok_lopass.wav)

(demod_amsc_nok2_lopass.wav)

Esta necessidade de manter uma portadora precisa no receptor, sem que haja muitos meios de recuperá-la a partir do sinal modulado, acaba tornando o AM-SC uma modulação pouco prática. Um dos poucos usos reais é a trasnsmissão estéro FM, onde o segundo canal é embutido dentro do próprio áudio, com portadora em 38KHz e sinal-piloto transmitido o tempo todo para garantir a perfeita demodulação no receptor.

Vejamos agora o código do demodulador AM tradicional:


modulated = wave.open("am.wav", "r")

f = demod_am = wave.open("demod_am.wav", "w")
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(44100)

for n in range(0, modulated.getnframes()):
signal = struct.unpack('h', modulated.readframes(1))[0] / 32768.0
signal = abs(signal)
demod_am.writeframes(struct.pack('h', signal * 32767))


Note que este demodulador nem usou seno ou cosseno. Ele é meramente um detector, ou seja, transforma sinais negativos em positivos, o que num rádio real seria feito por um diodo ou ponte de diodos. É isto que permite um receptor AM galena funcionar: basta um diodo e um capacitor.

Segue o resultado antes e depois do filtro passa-baixas:

(demod_am.wav)

(demod_am_lopass.wav)

Ficou um ruidozinho de portadora mesmo na versão filtrada, mas isto se deve muito à filtragem ruim (seria mais fácil filtrar se a freqüencia da portadora fosse muito mais alta que a do sinal original, como é o caso da transmissão de rádio).

Tanto a modulação AM-SC quanto AM tem a séria desvantagem de desperdiçar banda, pois geram duas "cópias" do mesmo sinal ao redor da portadora. Além disso, AM transmite a portadora o tempo todo junto com as cópias. No fim das contas, um transmissor AM gasta 75% da energia transmitindo "bobagens", que não aumentam seu alcance, servem apenas para facilitar o trabalho do receptor.

Mas existe uma forma de resolver isto. Já que o sinal AM-SC possui duas cópias, podemos filtrar uma fora, transmitindo apenas a outra. Isto denomina-se AM-SSB (AM com banda suprimida). Segue o sinal AM-SSB com a cópia inferior (2000-3000Hz) filtrada:

(amssb.wav)

Não parece muito diferente do sinal AM-SC, e de fato o mesmo demodulador AM-SC consegue recuperar a voz original a partir do sinal AM-SSB:

(demod_amssb_ok.wav)

(demod_amssb_ok_lopass.wav)

Além de não desperdiçar nenhuma energia (apenas uma cópia do sinal é transmitida, sem a portadora), o AM-SSB tem uma outra vantagem, ainda mais surpreendente. Veja o que acontece com a voz demodulada com uma portadora fora de fase:

(demod_amssb_nok_lopass.wav)

A voz foi recuperada normalmente. Desta forma, o receptor AM-SSB não precisa se preocupar com a fase da portadora gerada localmente, o que facilita muito as coisas. A freqüência ainda é importannte, qualquer desvio causa a mesma distorção que a observada em AM-SC:

(demod_amssb_nok2_lopass.wav)

AM-SSB é a modulação padrão utilizada pela radiocomunicação em geral (radioamador, polícia, aviação, etc. etc.). Além disso, a mesma técnica básica é utilizada em multiplexadores FDM, no sinal de vídeo da TV analógica, e na transmissão do canal estéreo das rádios FM (o segundo canal é modulado dentro do áudio, com portadora de 38KHz e largura de 19KHz).

A remoção da cópia excedente no transmissor pode ser feita com um filtro analógico, embora seja difícil e caro construir o filtro com as características necessárias. Rádios com processamento digital de sinais podem utilizar uma técnica denominada Transformada de Hilbert, o que dispensa este componente.
blog comments powered by Disqus