Действительно получается простой вольтметр. По анализатору спектра нашел преобразование фурье.
Делаем 5 замеров ацп в переменные Y1 - Y5, вычисляемY0
Y0 = (Y1+Y5+2*(Y2+Y4))/6 ,получается среднее значение сигнала
вычисляем гармоники сигнала:
M1 = (Y1 - Y5 + Y2 - Y4) / 3
M2 = (Y1 + Y5 - 2 * Y3) / 4
M3 = (Y1 - Y5 - 2 * (Y2-Y4)) / 6
M4 = ((Y1 + Y5) - 4 * (Y2 + Y4) + 6 * Y3) / 12
Где м1 - м4 амплитуды 1й - 4й гармоник сигнала. Можно вычислить из этого и коэффициент гармоник, но АВРу будет уже сложно K=(SQR((M2в степени 2)+(m3в квадрате)+(м4 в квадрате)))/м1 где К - коэффициент гармоник.
А вот что делать с этими циферками я не понял ))
Цветомузыка на AVR
- Engineer_Keen
- Друг Кота
- Сообщения: 3868
- Зарегистрирован: Пт янв 29, 2010 10:27:40
- Откуда: Москва
Re: Цветомузыка на AVR
KyJek писал(а):А вот что делать с этими циферками я не понял ))
Если вы про M1-M4, то выводить их через ШИМ на светодиоды, вот и получится анализатор спектра на 4 диапазона. Формулы кстати вы нашли довольно простые, их можно будет оптимизировать так, что даже тинька без аппаратного умножения/деления справится.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
-
KyJek
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт апр 07, 2015 19:19:29
- Откуда: г. Москва
Re: Цветомузыка на AVR
Что значит простые формулы?
. Формула либо верная, либо не верная. Что я теряю применяя данные формулы и что я получу если формулы будут более сложные ? И для чего нужен коэффициент гармоник ?
- Engineer_Keen
- Друг Кота
- Сообщения: 3868
- Зарегистрирован: Пт янв 29, 2010 10:27:40
- Откуда: Москва
Re: Цветомузыка на AVR
KyJek писал(а):Что значит простые формулы?![]()
![]()
. Формула либо верная, либо не верная.
БПФ в общем виде выглядит сложнее, а тут уже все приведено к простому алгоритму.
KyJek писал(а):И для чего нужен коэффициент гармоник ?
Для цветомузыки он точно не нужен
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Цветомузыка на AVR
интересно, откуда такие формулы выплыли...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
-
KyJek
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт апр 07, 2015 19:19:29
- Откуда: г. Москва
Re: Цветомузыка на AVR
Формулы я взял отсюда. http://bascom.at.ua/publ/cvetomuzyka_qu ... t/1-1-0-20
Не знаю, насколько они правильные, но если есть другие предложения, я с радостью поковыряюсь!
Формулы, думаю да могут быть сложнее, возможно не 4 гармоники а больше и количество замеров не 5. Думаю, я проиграю в точности, но пока это не будет так принципиально.
Не знаю, насколько они правильные, но если есть другие предложения, я с радостью поковыряюсь!
Формулы, думаю да могут быть сложнее, возможно не 4 гармоники а больше и количество замеров не 5. Думаю, я проиграю в точности, но пока это не будет так принципиально.
-
KyJek
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт апр 07, 2015 19:19:29
- Откуда: г. Москва
Re: Цветомузыка на AVR
Так же я нашел довольно понятный и интересный пример кода БПФ.
main
fft
Правда код для пик, но думаю саму вычислительную часть можно взять отсюда. не очень понимаю как получить не 32 гармоники, а 4 уменьшить количество замеров до 8?
main
Спойлер
Код: Выделить всё
/************************************************************************
main.c
FFT Audio Analysis
Copyright (C) 2011 Simon Inns
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Email: simon.inns@gmail.com
************************************************************************/
#ifndef MAIN_C
#define MAIN_C
// Global includes
#include <htc.h>
#include <stdio.h>
// Local includes
#include "hardware.h"
#include "fft.h"
#include "graph.h"
// PIC18F4550/PIC18F2550 fuse configuration:
// Config word 1 (Oscillator configuration)
// 20Mhz crystal input scaled to 48Mhz and configured for USB operation
__CONFIG(1, USBPLL & IESODIS & FCMDIS & HSPLL & CPUDIV1 & PLLDIV5);
// Config word 2
__CONFIG(2, VREGEN & PWRTDIS & BORDIS & BORV20 & WDTDIS & WDTPS32K);
// Config word 3
__CONFIG(3, PBDIGITAL & LPT1DIS & MCLREN);
// Config word 4
__CONFIG(4, XINSTDIS & STVREN & LVPDIS & ICPORTDIS & DEBUGDIS);
// Config word 5, 6 and 7 (protection configuration)
__CONFIG(5, UNPROTECT);
__CONFIG(6, UNPROTECT);
__CONFIG(7, UNPROTECT);
// Globals
short imaginaryNumbers[64];
short realNumbers[64];
void main(void)
{
// PIC port set up ----------
// Configure on-board ADC
// Vss and Vdd as voltage references
ADCON1 = 0b00001110;
// Configure the ADC acquisition time according to the datasheet
ADCON2 = 0b10110110; // Note: output is right justified
// Configure ports as inputs (1) or outputs(0)
// 76543210
TRISA = 0b00000001;
TRISB = 0b00000000;
TRISC = 0b00000011;
TRISD = 0b00000000;
TRISE = 0b00000000;
// Clear all ports
// 76543210
PORTA = 0b00000000;
PORTB = 0b00000000;
PORTC = 0b00000000;
PORTD = 0b00000000;
PORTE = 0b00000000;
RE0 = 0;
RE1 = 0;
RE2 = 0;
// Initialise the gLCD
gLcdInit();
gLcdClear();
while(1)
{
// Perform the FFT
// Get 64 samples at 50uS intervals
// 50uS means our sampling rate is 20KHz which gives us
// Nyquist limit of 10Khz
short i = 0;
unsigned short result;
for (i = 0; i < 64; i++)
{
// Perform the ADC conversion
// Select the desired ADC and start the conversion
ADCON0 = 0b00000011; // Start the ADC conversion on AN0
// Wait for the ADC conversion to complete
TESTPIN_W4 = 1; // Don't remove this... it will affect the sample timing
while(GODONE);
TESTPIN_W4 = 0; // Don't remove this... it will affect the sample timing
// Get the 10-bit ADC result and adjust the virtual ground of 2.5V
// back to 0Vs to make the input wave centered correctly around 0
// (i.e. -512 to +512)
realNumbers[i] = ((short)(ADRESH << 8) + (short)ADRESL) - 512;
// Set the imaginary number to zero
imaginaryNumbers[i] = 0;
// This delay is calibrated using an oscilloscope according to the
// output on RA1 to ensure that the sampling periods are correct
// given the overhead of the rest of the code and the ADC sampling
// time.
//
// If you change anything in this loop or use the professional
// (optimised) version of Hi-Tech PICC18, you will need to re-
// calibrate this to achieve an accurate sampling rate.
__delay_us(7);
}
// Perform the (forward) FFT calculation
// Note: the FFT result length is half of the input data length
// so if we put 64 samples in we get 32 buckets out. The first bucket
// cannot be used so in reality our result is 31 buckets.
//
// The maximum frequency we can measure is half of the sampling rate
// so if we sample at 20Khz our maximum is 10Khz (this is called the
// Nyquist frequency). So if we have 32 buckets divided over 10Khz,
// each bucket represents 312.5Khz of range, so our lowest bucket is
// (bucket 1) 312.5Hz - 625Hz and so on up to our 32nd bucket which
// is 9687.5Hz - 10,000Hz
// 1 : 312.5 - 625
// 2 : 625 - 937.5
// 3 : 937.5 - 1250
// 4 : 1250 - 1562.5
// 5 : 1562.5 - 1875
// 6 : 1875 - 2187.5
// 7 : 2187.5 - 2500
// 8 : 2500 - 2812.5
// 9 : 2812.5 - 3125
// 10 : 3125 - 3437.5
// 11 : 3437.5 - 3750
// 12 : 3750 - 4062.5
// 13 : 4062.5 - 4375
// 14 : 4375 - 4687.5
// 15 : 4687.5 - 5000
// 16 : 5000 - 5312.5
// 17 : 5312.5 - 5625
// 18 : 5625 - 5937.5
// 19 : 5937.5 - 6250
// 20 : 6250 - 6562.5
// 21 : 6562.5 - 6875
// 22 : 6875 - 7187.5
// 23 : 7187.5 - 7500
// 24 : 7500 - 7812.5
// 25 : 7812.5 - 8125
// 26 : 8125 - 8437.5
// 27 : 8437.5 - 8750
// 28 : 8750 - 9062.5
// 29 : 9062.5 - 9375
// 30 : 9375 - 9687.5
// 31 : 9687.5 - 10000
// Note: the '6' is the size of the input data (2 to the power of 6 = 64)
TESTPIN_W5 = 1;
fix_fft(realNumbers, imaginaryNumbers, 6);
// Take the absolute value of the FFT results
// Note: The FFT routine returns 'complex' numbers which consist of
// both a real and imaginary part. To find the 'absolute' value
// of the returned data we have to calculate the complex number's
// distance from zero which requires a little pythagoras and therefore
// a square-root calculation too. Since the PIC has multiplication
// hardware, only the square-root needs to be optimised.
long place, root;
for (int k=0; k < 32; k++)
{
realNumbers[k] = (realNumbers[k] * realNumbers[k] +
imaginaryNumbers[k] * imaginaryNumbers[k]);
// Now we find the square root of realNumbers[k] using a very
// fast (but compiler dependent) integer approximation:
// (adapted from: http://www.codecodex.com/wiki/Calculate_an_integer_square_root)
place = 0x40000000;
root = 0;
if (realNumbers[k] >= 0) // Ensure we don't have a negative number
{
while (place > realNumbers[k]) place = place >> 2;
while (place)
{
if (realNumbers[k] >= root + place)
{
realNumbers[k] -= root + place;
root += place * 2;
}
root = root >> 1;
place = place >> 2;
}
}
realNumbers[k] = root;
}
TESTPIN_W5 = 0;
// Now we have 32 buckets of audio frequency data represented as
// linear intensity in realNumbers[]
//
// Since the maximum input value (in theory) to the SQRT function is
// 32767, the peak output at this stage is SQRT(32767) = 181.
// Draw a bar graph of the FFT output data
TESTPIN_W6 = 1;
drawFftGraph(realNumbers);
TESTPIN_W6 = 0;
}
}
#endif
fft
Спойлер
Код: Выделить всё
/************************************************************************
fft.c
FFT Audio Analysis
Copyright (C) 2011 Simon Inns
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Email: simon.inns@gmail.com
************************************************************************/
#ifndef FFT_C
#define FFT_C
#include <htc.h>
#include "fft.h"
// fix_fft.c - Fixed-point in-place Fast Fourier Transform
// All data are fixed-point short integers, in which -32768
// to +32768 represent -1.0 to +1.0 respectively. Integer
// arithmetic is used for speed, instead of the more natural
// floating-point.
//
// For the forward FFT (time -> freq), fixed scaling is
// performed to prevent arithmetic overflow, and to map a 0dB
// sine/cosine wave (i.e. amplitude = 32767) to two -6dB freq
// coefficients.
//
// Written by: Tom Roberts 11/8/89
// Made portable: Malcolm Slaney 12/15/94 malcolm@interval.com
// Enhanced: Dimitrios P. Bouras 14 Jun 2006 dbouras@ieee.org
// Ported to PIC18F: Simon Inns 20110104
/*
fix_fft() - perform forward fast Fourier transform.
fr[n],fi[n] are real and imaginary arrays, both INPUT AND
RESULT (in-place FFT), with 0 <= n < 2**m
*/
void fix_fft(short fr[], short fi[], short m)
{
long int mr = 0, nn, i, j, l, k, istep, n, shift;
short qr, qi, tr, ti, wr, wi;
n = 1 << m;
nn = n - 1;
/* max FFT size = N_WAVE */
//if (n > N_WAVE) return -1;
/* decimation in time - re-order data */
for (m=1; m<=nn; ++m)
{
l = n;
do
{
l >>= 1;
} while (mr+l > nn);
mr = (mr & (l-1)) + l;
if (mr <= m) continue;
tr = fr[m];
fr[m] = fr[mr];
fr[mr] = tr;
ti = fi[m];
fi[m] = fi[mr];
fi[mr] = ti;
}
l = 1;
k = LOG2_N_WAVE-1;
while (l < n)
{
/*
fixed scaling, for proper normalization --
there will be log2(n) passes, so this results
in an overall factor of 1/n, distributed to
maximize arithmetic accuracy.
It may not be obvious, but the shift will be
performed on each data point exactly once,
during this pass.
*/
// Variables for multiplication code
long int c;
short b;
istep = l << 1;
for (m=0; m<l; ++m)
{
j = m << k;
/* 0 <= j < N_WAVE/2 */
wr = Sinewave[j+N_WAVE/4];
wi = -Sinewave[j];
wr >>= 1;
wi >>= 1;
for (i=m; i<n; i+=istep)
{
j = i + l;
// Here I unrolled the multiplications to prevent overhead
// for procedural calls (we don't need to be clever about
// the actual multiplications since the pic has an onboard
// 8x8 multiplier in the ALU):
// tr = FIX_MPY(wr,fr[j]) - FIX_MPY(wi,fi[j]);
c = ((long int)wr * (long int)fr[j]);
c = c >> 14;
b = c & 0x01;
tr = (c >> 1) + b;
c = ((long int)wi * (long int)fi[j]);
c = c >> 14;
b = c & 0x01;
tr = tr - ((c >> 1) + b);
// ti = FIX_MPY(wr,fi[j]) + FIX_MPY(wi,fr[j]);
c = ((long int)wr * (long int)fi[j]);
c = c >> 14;
b = c & 0x01;
ti = (c >> 1) + b;
c = ((long int)wi * (long int)fr[j]);
c = c >> 14;
b = c & 0x01;
ti = ti + ((c >> 1) + b);
qr = fr[i];
qi = fi[i];
qr >>= 1;
qi >>= 1;
fr[j] = qr - tr;
fi[j] = qi - ti;
fr[i] = qr + tr;
fi[i] = qi + ti;
}
}
--k;
l = istep;
}
}
#endif
Правда код для пик, но думаю саму вычислительную часть можно взять отсюда. не очень понимаю как получить не 32 гармоники, а 4 уменьшить количество замеров до 8?
Re: Цветомузыка на AVR
Здравствуйте!
Разбираюсь с БПФ и работой ЦМУ. До этого с ЦМУ дела не имел.
Какие вообще требования предъявляются к аналоговой части нормальной ЦМУ? Кто-то говорит, что достаточно полосы частот до 8 кГц. Так ли это или лучше сделать более широкую полосу?
Нашел пример на Мега8: http://lightportal.at.ua/publ/cvetomuzy ... 1/3-1-0-18
Не могу понять, как это работает без антиалиасингового фильтра?
Звук заводить хочу через микрофон чтобы небыло никаких проводов. Какие минусы у данного решения и реально ли так сделать нормальную ЦМУ? Или может через Блютуз?
Хочу сделать ЦМУ на 4 канала (светодиоды красного, желтого, зеленого и синего цвета). Как лучше разбить по частотам?
Как лучше выделять полосы - с помощью БПФ или же цифровыми фильтрами? Много видел споров на эту тему, но так и не нашел четкого ответа. Сам пока до конца не разобрался в алгоритмических тонкостях реализации БПФ и фильтров. Что быстрее - считать БПФ сразу для всего или же считать 4 шт фильтра? Также, какая дополнительная информация из спектра используется в разных эффектах? Т. е. для 4-х канальной ЦМУ достаточно ли только 4-х частотных полос или же надо иметь дополнительные частоты?
Разбираюсь с БПФ и работой ЦМУ. До этого с ЦМУ дела не имел.
Какие вообще требования предъявляются к аналоговой части нормальной ЦМУ? Кто-то говорит, что достаточно полосы частот до 8 кГц. Так ли это или лучше сделать более широкую полосу?
Нашел пример на Мега8: http://lightportal.at.ua/publ/cvetomuzy ... 1/3-1-0-18
Не могу понять, как это работает без антиалиасингового фильтра?
Звук заводить хочу через микрофон чтобы небыло никаких проводов. Какие минусы у данного решения и реально ли так сделать нормальную ЦМУ? Или может через Блютуз?
Хочу сделать ЦМУ на 4 канала (светодиоды красного, желтого, зеленого и синего цвета). Как лучше разбить по частотам?
Как лучше выделять полосы - с помощью БПФ или же цифровыми фильтрами? Много видел споров на эту тему, но так и не нашел четкого ответа. Сам пока до конца не разобрался в алгоритмических тонкостях реализации БПФ и фильтров. Что быстрее - считать БПФ сразу для всего или же считать 4 шт фильтра? Также, какая дополнительная информация из спектра используется в разных эффектах? Т. е. для 4-х канальной ЦМУ достаточно ли только 4-х частотных полос или же надо иметь дополнительные частоты?