Обработка

Тема в разделе "Библиотеки и интерфейсы", создана пользователем Andrei, 1 июн 2018.

  1. Andrei

    Andrei Member

    Публикаций:
    0
    Регистрация:
    13 апр 2018
    Сообщения:
    322
    На вход звуковой карты на канал R и L поступают два аудио сигнала.
    Нужно сдвинуть канал L относительно R на 90 градусов,
    Как это проще реализовать ?
    Наверное можно R сдвинуть +45, а L -45 ... , если использовать FIR фильтр как рассчитать угол сдвига ??

    [​IMG]
     
  2. Andrei

    Andrei Member

    Публикаций:
    0
    Регистрация:
    13 апр 2018
    Сообщения:
    322
    Вот полная схема ....
    [​IMG]
     
  3. Andrei

    Andrei Member

    Публикаций:
    0
    Регистрация:
    13 апр 2018
    Сообщения:
    322
    Ок, программу сделал, кой как, как получать сэмплы с звуковой карты ?? Предварительно установив частоту дискретизации 1200 Гц ???????????
     
  4. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    429
    Через WaveIn-функции, через DirectSound, через WinMM и т.д.
     
  5. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    312
    Адрес:
    Кольца Сатурна
    Andrei, доков и примеров (особенно с WinAPI и DirectSound) в инете теува хуча.
    А если попроще хочется, можно и BASS использовать или ещё какие-то библиотеки...
     
  6. Andrei

    Andrei Member

    Публикаций:
    0
    Регистрация:
    13 апр 2018
    Сообщения:
    322
    Понял пошёл искать доки
     
  7. Andrei

    Andrei Member

    Публикаций:
    0
    Регистрация:
    13 апр 2018
    Сообщения:
    322
    Пока плюнул, сделал на AVR, там хоть понятно с ADC напрямую можно читать семплы,
    все ворованное, фильтры с WinFilter, алгоритм с нета, ...., да и не факт что работает,
    отлаживать пока не получается, макетку собрать нужно ...
    ...

    Код (C++):
    1.  
    2. #include <math.h>
    3. #include <util/delay.h>
    4. #include <avr/io.h>
    5. #include <avr/interrupt.h>
    6. #define Ntap 31
    7. #define DCgain 32768
    8. #define ADC_VREF_TYPE ((1<<REFS1) | (1<<REFS0) | (0<<ADLAR)) // Внутренне опорное напряжение 2,56 Вольта
    9. #define LED_PORT PORTC
    10. #define Led_I 1
    11. #define Led_Q 2
    12. #define Led_Run 0
    13. // Глобальные переменные
    14. int OutSample,I,Q,N,X1,X2,X3,Y1,Y2,Y3;
    15. float count=0;
    16. int led_flag=0;
    17. int cos_N[4]={1,0,-1,0};
    18. int sin_N[4]={0,1,0,-1};
    19. int sin_N_m[4]={0,-1,0,1};
    20. // Читаем ADC
    21. int read_adc(unsigned char adc_input)
    22.                                              {
    23.                                               ADMUX=adc_input | ADC_VREF_TYPE;
    24.                                               // Delay needed for the stabilization of the ADC input voltage
    25.                                               _delay_us(10);
    26.                                               // Start the AD conversion
    27.                                               ADCSRA|=(1<<ADSC);
    28.                                               // Wait for the AD conversion to complete
    29.                                               while ((ADCSRA & (1<<ADIF))==0);
    30.                                               ADCSRA|=(1<<ADIF);
    31.                                               return ADCW-512; // Убираем постоянную составляющую (преобразуем однополярный сигнал в двухполярный)
    32.                                              }
    33. // Инициализация ADC
    34. void adc_init(void)
    35.                    {
    36.    DIDR0=(0<<ADC7D) | (0<<ADC6D) | (0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
    37.                    ADMUX=ADC_VREF_TYPE;
    38.                    ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
    39.                    ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
    40.                    }
    41. // Настройка генератора
    42. void clk_init(void)
    43.                    {
    44.                     CLKPR=(1<<CLKPCE);
    45.                     CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
    46.                    }
    47. // Инициализация портов
    48. void port_init(void)
    49.                    {
    50.     // Порт А на ввод ADC (подтягивающие резисторы не включены)
    51.       PORTA=0x00;
    52. DDRA=0x00;
    53. // Порт С на вывод
    54. PORTC=0x00;
    55. DDRC=0xFF;
    56. // Порт D на вывод
    57.                     PORTD=0x00;
    58.                     DDRD=0xFF;
    59.                    }
    60. // Настройки таймера 1 (Срабатывание по совпадению)
    61. void timer_init(void)
    62.                     {
    63.                      // Timer/Counter 1 initialization
    64.                      // Clock source: System Clock
    65.                      // Clock value: 312,500 kHz
    66.                      // Mode: Normal top=0xFFFF
    67.                      // OC1A output: Disconnected
    68.                      // OC1B output: Disconnected
    69.                      // Noise Canceler: Off
    70.                      // Input Capture on Falling Edge
    71.                      // Timer Period: 0,20972 s
    72.                      // Timer1 Overflow Interrupt: Off
    73.                      // Input Capture Interrupt: Off
    74.                      // Compare A Match Interrupt: On
    75.                      // Compare B Match Interrupt: Off
    76.                      TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
    77.                      TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (1<<CS11) | (1<<CS10);
    78.                      TCNT1H=0x00;
    79.                      TCNT1L=0x00;
    80.                      ICR1H=0x00;
    81.                      ICR1L=0x00;
    82.                      OCR1AH=0x01;
    83.                      OCR1AL=0x77;
    84.                      OCR1BH=0x00;
    85.                      OCR1BL=0x00;
    86. // Включение прерываний по таймеру
    87. TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (1<<OCIE1A) | (0<<TOIE1);
    88. }
    89. // Фильтр канала I
    90. int  fir_I(int NewSample) {
    91.     int FIRCoef[Ntap] = {
    92.          -406,
    93.          -207,
    94.           529,
    95.           240,
    96.          -698,
    97.          -274,
    98.           942,
    99.           308,
    100.         -1317,
    101.          -338,
    102.          1972,
    103.           363,
    104.         -3441,
    105.          -379,
    106.         10572,
    107.         17042,
    108.         10572,
    109.          -379,
    110.         -3441,
    111.           363,
    112.          1972,
    113.          -338,
    114.         -1317,
    115.           308,
    116.           942,
    117.          -274,
    118.          -698,
    119.           240,
    120.           529,
    121.          -207,
    122.          -406
    123.     };
    124.     static int x[Ntap]; //input samples
    125.     long int y=0;            //output sample
    126.     int n;
    127.     //shift the old samples
    128.     for(n=Ntap-1; n>0; n--)
    129.        x[n] = x[n-1];
    130.     //Calculate the new output
    131.     x[0] = NewSample;
    132.     for(n=0; n<Ntap; n++)
    133.         y += FIRCoef[n] * x[n];
    134.  
    135.     return y / DCgain;
    136.  
    137. }
    138. // Фильтр канала Q
    139. int  fir_Q(int NewSample) {
    140.     int FIRCoef[Ntap] = {
    141.          -406,
    142.          -207,
    143.           529,
    144.           240,
    145.          -698,
    146.          -274,
    147.           942,
    148.           308,
    149.         -1317,
    150.          -338,
    151.          1972,
    152.           363,
    153.         -3441,
    154.          -379,
    155.         10572,
    156.         17042,
    157.         10572,
    158.          -379,
    159.         -3441,
    160.           363,
    161.          1972,
    162.          -338,
    163.         -1317,
    164.           308,
    165.           942,
    166.          -274,
    167.          -698,
    168.           240,
    169.           529,
    170.          -207,
    171.          -406
    172.     };
    173.     static int x[Ntap];      //input samples
    174.     long int y=0;            //output sample
    175.     int n;
    176.     //shift the old samples
    177.     for(n=Ntap-1; n>0; n--)
    178.        x[n] = x[n-1];
    179.     //Calculate the new output
    180.     x[0] = NewSample;
    181.     for(n=0; n<Ntap; n++)
    182.         y += FIRCoef[n] * x[n];
    183.  
    184.     return y / DCgain;
    185.  
    186. }
    187. // Обработчик прерывания по таймеру 1200 Гц
    188. ISR (TIMER1_COMPA_vect)
    189. {
    190.  if (N==3)
    191.          {
    192. N=0;
    193. }
    194.          else N++;
    195. I=read_adc(0);
    196. Q=read_adc(1);
    197. X1=I*cos_N[N]+Q*sin_N[N];
    198. X2=fir_I(X1);
    199. X3=X2*cos_N[N];
    200. Y1=I*sin_N_m[N]+Q*cos_N[N];
    201. Y2=fir_Q(Y1);
    202. Y3=Y2*sin_N_m[N];
    203. OutSample=X3+Y3;
    204. PORTD=OutSample+512;// восстанавливаем однополярный сигнал
    205. }
    206. int  main (void)
    207. {
    208.  //Инициализация ADC
    209.  adc_init();
    210.  //Инициализация генератора
    211.  clk_init();
    212.  // Инициализация портов
    213.  port_init();
    214.  // Инициализация таймера
    215.  timer_init();
    216.  // Разрешение прерываний
    217.  sei();
    218.  while(1)
    219.  {
    220.   // Led_Run индикатор просчета фильтров
    221.   if (count==1000)
    222.                   {
    223.   led_flag=1;
    224.   }
    225.   else
    226.        {
    227.    count++;
    228.    }
    229.   if (led_flag==1)
    230.                   {
    231.   LED_PORT |= 1 << Led_Run; //зажечь
    232.   led_flag=0;
    233.   count=0;
    234.   }
    235.   else
    236.       {
    237.                        LED_PORT &= ~(1 << Led_I);// Гасим
    238.               }
    239.   if (I==0)
    240.            {
    241.             // Зажигаем диод I
    242. LED_PORT |= 1 << Led_I; //зажечь
    243.            }
    244.             else
    245.     {
    246. // Гасим диод I
    247. LED_PORT &= ~(1 << Led_I);// Гасим
    248. }
    249.   if (Q==0)
    250.            {
    251.             // Зажигаем диод Q
    252. LED_PORT |= 1 << Led_Q; //зажечь
    253.            }
    254.             else
    255.     {
    256. // Гасим диод Q
    257. LED_PORT &= ~(1 << Led_I);// Гасим
    258. }
    259.                        
    260.  
    261.  }
    262. }
    263.