Автор Тема: Авто нотч  (Прочитано 12812 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Авто нотч
« : Октябрь 11, 2020, 09:30:28 pm »
Пока я не совсем понимаю как оно работает.


void arm_lms_norm_init_f32   (   arm_lms_norm_instance_f32 *    S ,
uint16_t    numTaps ,
float32_t *    pCoeffs ,
float32_t *    pState ,
float32_t    му ,
uint32_t    размер блока
)      
Параметры
[в]   S   указывает на экземпляр структуры фильтра LMS с плавающей запятой
[в]   numTaps   количество коэффициентов фильтра
[в]   pCoeffs   указывает на буфер коэффициентов
[в]   pState   указывает на буфер состояния
[в]   му   размер шага, который управляет обновлениями коэффициентов фильтра
[в]   размер блока   количество образцов для обработки
Возврат
никто
Детали
pCoeffs указывает на массив коэффициентов фильтра, хранящихся в обратном во времени порядке:
   {b [numTaps-1], b [numTaps-2], b [N-2], ..., b [1], b
  • }

Начальные коэффициенты фильтра служат отправной точкой для адаптивного фильтра. pStateуказывает на массив numTaps+blockSize-1выборок длины , где blockSize- количество входных выборок, обработанных каждым вызовом arm_lms_norm_f32().


void arm_lms_norm_f32   (   arm_lms_norm_instance_f32 *    S ,
const float32_t *    pSrc ,
float32_t *    pRef ,
float32_t *    pOut ,
float32_t *    pErr ,
uint32_t    размер блока
)      
Параметры
[в]   S   указывает на экземпляр структуры нормализованного фильтра LMS с плавающей запятой
[в]   pSrc   указывает на блок входных данных
[в]   pRef   указывает на блок справочных данных
[вне]   pOut   указывает на блок выходных данных
[вне]   pErr   указывает на блок данных об ошибке
[в]   размер блока   количество образцов для обработки
Да да, я знаю, у меня ничего не получится )))

Оффлайн Relayer

  • Hero Member
  • *****
  • Сообщений: 1006
  • UR5FFR
Re: Авто нотч
« Ответ #1 : Октябрь 11, 2020, 09:59:00 pm »
А что в качестве референса использовать? Шум белый?
Нет никакого референса. Рассматривайте LMS как простой линейный предсказатель невысокого порядка. Даете ему на вход синус плюс чегото там еще - он адаптируется к самому простому сигналу - синусу. Вычитаете - остается все остальное (шум, речь и тп)
В любой схеме есть как минимум одна ненужная деталь :)

Оффлайн Relayer

  • Hero Member
  • *****
  • Сообщений: 1006
  • UR5FFR
Re: Авто нотч
« Ответ #2 : Октябрь 11, 2020, 10:02:04 pm »
Вот код для LMS. Семплрейт 24к. Параметры: Order=25, Delay=20, Leakage=1E-5, AdaptationRate=0.002
Может использоваться как шумодв если FMode = fmDeNoise, но хреново и надо другие параметры. С параметрами которые я написал хорошо работает как автонотч. В случае другого семплрейт параметры возможно придется менять. order так точно можно будет уменьшить
procedure TDSPLMSFilter.ApplyFilter(bf: TBuffer);
var px: PFloat32;
    i,j,idl,sz,mask,dl: integer;
    sum,sum_sq,df: double;
begin
  dl:=Delay;
  mask:=Length(DelayLine)-1;
  df:=1-Leakage*AdaptationRate;
  bf_Write(bf);
  px:=bf_Data(bf);
  sz:=Length(taps)-1;
  idl:=idelay;
  for j:=1 to bf.Size do begin
    DelayLine[idl]:=px^;
    DelayLineSqr[idl]:=px^*px^;
    sum:=0; sum_sq:=0;
    for i:=0 to sz do begin
      sum:=sum+DelayLine[(idl+i+1+dl) and mask]*taps[i];
      sum_sq:=sum_sq+DelayLineSqr[(idl+i+1+dl) and mask];
    end;
    if FMode = fmDeNoise then begin
      px^:=sum;
      sum:=DelayLine[idl]-sum;
    end else begin
      sum:=DelayLine[idl]-sum;
      px^:=sum;
    end;
    // LMS update
    sum:=sum*AdaptationRate/(sum_sq+1E-10);
    for i:=0 to sz do
      taps[i]:=taps[i]*df+sum*DelayLine[(idl+i+1+dl) and mask];
    //
    Inc(px);
    idl:=(idl-1) and mask;
  end;
  idelay:=idl;
