Circular buffer moving average


Eu sei que isso é possível com o aumento como por: Mas eu realmente gostaria de evitar o uso de impulso. Eu pesquisei e não encontrei nenhum exemplo adequado ou legível. Basicamente, quero rastrear a média móvel de um fluxo contínuo de um fluxo de números de ponto flutuante usando os 1000 números mais recentes como amostra de dados. Qual é a maneira mais fácil de conseguir isso, experimentei usar uma matriz circular, média móvel exponencial e uma média móvel mais simples, e descobri que os resultados da matriz circular se adequavam melhor às minhas necessidades. perguntou 12 de junho de 12 às 4:38 Se as suas necessidades são simples, você pode tentar usar uma média móvel exponencial. Simplificando, você cria uma variável de acumulador e, à medida que seu código examina cada amostra, o código atualiza o acumulador com o novo valor. Você escolhe um alfa constante que esteja entre 0 e 1 e calcula isso: você só precisa encontrar um valor de alfa onde o efeito de uma determinada amostra dura apenas cerca de 1000 amostras. Hmmm, eu não tenho certeza se isso é adequado para você, agora que eu coloquei aqui. O problema é que 1000 é uma janela muito longa para uma média móvel exponencial Não tenho certeza se existe um alpha que possa distribuir a média nos últimos 1000 números, sem underflow no cálculo do ponto flutuante. Mas se você quisesse uma média menor, como 30 números ou mais, essa é uma maneira muito fácil e rápida de fazer isso. respondeu 12 de junho às 12:44 1 em seu post. A média móvel exponencial pode permitir que o alfa seja variável. Então, isso permite que ele seja usado para calcular as médias da base de tempo (por exemplo, bytes por segundo). Se o tempo desde a última atualização do acumulador for maior que 1 segundo, você deixa o alpha ser 1.0. Caso contrário, você pode deixar o alpha ser (usecs desde a última atualização / 1000000). Basicamente eu quero acompanhar a média móvel de um fluxo contínuo de um fluxo de números de ponto flutuante usando os 1000 números mais recentes como uma amostra de dados. Observe que o abaixo atualiza o total como elementos adicionados / substituídos, evitando o deslocamento O (N) caro para calcular a soma - necessária para a média - sob demanda. Total é feito um parâmetro diferente de T para suportar, e. usando um longo longo ao totalizar 1000 long s, um int para char s, ou um double para total float s. Isso é um pouco defeituoso, pois as amostras podem passar do INTMAX - se você se importar, pode usar um sinal longo sem assinatura. ou use um membro extra de dados de bool para registrar quando o contêiner é preenchido pela primeira vez enquanto circula números em torno do array (melhor que renomeie algo inócuo como pos). Resposta: 12 de junho, às 5:19, assume-se que o operador "qvoid" (amostra T) é, na verdade, o operador "co-vi" ("amostra T"). ndash oPless Jun 8 14 às 11:52 oPless ahhh. bem manchado. na verdade eu quis dizer que seria void operator () (amostra T), mas é claro que você poderia usar qualquer notação que você gostasse. Vai consertar, obrigado. Tony D Jun 8 14 at 14: 27The Scientist and Engineers Guide to Digital Signal Processing Por Steven W. Smith, Ph. D. Capítulo 28: Processadores de sinal digital Os processadores de sinal digital são projetados para executar rapidamente filtros FIR e técnicas similares. Para entender o hardware. devemos primeiro entender os algoritmos. Nesta seção, vamos fazer uma lista detalhada das etapas necessárias para implementar um filtro FIR. Na próxima seção, veremos como os DSPs são projetados para executar essas etapas da maneira mais eficiente possível. Para começar, precisamos distinguir entre processamento off-line e processamento em tempo real. No processamento off-line, todo o sinal de entrada reside no computador ao mesmo tempo. Por exemplo, um geofísico pode usar um sismógrafo para registrar o movimento do solo durante um terremoto. Após a agitação, a informação pode ser lida em um computador e analisada de alguma forma. Outro exemplo de processamento off-line é a imagem médica, como a tomografia computadorizada e a ressonância magnética. O conjunto de dados é adquirido enquanto o paciente está dentro da máquina, mas a reconstrução da imagem pode ser atrasada até um momento posterior. O ponto-chave é que todas as informações estão disponíveis simultaneamente para o programa de processamento. Isso é comum em pesquisa e engenharia científica, mas não em produtos de consumo. O processamento off-line é o domínio de computadores pessoais e mainframes. No processamento em tempo real, o sinal de saída é produzido ao mesmo tempo que o sinal de entrada está sendo adquirido. Por exemplo, isso é necessário na comunicação telefônica, aparelhos auditivos e radar. Esses aplicativos devem ter as informações imediatamente disponíveis, embora possam ser atrasadas por um curto período. Por exemplo, um atraso de 10 milissegundos em uma chamada telefônica não pode ser detectado pelo alto-falante ou ouvinte. Da mesma forma, não faz diferença se um sinal de radar é atrasado por alguns segundos antes de ser exibido ao operador. Aplicativos em tempo real inserem uma amostra, executam o algoritmo e geram uma amostra, over-and-over. Alternativamente, eles podem inserir um grupo de amostras, executar o algoritmo e gerar um grupo de amostras. Este é o mundo dos processadores de sinal digital. Agora olhe para trás na Fig. 28-2 e imagine que este é um filtro FIR sendo implementado em tempo real. Para calcular a amostra de saída, devemos ter acesso a um certo número das amostras mais recentes da entrada. Por exemplo, suponha que usamos oito coeficientes neste filtro, um 0. um 1. hellip a 7. Isso significa que devemos conhecer o valor das oito amostras mais recentes do sinal de entrada, xn, xn-1, hellipxn -7. Essas oito amostras devem ser armazenadas na memória e continuamente atualizadas conforme novas amostras são adquiridas. Qual é a melhor maneira de gerenciar essas amostras armazenadas? A resposta é buffer circular. A Figura 28-3 ilustra um buffer circular de oito amostras. Colocamos esse buffer circular em oito locais de memória consecutivos, 20041 a 20048. A Figura (a) mostra como as oito amostras da entrada podem ser armazenadas em um determinado instante no tempo, enquanto (b) mostra as alterações após a próxima amostra ser adquirido. A idéia do buffer circular é que o final desse array linear é conectado ao seu local de memória inicial. 20041 é visto como próximo a 20048, assim como 20044 fica próximo a 20045. Você acompanha o array por um ponteiro (uma variável cuja value é um endereço) que indica onde reside a amostra mais recente. Por exemplo, em (a) o ponteiro contém o endereço 20044, enquanto que em (b) ele contém 20045. Quando uma nova amostra é adquirida, ela substitui a amostra mais antiga na matriz e o ponteiro é movido com um endereço à frente. Os buffers circulares são eficientes porque apenas um valor precisa ser alterado quando uma nova amostra é adquirida. Quatro parâmetros são necessários para gerenciar um buffer circular. Primeiro, deve haver um ponteiro que indique o início do buffer circular na memória (neste exemplo, 20041). Em segundo lugar, deve haver um ponteiro indicando o final da matriz (por exemplo, 20048), ou uma variável que mantenha o seu comprimento (por exemplo, 8). Terceiro, o tamanho do passo do endereçamento de memória deve ser especificado. Na Fig. 28-3, o tamanho do passo é um. por exemplo: o endereço 20043 contém uma amostra, o endereço 20044 contém a próxima amostra e assim por diante. Isso não é freqüentemente o caso. Por exemplo, o endereçamento pode se referir a bytes, e cada amostra pode exigir dois ou quatro bytes para manter seu valor. Nestes casos, o tamanho do passo precisaria ser dois ou quatro, respectivamente. Esses três valores definem o tamanho e a configuração do buffer circular e não serão alterados durante a operação do programa. O quarto valor, o ponteiro para a amostra mais recente, deve ser modificado à medida que cada nova amostra é adquirida. Em outras palavras, deve haver uma lógica de programa que controle como esse quarto valor é atualizado com base no valor dos três primeiros valores. Embora essa lógica seja bem simples, ela deve ser muito rápida. Este é o ponto principal desta discussão que os DSPs devem ser otimizados no gerenciamento de buffers circulares para alcançar a maior velocidade de execução possível. Como um aparte, o buffer circular também é útil no processamento off-line. Considere um programa em que os sinais de entrada e de saída estão completamente contidos na memória. O tamponamento circular não é necessário para um cálculo de convolução, porque cada amostra pode ser acessada imediatamente. No entanto, muitos algoritmos são implementados em etapas. com um sinal intermediário sendo criado entre cada estágio. Por exemplo, um filtro recursivo executado como uma série de biquads opera dessa maneira. O método de força bruta é armazenar todo o comprimento de cada sinal intermediário na memória. O buffer circular fornece outra opção: armazenar apenas as amostras intermediárias necessárias para o cálculo em questão. Isso reduz a quantidade necessária de memória, às custas de um algoritmo mais complicado. A idéia importante é que os buffers circulares são úteis para o processamento off-line, mas críticos para aplicativos em tempo real. Agora podemos observar as etapas necessárias para implementar um filtro FIR usando buffers circulares para o sinal de entrada e os coeficientes. Essa lista pode parecer trivial e superexaminada - não é O manuseio eficiente dessas tarefas individuais é o que separa um DSP de um microprocessador tradicional. Para cada nova amostra, todas as etapas a seguir precisam ser tomadas: O objetivo é tornar essas etapas executadas rapidamente. Como as etapas de 6 a 12 serão repetidas várias vezes (uma vez para cada coeficiente no filtro), deve ser dada atenção especial a essas operações. Microprocessadores tradicionais geralmente devem executar esses 14 passos em série (um após o outro), enquanto os DSPs são projetados para realizá-los em paralelo. Em alguns casos, todas as operações dentro do loop (etapas 6-12) podem ser concluídas em um único ciclo de clock. Vamos olhar para a arquitetura interna que permite este desempenho magnífico. Ajuda sobre o buffer circular em ASM. Iniciado por malli1729 x25CF 16 de setembro de 2008 Iam New to Assembly linguagem de programação. Iam Apenas tentando aprendê-lo .. Eu quero implementar um buffer circular na linguagem assembly. Eu não posso encontrar os detalhes Implementaion do Circular Buffer .. ou seja, em manuais eu vi informações sobre I, B, L, M registradores e endereçamento linear, Circular Addressing etc. Mas eu não encontrei nenhum código psuedo para isso. Eu não posso implementar um buffer circular simples também. Por ex..A Moving Average FIR filter Meu problema é se eu tenho um Buffer circular eu posso inicializar o B, I, L, M registra correspondentemente ... mas eu não sei se o LOOP irá continuar automaticamente ou então nós precisamos escrever o LOOP explicitamente. Eu não sei se eu expliquei meu problema claramente ou não. se não posso entender, eu posso explicar mais de forma brutal. OBRIGADO U .. ESPERANDO RESPOSTA. Começar um novo tópico Postado por Mike Rosing x25CF 16 de setembro de 2008 Em terça-feira, 16 de setembro de 2008, malli1729 escreveu: gt Oi gt Iam New to Assembly Linguagem de programação. Iam Apenas tentando aprender .. gt Eu quero implementar um buffer circular na linguagem assembly. gt Eu não posso encontrar os detalhes Implementaion do Circular Buffer .. gt significa em manuais eu vi informações sobre I, B, L, M registradores e Linear gt endereçamento, Circular Addressing etc. gt Mas eu não encontrei nenhum código psuedo para aquele. gt gt eu não posso implementar um buffer Circular simples também. Para gt ex..A Filtro FIR Média Móvel gt gt Meu problema é se eu tenho um Buffer circular eu posso inicializar o B, I, L, M gt ​​registra correspondentemente ... mas eu não sei se o LOOP vai continuar automaticamente ou então precisamos escrever o LOOP gt explicitamente. Precisa ser expicit. Confira os exemplos de código no segundo link. Boa sorte e divirta-se Paciência, persistência, verdade, Dr. Mike Inicie um novo tópico Postado por shopping. yahoo. co. in x25CF 17 de setembro de 2008 Oi gtIam Novidade na programação em linguagem de montagem. Iam Apenas tentando aprendê-lo .. gtId quero implementar um buffer circular na linguagem assembly. gtI não consigo encontrar os detalhes Implementaion de Circular Buffer .. i gtmean em manuais eu vi informações sobre I, B, L, M registradores e Linear gtaddressing, Circular Addressing etc. gtBut eu não encontrei nenhum código psuedo para isso. gt gti não pode implementar um buffer Circular simples também. Para gtex..Um filtro FIR média móvel gt gtMeu problema é que se eu tiver um Buffer circular eu posso inicializar os registradores B, I, L, M correspondentemente..mas eu não sei se o LOOP irá continuar automaticamente ou então nós precisamos escrever o LOOP gtexplicitly. Não sei se expliquei meu problema claramente ou não. Se gtcant entender, eu posso explicar mais breifly. gtTHANK U .. gtWAITING PARA RESPOSTA. gt Oi eu estou apenas atualizando a mensagem. O registro de índice deve ser incrementado explicitamente. Acabei de escrever um pequeno código de exemplo, mas iam entrar em problemas quando iam executar o código. Eu só quero ver como o registro do índice está aumentando para que só eu tenha escrito este código. section L1data byte2 em 0x1,0x2,0x3,0x4.align 2.byte2 fil 0x8,0x6,0x4,0x2 // eu quero definir 2 Buffers Circulares um para IN e para Filtro. global principal principal: p0.l lo (em) // P0 Poionado para entrada p0.h hi (em) p1.l lo (fil) // P1 Poionado para Filtro p1.h oi (fil) i0 p0 // Buffer Circular Para entrada b0 p0 l0 0x4 m0 0x2 // p1 4 i1 p1 // Buffer Circular Para Filtro b1 p1 l1 0x4 m1 0x2 p3 0x8 a00 a10 LSETUP (sss, eee) LC0 p3 sss: r1 I0m0 r2 I1m0 // r3 r1.l r2.l a0 r1.l r2.l, a1 r1.h r2.h -------------- gtgtgtgtgtgtgtgtgtgtgtgt r1 I0m0 // A exceção está chegando r2 I1m1 eee: a0 r1.l r2.l, a1 r1.h r2.h main. end: neste código iam recebendo uma exceção desconhecida ocorrida exceção na linha indicada. Qual é a razão pela qual eu não sei. qualquer ajuda. Como pode ser que haja alguma via especial para atualizar o registrador Index ou qualquer outro Inicie um novo tópico Postado por George Kadziolka x25CF 17 de setembro de 2008 O registrador de comprimento precisa ser configurado para o número de bytes em seu bugger circular. Você tem 4 palavras de 16 bits, então L0 e L1 precisam ser 8. Veja o campo EXCAUSE no registrador SEQSTAT para um código que identifica o tipo de exceção. RETX terá o endereço da instrução que causou a exceção. Cobrimos isso e muito mais em nossa oficina Blackfin de 3,5 dias. Confira nosso site. A partir de um. mailto: a. Em nome de m. yahoo. co. in Enviado: quarta-feira, setembro 17, 2008 6:26 AM Para: a. Assunto: adsp Re: Ajuda sobre o buffer circular no ASM. Oi gtIam Novidade na programação em linguagem Assembly. Iam Apenas tentando aprendê-lo .. gtId quero implementar um buffer circular na linguagem assembly. gtI não consigo encontrar os detalhes Implementaion de Circular Buffer .. i gtmean em manuais eu vi informações sobre I, B, L, M registradores e Linear gtaddressing, Circular Addressing etc. gtBut eu não encontrei nenhum código psuedo para isso. gt gti não pode implementar um buffer Circular simples também. Para gtex..Um filtro FIR média móvel gt gtMeu problema é que se eu tiver um Buffer circular eu posso inicializar os registradores B, I, L, M correspondentemente..mas eu não sei se o LOOP irá continuar automaticamente ou então nós precisamos escrever o LOOP gtexplicitly. Não sei se expliquei meu problema claramente ou não. Se gtcant entender, eu posso explicar mais breifly. gtTHANK U .. gtWAITING PARA RESPOSTA. gt Oi eu estou apenas atualizando a mensagem. O registro de índice deve ser incrementado explicitamente. Acabei de escrever um pequeno código de exemplo, mas iam entrar em problemas quando iam executar o código. Eu só quero ver como o registro Index está crescendo para que só eu tenha escrito este código byte em 0x1,0x2,0x3,0x4.align 2.byte2 fil 0x8,0x6,0x4,0x2 // Eu quero definir 2 Buffers Circulares um para IN e para Filtro. global main main: p0.l lo (in) // P0 Poionado para entrada p0.h hi (in) p1.l lo (fil) // P1 Poionado para Filtro p1.h hi (fil ) i0 p0 // Buffer Circular Para entrada b0 p0 l0 0x4 m0 0x2 // p1 4 i1 p1 // Buffer Circular Para Filtro b1 p1 l1 0x4 m1 0x2 p3 0x8 a00 a10 LSETUP (sss, eee) LC0 p3 sss: r1 I0m0 r2 I1m0 // r3 r1.l r2.l a0 r1.l r2.l, a1 r1.h r2.h -------------- gtgtgtgtgtgtgtgtgtgtgtgt r1 I0m0 // Exceção está chegando r2 I1m1 eee : a0 r1.l r2.l, a1 r1.h r2.h main. end: neste código iam recebendo uma exceção desconhecida ocorrida exceção na linha indicada. Qual é a razão pela qual eu não sei. qualquer ajuda. como pode ser que haja alguma via especial para atualizar o registrador Index ou qualquer outro Inicie um novo tópico Postado por rama raju x25CF 24 de setembro de 2008 Estou tendo uma dúvida básica. Suponha que, se temos o comprimento da derivação do filtro nh amp no. de amostras nr, então, de acordo com a operação de convolução, obtemos as saídas nrnh-1. O filtro nada mais é que convolução de amostras e filtro Você pode ver esse código de filtro, que eu tirei do documento da biblioteca DSP das TIs (spru565a pdg. no 86) xnrnh1 Ponteiro para a matriz de tamanho nr nh 1. hnh Ponteiro para coeficiente array de tamanho nh rnr Ponteiro para a matriz de saída de tamanho nr. Deve estar alinhado com a palavra. nh Número de coeficientes. Deve ser 5. nr Número de amostras para calcular. Deve ser um múltiplo de 4. void DSPfirgen (short x, short h, short r, para (j 0 jn nr j) para (i 0 i lt nh i) rj sum gtgt 15 Suponha que se configurarmos dois buffers ping-pong (enquanto o mcbsp (ou esporte) preenche um buffer, outro buffer pode ser usado para filtragem) para filtragem em tempo real, como usar esse código de filtro, enquanto desloco de um buffer para outro buffer que você precisa ter 1) elementos históricos para calcular a saída atual Considere este exemplo Suponha que o comprimento do filtro (nr) seja 50. Os números requeridos de amostras de saída são 100, então eu devo passar a matriz de entrada dos elementos (10050-1149). comprimento 149. Agora a minha pergunta é ao passar do primeiro buffer para o segundo buffer, precisamos copiar alguns elementos do primeiro buffer para o local inicial do segundo buffer (acho que precisamos copiar os últimos elementos (nr-1) do local inicial do buffer). seu segundo buffer) Nesse caso, em que local devo apontar minha entrada para filtrar, pode alguém ajudar nesse aspecto. Obrigado em Adavance Começar um novo tópico Postado por Mike Rosing x25CF 24 de setembro de 2008 Há algumas maneiras de atacar isso. Uma delas é usar um buffer circular e chamar o filtro para cada nova amostra. Para um pingue-pongue, você deseja iniciar o próximo bloco em nh1 no buffer de amostra. Observe que o número de amostras de entrada é nh nr - 1. Cada amostra de saída é proveniente de nh amostras de dados de entrada. Portanto, se você tiver um buffer circular maior que nh samples, poderá calcular uma amostra de saída com base em onde a última entrada entrou. A última entrada marca o final do buffer de amostra - portanto, você inicia nh samples antes disso e calcula o filtrar usando endereçamento circular. O bom disso é que você não precisa redefinir nenhum dos ponteiros de coeficiente, eles apenas retornam ao início. Acho que fará mais sentido se você desenhar uma imagem da memória. Então será óbvio onde o início do segundo buffer é tão bem quanto a sobreposição do segundo no primeiro. Um grande buffer circular também será útil para isso. Paciência, persistência, verdade, Dr. Mike Em Wed, 24 de setembro de 2008, rama raju escreveu: gt gt Oi, gt gt eu estou tendo uma dúvida básica. Suponha que se gt tivermos comprimento da derivação do filtro nh amp gt gt no. de amostras nr então, de acordo com a operação de convolução gt, obtemos também as saídas gt nrnh-1. O filtro nada mais é do que convolução gt de amostras e filtro kernel gt gt. gt gt gt Você pode ver este código de filtro, que eu tomei de TIs biblioteca de DSP gt gt documento (spru565a pdg. no 86) gt gt xnrnh1 Ponteiro para a matriz de entrada de tamanho gt nr nh 1. gt gt hnh Ponteiro para coeficiente array de tamanho gt nh. gt rtr Ponteiro para a matriz de saída de tamanho gt nr. Deve estar alinhado com a palavra. gt gt nh Número de coeficientes. Deve ser 5. gt gt nr Número de amostras para calcular. Deve ser um múltiplo de 4. gt gt gt void DSPfirgen (short x, short h, gt short r, gt gt int nh, int nr) gt gt int i, j, sum gt gt para (j 0 j nt j) gt gt soma 0 gt gt para (i 0 i lt nh i) gt soma xi gt rj soma gtgt 15 gt gt gt gt gt gt su Suponha que se configuramos dois buffers de ping-pong gt, (enquanto mcbsp (ou esporte) preenche um buffer, outro buffer pode ser usado para filtragem) em tempo real. como pode usar este código de filtro. gt gt Quero dizer, enquanto mudando de um buffer gt para outro buffer você precisa ter (filtro tap length -1) elementos de histórico gt para calcular a saída gt atual. gt gt Considere este exemplo. gt gt Suponha que o comprimento do filtro (nr) seja 50. gt gt Números requeridos de amostras de saída são gt 100, então devo passar a matriz de entrada de elementos (10050-1149). Então, eu posso configurar meu tamanho de buffer 149. gt gt Agora minha pergunta é enquanto mudando do primeiro buffer de gt para o segundo buffer, precisamos copiar algum número de elementos do primeiro buffer para o local de início do segundo buffer de gt. gt gt (acho que precisamos copiar os últimos elementos (nr-1) começando a localização do seu segundo buffer gt) Nesse caso, eu deveria apontar minha entrada para filtrar. Qualquer um pode ajudar nesse sentido? gt gt Obrigado em Adavance gt gt SVS Iniciar um novo tópico

Comments