Thursday 22 February 2018

0xfe binary options


Conversão de Tipo de Dados TOTIMESTAMP Expressão de sintaxe é uma cadeia de caracteres incluída entre aspas simples ou uma marca de hora de época UNIX, não incluída entre aspas simples. 39format39 é um especificador de formato colocado entre aspas simples que define um padrão para a formatação de saída. Use esta opção somente quando a expressão é uma seqüência de caracteres, não um timestamp de época UNIX. TOTIMESTAMP Notas de Uso Especifique um formato usando padrões definidos na classe Joda DateTimeFormat. A função TOTIMESTAMP leva um timestamp de época Unix. A função TODATE leva um timestamp de época UNIX em milissegundos. TOTIMESTAMP Exemplos Converter uma data para um carimbo de data / hora. Converter o tempo de Unix Epoch para um timestamp. Converter uma data UTC para um deslocamento de carimbo de hora do código de fuso horário UTC. Limitação de fuso horário Atualmente o Drill não suporta a conversão de uma data, hora ou carimbo de data / hora de um fuso horário para outro. Consultas de dados associados a um fuso horário podem retornar resultados inconsistentes ou um erro. Para obter mais informações, consulte o quotUnderstanding Drill39s Timestamp e Timezonequot blog. O fuso horário Drill é baseado no fuso horário do sistema operacional, a menos que você o substitua. Para contornar a limitação, configure o Drill para usar o tempo UTC-based, converter seus dados para timestamps UTC e executar operação de data / hora em UTC. Dê uma olhada na configuração do fuso horário Drill executando a função TIMEOFDAY ou consultando a tabela system. options. Essa função TIMEOFDAY retorna a data e hora local com informações de fuso horário. Configure o formato de fuso horário padrão em /conf/drill-env. sh adicionando - Duser. timezoneUTC a DRILLJAVAOPTS. Por exemplo: Reinicie o shell de drill. Confirme se Drill está agora definido como UTC: Pode utilizar a opção z para identificar o fuso horário no TOTIMESTAMP para se certificar de que o carimbo de data / hora tem o fuso horário. Além disso, use a opção z para identificar o fuso horário em um timestamp usando a função TOCHAR. Por exemplo: Copyright 2017-2017 A Apache Software Foundation, licenciada sob a Licença Apache, Versão 2.0. Apache e o logotipo da pena de Apache são marcas registradas da fundação do software de Apache. Outros nomes que aparecem no site podem ser marcas registradas de seus respectivos proprietários. Explorando JPEG Este arquivo é um arquivo HTML e um programa Haskell alfabetizado. Se você renomeá-lo para. lhs você pode compilá-lo com GHC 6.6. Este é um decodificador JPEG funcional, se limitado. Ele só decodifica tons de cinza, imagens de 8 bits e é excessivamente sensível às opções usadas. Eu pensei que as pessoas podem gostar de aprender um pouco sobre o padrão JPEG. Francamente, você pode simplesmente ignorar todo o código se você não entende Haskell. Um bitstream JPEG consiste em vários segmentos. Cada byte no arquivo pertence a um segmento e cada segmento segue um formato comum: 0x01. 0xfe (tipo de segmento) comprimento do cabeçalho (frequentemente incluído, mas não sempre) Após o cabeçalho bytes de comprimento pode vir um fluxo codificado de bytes. Se o fluxo codificado de bytes contiver um 0xff. Um 0 x 00 é recheado depois para se certificar de que o 0xff isnt confundido com o início do próximo cabeçalho. Eu vou colocar no primeiro pedaço de código agora, então eu tenho que tirar o módulo de coisas fora do caminho. Você pode ignorar este são todos os módulos padrão, exceto para BitSyntax que é um módulo auxiliar para análise de formatos binários. Agora, heres o código que leva um arquivo JPEG e retorna uma lista de segmentos. Ele procura o marcador de início de segmento e retorna uma lista de tipos de segmento eo corpo desse segmento. Seu um pouco frouxo porque não pula o cabeçalho do segmento para aqueles segmentos que têm um comprimento. Assim é possível que ele vai encontrar um marcador nos cabeçalhos. No entanto, basta para as nossas necessidades. Neste ponto Ill apresentar nossa imagem de teste: Executando jpegSegments neste arquivo dá os seguintes segmentos Tipo de segmento Comprimento do segmento O segmento APP0 marca este arquivo como um JFIF / JPEG. JFIF define alguns campos extras (como a resolução da imagem e uma miniatura opcional) e você pode descobrir mais sobre isso aqui. Quase todos os JPEGs encontrados na natureza serão arquivos JFIF. O esboço do arquivo JPEG é que ele contém um quadro (imagem) e que o quadro pode uma das varreduras mais. As varreduras podem dar progressivamente mais detalhes, ou podem ser eixos diferentes do espaço de cores etc. Para este exemplo, temos apenas uma varredura e apenas um eixo de espaço de cor (luminância, por causa de sua escala de cinza). As tabelas de quantificação e Huffman são necessárias para a descodificação da imagem, então a primeira coisa que fazemos é analisar e armazenar as informações neles. Bem estar armazenando as informações em uma estrutura: Pode haver muitas tabelas Huffman e quantisation definidas e varreduras diferentes podem usar tabelas diferentes. Então, nós armazenamos um mapa de tabelas, embora só esperamos um. Primeiro analisamos a tabela de quantificação (o segmento é chamado DQT na especificação JPEG e você verá esses nomes de tripleto aparecendo de vez em quando). Não se preocupe com o que uma tabela de quantificação é ainda muito, bem chegar a isso mais tarde, é basicamente apenas uma matriz de valores de 64. O segmento de tabela de quantificação se parece com: 0xdb (tipo de segmento) comprimento de precisão de segmento em 64 elementos de u8 ou U16 valores de quantificação em ordem ziguezague As últimas três linhas são repetidas para o comprimento do segmento. Heres o código de análise Huffman codificação Im indo para assumir que você sabe o que Huffman codificação é, se não você pode ler sobre ele. JPEG define um modo para Huffman e codificação aritmética, mas, devido a questões de patentes, apenas Huffman é visto na natureza. A codificação aritmética é mais lenta, mas obtém cerca de 10 compressão melhor para arquivos JPEG. As árvores de Huffman em JPEG nunca são mais profundas do que 16 elementos e são comunicadas com duas listas. O primeiro é 16 elementos de comprimento e dá o número de valores em cada profundidade na árvore. (Assim, o primeiro elemento dá o número de valores que são apenas um passo da raiz da árvore, o segundo o número que são dois passos, etc). A segunda lista é uma lista de elementos, por ordem de profundidade. O padrão JPEG fornece uma definição muito complexa de como construir as árvores de Huffman (o que parece ser um caso de otimização prematura). O algoritmo real é o seguinte: Comece com uma árvore vazia Para cada par (elemento, profundidade) na lista de elementos (em ordem): Vá passos em profundidade a partir da raiz, sempre indo para a esquerda em cada etapa se há espaço para fazê-lo. (Os elementos estão sempre nas folhas das árvores, então se a subárvore esquerda é um elemento, ou é uma árvore completamente terminada por elementos, você não pode ir para a esquerda) Onde você parar, insira o elemento Heres nossa estrutura de árvore: Cada nó no Árvore está vazia. Full (um nó folha, com no elemento Int) ou uma árvore com uma fullness-flag, e leftright filhos. O sinalizador de plenitude para cada nó de árvore é verdadeiro se não mais elementos podem ser inseridos nele. Isso nos poupa da necessidade de retroceder. O tipo Branch é usado para armazenar os passos que levamos para inserir o elemento. Isso é necessário se você está indo para implementar uma pesquisa de tabela rápida (não estamos neste caso, por isso é apenas um exemplo.) Heres a função para adicionar um elemento para a árvore. Você pode verificar os padrões, se quiser: Construir uma árvore é apenas um caso de chamar huffTreeAdd para cada par (profundidade, elemento) na tabela Huffman. Nós jogamos fora o caminho de Branch es, mas isso é onde você iria construir uma tabela de pesquisa se você queria velocidade. Olhando acima valores da árvore é muito simples, você apenas anda a árvore até que você bate um elemento. Esta função usa uma lista de Bool s como uma lista de bits onde true significa tomar a subárvore direita. Retorna o elemento e a lista restante de bits. Agora que você conhece a teoria, há apenas a questão de como ler os bytes. Lembre-se que só precisamos da lista de comprimentos e da lista de elementos, a partir da qual o layout do segmento é óbvio: elementos, por ordem de profundidade Como as tabelas de quantização, as últimas quatro linhas são repetidas para o comprimento do segmento. Heres a função de análise, retorna a classe, id e uma lista de pares (de profundidade, elemento): Existem dois outros segmentos que precisamos analisar, o início da moldura eo início da digitalização. Seus formatos exatos não são importantes, eles contêm o que você esperaria: a largura ea altura da imagem, número de componentes (eixo de espaço de cor) e quais tabelas para usar na decodificação: Theres também uma função que traduz os valores de retorno destas parsing Funções em mudanças na estrutura JpegState (que nós definimos maneira acima se você lembrar): A Transformação de Coseno Discreto estavam quase prontos para começar a decodificar o coração de JPEG - o DCT. Ao codificar uma imagem, sua divisão em 8x8 quadrados de pixels. Cada um desses quadrados é então transformado através da DCT (que é totalmente reversível). Você pode pensar no DCT como alterando os pixels do tempo para o domínio da freqüência: o gráfico tempo vs amplitude de uma forma de onda está no domínio do tempo ea parcela de frequência vs amplitude (como você vê em um equalizador gráfico) está na freqüência domínio. O DCT é totalmente reversível. Você também pode pensar no DCT como uma função que transforma uma grade de 8x8 pixels em uma combinação linear das seguintes funções de base gráfica: Existem 64, 8x8 imagens lá. O superior esquerdo é chamado de componente DC e todo o resto são componentes AC. Esperançosamente você pode ver que um bloco 8x8 contínuo é sempre alguma fração do azulejo esquerdo superior. Se o bloco de 8x8 desvanece-se para o fundo, adicione então um pouco da telha imediatamente abaixo. Pode não ser óbvio que todos os blocos de 8x8 pixels podem ser representados como combinações lineares dessas telhas, mas é verdade. A componente DC é a onda de coseno que não faz ciclos sobre o bloco 8x8. Indo um azulejo à esquerda, essa é a onda de coseno que faz metade de um ciclo sobre o bloco. Próxima telha ao longo faz um ciclo sobre o bloco e assim por diante. Ir para esquerda aumenta a frequência horizontal e descer aumenta a frequência vertical. No entanto, o olho humano tem sensibilidades diferentes nestas frequências. A maioria das telhas de alta freqüência pode ser jogada fora sem qualquer efeito perceptível. Este jogando fora é gerenciado dividindo a amplitude de cada ladrilho por um número fixo na esperança de que muitos deles vão para zero. Quanto maior o divisor, menor a qualidade e os divisores são ponderados de modo que os componentes de alta freqüência são divididos por um número maior. A lista de divisores é a tabela de quantificação que tratamos antes. Você pode executar o DCT correlacionando os valores de pixel com as funções coseno, que, para o caso 1-d, é o mesmo que multiplicar pela matriz DCT: Como cada linha é ortogonal, o inverso dessa matriz é apenas sua transposição. Representamos uma matriz como uma lista de linhas, onde cada linha é uma lista de valores. Isto nos dá as funções de transposição, vetorvector, matrizvector e matrixmatrix: Também podemos definir a matriz DCT 8x8 inversa: codificação DCT Agora entendemos que para decodificar a imagem precisamos apenas obter os coeficientes DCT para cada bloco 8x8, multiplicar pela quantificação Tabela e executar a DCT inversa para obter os valores de pixel. A questão restante é como decodificar os coeficientes DCT. Primeiro, os blocos 8x8 são codificados em ordem de varredura (da esquerda para a direita, de cima para baixo) e, onde a imagem não é um número inteiro de blocos de 8x8, os pixels mais à direita e mais baixos são repetidos para torná-lo assim. Para cada bloco 8x8 o coeficiente DC é codificado primeiro usando uma tabela de Huffman e os coeficientes de AC seguem (todos os 63 deles) usando outra tabela de Huffman (e outro esquema de codificação). Ambos DC e AC usam o mesmo esquema de codificação inteiro, no entanto, que é o que bem cobrir próxima: Um número inteiro é codificado por Huffman codificação seu intervalo e, em seguida, twos complementar a codificação do deslocamento dentro desse intervalo. Os intervalos têm a seguinte aparência: SSSS (número de intervalo) O valor SSSS é o elemento da árvore Huffman (para DC) eo número de bits de arrasto. Portanto, se você decodificar 3 da árvore de Huffman, você toma os três bits a seguir do fluxo de bits. O primeiro desses bits é verdadeiro se você está contando a partir do fundo da subrange positivo e false se você está contando a partir do fundo da subrange negativo. Os dois últimos são o número a ser adicionado a esse valor base: O valor DC de cada bloco DCT é codificado como a diferença do valor DC do último bloco decodificado. (O valor DC do bloco antes do primeiro é considerado 0). Este código não faz a diferença, apenas decodifica o valor: os valores AC são um pouco diferentes. Em primeiro lugar, há 63 deles em cada bloco e geralmente há longas corridas de zeros entre valores. Assim, a árvore AC Huffman decodifica dois valores: um valor SSSS (nos 4 bits inferiores), tal como acima e um valor RRRR (nos quatro bits superiores), que dá o número de zeros anteriores. Portanto, se a árvore AC Huffman decodifica um valor de 0x53, isso é SSSS 3 e RRRR 5 e resulta nos valores 0, 0, 0, 0, 0, x. Onde x está na gama -31 ..- 16,16..31. Você decodificar os três bits a seguir para localizar o valor exato para x. Existem também códigos especiais para 16 zeros (0x00) e para terminar os valores de CA para este bloco (0xf0) uma vez que os blocos terminam frequentemente com muitos valores zero. Claramente, a codificação Huffman dos valores AC funciona melhor quando há lotes de execuções de zeros e muitos zeros no final. Componentes de alta freqüência são susceptíveis de ser quantised a zero, mas se tomarmos os valores de CA em ordem raster, os componentes de freqüência mais alta não estarão sempre no final. Assim, os valores de CA são codificados em ordem ziguezague. Heres um diagrama: E heres o código: Estamos, finalmente, pronto para decodificar o JPEG, mas primeiro eu preciso para obter algumas funções auxiliares fora do caminho. Os dois primeiros (groupSize e d8ru) são triviais. O último, bytesToBits converte um bloco de dados de memória em uma lista de bits, removendo o 0x00 recheado após cada 0xff (lembre-se que esses bytes recheados são colocados lá para parar os dados de Huffman parecendo o início do próximo segmento). Agora, a função de decodificação. Ive adicionou comentários no final de algumas das linhas para que você possa acompanhar. Primeiro vamos descobrir quantos blocos DCT existem (0), este é apenas o número de blocos em uma linha vezes o número de linhas sobre a altura de um bloco. Em seguida, (1) decodificamos o delta DC e adicionamo-lo ao último valor DC (2). Então podemos decodificar todos os valores AC (3) e multiplicar todos os coeficientes DCT pela tabela de quantificação (4). Finalmente des-ziguezague e realizamos a DCT inversa (5) e foram feitas. Isto é feito para cada bloco DCT no arquivo e nós terminamos com uma lista de 8x8 matrizes de valores de pixels. Esses valores de pixel são de -128 a 128 (porque o DCT funciona melhor quando eles são simétricos em torno de 0). Devido a alguns erros de arredondamento, os valores reais podem exceder esse intervalo e, portanto, precisam ser fixados no tempo de saída. Acabamento A última função fornece a lista de matrizes de valores de pixels para um arquivo PGM. Percorremos cada linha de valores de DCT oito vezes para obter cada linha de varredura (0) e, para cada valor de pixel, somamos 128 e prendemos o intervalo (1). E então theres a função principal que apenas faz um decodificador de exemplo que lê de test. jpeg e escreve para out. pgm. Heres o resultado (convertido em PNG): 0xFE - 11111110b - 0376 - 254 - b99 VexFlow é ES6 Graças ao heroísmo de SilverWolf90 e AaronMars. E a ajuda de muitos outros, VexFlows src / tree inteiro foi migrado para ES6. Este é um enorme benefício para o projeto e para a saúde da base de código. Algumas das vitórias são: Módulos reais, que nos permite extrair informações de dependência explícitas e gerar gráficos como este. Const-correção e escopo variável previsível com const e let. Classes, funções lambda e muitos outros aprimoramentos estruturais que melhoram muito a clareza e concisão do codebase. Parte do esforço de migração também envolveu fazer tudo limpo, melhorando o estilo geral ea consistência da base de código - veja o breve documento do SilverWolf90 sobre como aqui. Testes de regressão visual VexFlow agora tem um sistema de teste de regressão visual e todos os testes QUnit geradores de imagens são automaticamente incluídos. O objetivo deste sistema é detectar diferenças na produção renderizada sem ter que confiar em globos oculares humanos, especialmente dado o grande número de testes que existem hoje. Ele faz isso ao calcular um hash perceptivo (PHASH) de cada imagem de teste e compará-lo com o hash de uma imagem abençoada bem conhecida. Quanto maior a distância aritmética entre os hashes, mais diferentes são as duas imagens. O sistema também gera uma imagem diff, que é uma sobreposição das duas imagens, com as diferenças realçadas, para facilitar a depuração. Heres um exemplo de um teste de falha: Esses testes são executados automaticamente para todos os PRs, compromissos e lançamentos. Props para Taehoon Moon para a migração dos testes de regressão de NodeJS para SlimerJS, dando-nos headless apoio e Travis CI integração. Para saber mais, leia a página Wiki em Testes de Regressão Visual. SVG nativo Graças à incrível contribuição de Gregory Ristow. O VexFlow agora possui um backend de renderização SVG nativo eo back-end RaphaelJS foi reprovado. Isso não só reduz o tamanho global e inchaço, mas também melhora muito desempenho de renderização. O novo backend é chamado Rendering. Backends. SVG com o código em Vex. Flow. SVGContext. Aqui está um exemplo rápido de como usar o novo backend: jsfiddle. net/nL0cn3vL/2/. Melhor suporte microtonal VexFlow agora tem melhor suporte para árabe, turco e outras músicas microtonais através de acidentes e assinaturas-chave. Graças ao infojunkie para um monte de o levantamento de peso aqui, e para todos os contribuintes na questão GitHub. O suporte microtónico não é de forma alguma completo, mas este é um passo notável no espaço. Outras coisas Muitas outras coisas que vale a pena mencionar: Suporte para a interatividade do usuário em notação SVG. Você pode anexar manipuladores de eventos a elementos (ou grupos de elementos) e modificar dinamicamente várias propriedades da partitura. Melhorado suporte de caixa delimitadora. Alinhamento de clef, timesignature, e outros modificadores stave durante mid-measure changes. Muitas melhorias para o sistema de construção e integração Travis CI. Muitas correções de bugs relacionadas à transmissão, tuplas, anotações, etc. Muitos agradecimentos a todos os colaboradores envolvidos Foi um ano desde que eu postei alguma coisa, então como sobre algumas novidades Muitas novidades em VexFlow e VexTab. Meu VexFlow Lançamos o My VexFlow. Uma plataforma de publicação de conteúdo para músicos baseada no VexFlow. A plataforma permite que os músicos, professores de música, estudantes para criar, publicar e compartilhar conteúdo com notação de música bonito, tablatura, gráficos de acordes, diagramas, etc Aqui estão alguns strawmen que eu criei para mostrar o que My VexFlow pode fazer: Você também pode incorporar Conteúdo do My VexFlow em seus próprios sites e blogs, assim como você faria com um vídeo do YouTube. Heres um exemplo. A notação acima foi criada no My VexFlow, e incorporada nesta postagem no blog. Um novo VexTab VexTab foi revisado mais uma vez, desta vez reescrito em CoffeScript e Jison. O código é muito mais limpo, mais flexível e mais gerenciável. O novo VexTab já não é apenas para guitarristas - sua sintaxe de nota / oitava, além da sintaxe fret / string. Ele também suporta quase todos os recursos do VexFlow, como tuplas, restos, articulações, símbolos de pontuação e modificadores, etc. Também é movido para seu próprio repositório: github / 0xfe / vextab Guitarra e Fretboards de Baixo Meu VexFlow tem suporte para fretboards de guitarra, que você Pode personalizar e usar para diagramas descritivos. Slash Notation Render gráficos de acordes com dicas rítmicas usando notação barra. Isso também é útil para algumas notação de bateria. Muito mais Isto não é tudo. Há anotações de pontuação, tuplas, anotações de ponteiras, etc. etc. Veja a lista completa em: Novo em My VexFlow. Experimentar e aproveitar Passei um pouco mais de tempo experimentando com k-significa agrupamento em imagens e percebi que eu poderia usar esses clusters para recolorir a imagem de formas interessantes. Eu escrevi a função saverecolor para substituir pixels de determinados clusters (substituições) por novos de igual intensidade, conforme especificado pelo vetor rgbfactors. Por exemplo, o código a seguir converterá pixels dos dois primeiros clusters para greyscale. Seu greyscale porque o rgbfactors distribui a intensidade do pixel uniformemente entre os canais. Um fator de c (20/100, 60/100, 20/100) tornaria os pixels do cluster 60 mais verdes. Permite obter alguns exemplos. Heres uma imagem unprocessed, ao lado de seus conjuntos da cor. Eu escolhi k10. Você pode definir k especificando o parâmetro palettesize para saverecolor. Heres o que acontece quando eu remover o vermelho (o primeiro cluster). Na imagem seguinte, mantenho o vermelho e removo tudo o resto. Abaixo, substituo os pixels do cluster vermelho, com os verdes de intensidade correspondente. E este é um divertimento um: Livrar-se de tudo, manter apenas a grama. Eu tentei isso em várias imagens, usando diferentes tamanhos de cluster, substituições e fatores RGB, com muitos resultados interessantes. De qualquer forma, você deve experimentar com isto vocês mesmos e deixe-me saber o que você encontrar. Devo salientar que nada aqui é novo ou novo - é tudo bem conhecido nos círculos de processamento de imagens. Ainda é bastante impressionante o que você pode fazer quando você aplica algoritmos de aprendizagem de máquina simples para outras áreas. Ok, como em todas as minhas postagens, o código está disponível no meu repositório GitHub. Meu colega de trabalho do Google, Tony Rippy, tem trabalhado por um tempo em um problema fascinante. Pegue todos os pixels de uma fotografia e reorganize-os para que a imagem final se pareça com uma paleta de artistas - algo para a qual você pode pegar um pincel e recriar a imagem original. Hes tem algumas soluções realmente boas olhando que pôde afixar se você lhe perguntar agradàvel. -) Isso acaba por ser um problema complicado, e é difícil chegar a uma medida objetiva da qualidade de qualquer solução dada. Na verdade, a qualidade é muito subjetiva. De qualquer forma, ao estudar o algoritmo de clustering K-means de ml-class. Me pareceu que k-means poderia ser usado para ajudar com a extração de uma pequena paleta de cores de uma imagem. Por exemplo, usando cada um dos canais RGB como características e distância euclidiana como a métrica de similaridade, pode-se executar k-meios de estoque para gerar clusters de cores semelhantes. Eu codifiquei um rápido script R para testar isso e tenho alguns resultados interessantes. Aqui está um exemplo de uma imagem com sua paleta potencial. Lembre-se de que a segunda imagem é simplesmente a primeira imagem com os pixels rearranjados. Experimentei com vários valores de k (número de clusters) para as diferentes imagens. Acontece que o seu bastante difícil de algoritmicamente pré-determinar este número (embora existam várias técnicas que existem.) A água villa pic acima tem 15 clusters, o viveiro pic abaixo tem 20, eo desenho animado tem 6. Note que este É apenas um subproblema do original há também o subproblema de colocação, que eu contornei ao redor simplesmente arranjando as cores em faixas verticais através da imagem final. Im consideravelmente nenhuma paleta dos artistas olha como este. Também, essas paletas arent muito limpos. Desde que as imagens originais eles próprios são barulhentos, alguns deste ruído arbitrariamente fluem para os vários clusters. Trabalhar com uma versão filtrada da imagem seria batota, então nós não vamos fazer isso. Mas poderemos extrair os pixels ruidosos, colocá-los em um cluster especial e executar k-means nos pixels restantes. Primeiro instale os pacotes cclust e ReadImages do CRAN. E experimentar o algoritmo em um console R: Isto irá produzir um enredo com a imagem original eo transformado um ao lado do outro, como o anexo fotos abaixo. Ele usa 10 clusters por padrão, para uma paleta de 10 cores. Você pode alterar isso passando a contagem de cluster como o segundo parâmetro para plotpalette. Isso é tudo pessoal No meu último post, eu passei sobre alguns dos conceitos básicos da Web Audio API e mostrou-lhe como gerar ondas seno de várias freqüências e amplitudes. Fomos apresentados a algumas classes de áudio da Web. Tais como AudioContext. AudioNode. E JavaScriptAudioNode. Desta vez, eu vou ir levar as coisas um pouco mais longe e construir um analisador de espectro em tempo real com Web Audio e HTML5 Canvas. O produto final reproduz um arquivo de música remoto e exibe o espectro de freqüência sobreposto com um gráfico de domínio de tempo. A demo está aqui: Analisador de Espectro JavaScript. O código da demo está no meu repositório GitHub. As novas classes Neste post apresentamos três novas classes Web Audio: AudioBuffer. AudioBufferSourceNode. E RealtimeAnalyzerNode. Um AudioBuffer representa um recurso de áudio na memória. Geralmente é usado para armazenar clipes de áudio curtos e pode conter vários canais. Um AudioBufferSourceNode é uma especialização do AudioNode que serve áudio de AudioBuffer. Um RealtimeAnalyzerNode é um AudioNode que retorna informações de análise de tempo e frequência de domínio em tempo real. O encanamento Para começar, precisamos adquirir algum áudio. A API suporta vários formatos diferentes, incluindo MP3 e áudio codificado em PCM bruto. Em nossa demonstração, recuperamos um recurso de áudio remoto (um arquivo MP3) usando AJAX e usamo-lo para preencher um novo AudioBuffer. Isso é implementado na classe RemoteAudioPlayer (js / remoteaudioplayer. js) assim: Observe que o jQuery s AJAX chama arent usado aqui. Isso ocorre porque o jQuery não suporta o tipo de resposta arraybuffer, que é necessário para carregar dados binários a partir do servidor. O AudioBuffer é criado com a função createBuffer do AudioContext. O segundo parâmetro, true. Diz-lhe para misturar todos os canais para um único canal mono. O AudioBuffer é então fornecido para um AudioBufferSourceNode. Que será a fonte de áudio de contextos. Este nó de origem é então conectado a um RealTimeAnalyzerNode. Que por sua vez está ligado ao destino de contextos, isto é, ao dispositivo de saída de computadores. Para iniciar a reprodução da música, chame o método noteOn do nó de origem. NoteOn tem um parâmetro: um timestamp indicando quando iniciar a reprodução. Se definido para 0. ele é reproduzido imediatamente. Para começar a tocar a música em 0,5 segundos a partir de agora, você pode usar context. currentTime para obter o ponto de referência. Também vale a pena notar que especificamos a granularidade da FFT para 2048, definindo a variável analyzer. fftSize. Para aqueles não familiarizados com a teoria de DSP, isso quebra o espectro de freqüência do áudio em 2048 pontos, cada ponto representando a magnitude da n / 2048a freqüência bin. A estratégia geral é pesquisar o analisador a cada poucos milissegundos (por exemplo, com window. setInterval), solicitar os dados de domínio de tempo ou frequência e, em seguida, Renderizá-lo em um elemento HTML5 Canvas. O analisador exporta alguns métodos diferentes para acessar os dados de análise: getFloatFrequencyData. GetByteFrequencyData. GetByteTimeDomainData. Cada um desses métodos preencher um determinado ArrayBuffer com os dados de análise apropriados. No snippet abaixo, agendamos uma função update () a cada 50ms, que divide os pontos de dados de domínio de freqüência em 30 bins e representa uma barra representando a magnitude média dos pontos em cada bin. Uma estratégia semelhante pode ser empregada para dados de domínio de tempo, exceto por algumas pequenas diferenças: Os dados de domínio de tempo são normalmente renderizados como ondas, então você pode querer usar muito mais bins e plotar pixels em vez de barras de desenho. O código que processa os gráficos de domínio de tempo e freqüência na demo é encapsulado na classe SpectrumBox em js / spectrum. js. O Minutiae Eu glosou sobre um número de coisas neste borne, na maior parte com respeito aos detalhes do demo. Você pode aprender tudo a partir do código-fonte, mas heres um resumo para o impaciente: Os gráficos são na verdade dois HTML5 Canvas elementos sobreposto usando CSS absoluto posicionamento. Cada elemento é usado por sua própria classe SpectrumBox, uma que exibe o espectro de freqüência, a outra que exibe a onda do domínio do tempo. O roteamento dos nós é feito no manipulador onclick para o botão de reprodução - ele leva o AudioSourceNode do RemoteAudioPlayer. Roteia-lo para o nó do analisador de freqüência, rotas que para o nó do analisador de domínio do tempo, e, finalmente, para o destino. Bônus: Outra demonstração Isso é tudo pessoal Agora você tem o know-how para construir um novo analisador de espectro gráfico. Se tudo o que você quer fazer é jogar com as ondas e olhar para os gráficos, confira a minha outra demonstração: The Web Audio Tone Analyzer (source). Este é realmente apenas o mesmo analisador de espectro da primeira demo, conectado ao gerador de tom do último post. Como lembrete, todo o código para minhas postagens está disponível no meu repositório GitHub: github / 0xfe. A faixa de áudio usada na demo é uma tomada descartada de Who-Da-Man. Que eu gravei com a minha banda anterior Captain Starr muitos anos atrás. Finalmente, não se esqueça de ler a Web Audio API especificação preliminar para obter mais informações.

No comments:

Post a Comment