end;

function TDSPLMSFilter.Redesign(SampleRate: integer; var DelayLen: integer): Boolean;
begin
  taps:=nil;
  Result:=False;
  if Order > 0 then begin
    SetLength(taps,Order);
    FillChar(taps[0],Length(taps)*SizeOf(TFloat32),0);
    DelayLen:=Order+Delay+10{Gap};
    SetLength(DelayLineSqr,RoundToPower2(DelayLen)*2);
    FillChar(DelayLineSqr[0],Length(DelayLineSqr)*SizeOf(TFloat32),0);
    Result:=True;
  end;
end;
« Последнее редактирование: Октябрь 12, 2020, 10:11:14 am от Сергей »
В любой схеме есть как минимум одна ненужная деталь :)

Оффлайн Relayer

  • Hero Member
  • *****
  • Сообщений: 1006
  • UR5FFR
Re: Авто нотч
« Ответ #3 : Октябрь 11, 2020, 10:08:02 pm »
Млин, можно как-то запретить форматирование? Этож ппц какой-то - съедает квадратные скобки с индексами. Что за форумный движок такой кривой?!?!?
В любой схеме есть как минимум одна ненужная деталь :)

Оффлайн zenit

  • Full Member
  • ***
  • Сообщений: 131
Re: Авто нотч
« Ответ #4 : Октябрь 12, 2020, 08:03:52 am »
Млин, можно как-то запретить форматирование?
Попробуйте вставлять текст как код.
вот так для примера- смайлики в игноре  :)  ;)  :D

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Авто нотч
« Ответ #5 : Октябрь 12, 2020, 09:00:39 am »
void DMA2_Stream5_IRQHandler(void) {
    /* USER CODE BEGIN DMA2_Stream5_IRQn 0 */
    //////////////////////////////////////////////////B-RX
    // saiRxBankNowNumber++;

    if ((DMA2->HISR & DMA_HISR_TCIF5) != 0) {

        uint8_t b = (uint8_t) ((hdma_sai1_b.Instance->CR & DMA_SxCR_CT) != 0);
        if (b != 0)
            saiRxBankNowNumber = 0;
        else
            saiRxBankNowNumber = 1;

        arm_fir_f32(&S_dsp, (float *) &saiRxBank[saiRxBankNowNumber], (float32_t *) pFirOutTemp, FRAME_SIZE);
        uint16_t y = 0;
        float32_t a;
        if (tim > 0)tim--;
        for (int i = 0; i < FRAME_SIZE; i++) {
            a = (pFirOutTemp[i] < 0) ? -1.0f * (pFirOutTemp[i]) : pFirOutTemp[i];
            nowAgc = 1 / a;
            if (nowAgc <= agcLevel) {
                agcLevel = nowAgc;
                tim = 2;
            } else {
                if (tim == 0) agcLevel += 0.02f;
            }
            pFirOutTemp[i] *= agcLevel;
        }


        arm_fir_f32(&S_dsp_temp, (float *) pFirOutTemp, (float32_t *) pFirOut, FRAME_SIZE);

        for (int i = 1; i < FRAME_SIZE; i += 2) {
            pOutDac[dacTxBankNawNumber][y] = (uint32_t) (2048 + pFirOut[i - 1] * 300);
            pOutDac[dacTxBankNawNumber][y] |= ((uint32_t) (2048 + pFirOut[i] * 300)) << 16;
            y++;
        }
        mayk = 2;


    }
    /* USER CODE END DMA2_Stream5_IRQn 0 */
    HAL_DMA_IRQHandler(&hdma_sai1_b);
    /* USER CODE BEGIN DMA2_Stream5_IRQn 1 */

    /* USER CODE END DMA2_Stream5_IRQn 1 */
}
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Авто нотч
« Ответ #6 : Октябрь 12, 2020, 09:02:38 am »
Спасибо Андрею за код
Спасибо Зениту за совет
 lol22
Да да, я знаю, у меня ничего не получится )))

Оффлайн Relayer

  • Hero Member
  • *****
  • Сообщений: 1006
  • UR5FFR
Re: Авто нотч
« Ответ #7 : Октябрь 12, 2020, 09:07:33 am »
Не могу поправить пост. Короче там съело taps [ i ] везде
В любой схеме есть как минимум одна ненужная деталь :)

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Авто нотч
« Ответ #8 : Октябрь 12, 2020, 01:54:33 pm »
начилась рабочая неделя.... dontt44
Да да, я знаю, у меня ничего не получится )))

Оффлайн GenaSPB

  • Jr. Member
  • **
  • Сообщений: 74
Re: Авто нотч
« Ответ #9 : Октябрь 12, 2020, 09:49:29 pm »
Посмотрел у UA3REO.
Там перед началом обработки очередного блока семплов просто проверяется на наличие НЕ ЧИСЕЛ в ранее накомленнвх коэффициентов

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Авто нотч
« Ответ #10 : Октябрь 13, 2020, 05:17:42 pm »
Ну вот, что я сделал и не заработало. НЕ удивительно, в слепую делаю, то чего не понимаю .

и так
сперва делаю ini
// arrays
__IO float32_t pOutLms[FRAME_SIZE];//out array
__IO float32_t lmsRef[FRAME_SIZE];// reference
__IO float32_t lmsErr[FRAME_SIZE];// error
 

ини и заполнение lmsRef синусом массива длиной FRAME_SIZE (1024)
LMS_FILTER_AP_NUM=40

//lms
//https://www.keil.com/pack/doc/CMSIS/DSP/html/group__LMS__NORM.html
//LMS_FILTER_AP_NUM=40
    arm_lms_norm_init_f32(&Slms, LMS_FILTER_AP_NUM, (float32_t *) firCoeff32, &firStateF32lms[0], 20, FRAME_SIZE);

    float32_t phaseRef = 0;
    float32_t pi2=2.0f * pi;
    delta =  (pi2 * 1000) / 24000;//1000Hz
    //заполнение референсного массива синусом
    for (int i = 0; i < FRAME_SIZE; i += 1) {
        lmsRef[i] = arm_sin_f32(phaseRef);
        phaseRef += delta;
        if (phaseRef >= pi2) phaseRef -=pi2;
    }


Теперь в прерывании:

....
       arm_lms_norm_f32(&Slms,(float32_t *)pFirOutTemp,(float32_t *)lmsRef,(float32_t *)pOutLms,(float32_t *)lmsErr,FRAME_SIZE);
....

Ну и на выходе фигня
« Последнее редактирование: Октябрь 13, 2020, 05:19:29 pm от ra0ahc »
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Авто нотч
« Ответ #11 : Октябрь 13, 2020, 05:45:26 pm »
arm_lms_norm_init_f32

здесь есть
-   размер шага, который управляет обновлениями коэффициентов фильтра
поставил 2 , что то там заплясало поработало сколько то и в аут улетело.

arm_lms_norm_init_f32(&Slms, LMS_FILTER_AP_NUM, (float32_t *) firCoeff32, &firStateF32lms[0], 2, FRAME_SIZE);


и еще, что делать с массивом Error?
« Последнее редактирование: Октябрь 13, 2020, 05:47:40 pm от ra0ahc »
Да да, я знаю, у меня ничего не получится )))

Оффлайн Relayer

  • Hero Member
  • *****
  • Сообщений: 1006
  • UR5FFR
Re: Авто нотч
« Ответ #12 : Октябрь 13, 2020, 05:47:46 pm »
Так надо видеть и понимать что внутри arm_lms_norm_f32 делается. Не понимаю почему вы не хотите написать код "с нуля" - там не так сложно
В любой схеме есть как минимум одна ненужная деталь :)

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Авто нотч
« Ответ #13 : Октябрь 13, 2020, 05:51:12 pm »
"с нуля" -
Потому-что не понимаю, нет опыта. Я даже на листе не смогу описать этот процесс
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Авто нотч
« Ответ #14 : Октябрь 13, 2020, 05:58:11 pm »
Геннадий как вы запустили "это"?
Да да, я знаю, у меня ничего не получится )))