Ultrasonic Audio File Player
Dependencies: mbed
Fork of TAU_ZOOLOG_Chirp_Generator by
main_filter3.cpp
- Committer:
- Arkadi
- Date:
- 2017-08-06
- Revision:
- 12:e2b4a11ebe5a
- Parent:
- 9:6d4136d9c074
- Child:
- 13:24d8512fc722
File content as of revision 12:e2b4a11ebe5a:
/* General Biquadratic Digital Filter Implementation ADC --> Filter --> DAC , Based on NUCLEO - F303RE Pinout: ADC -- PA_0 -- A0 DAC -- PA_4 -- A2 I/O -- PA_5 -- D13 (Status LED, Condition) I/O -- PA_6 -- D12 (Toggle Pin, Loop Freq) I/O -- PA_7 -- D11 (General Output Pin ) Make sure to use float variables in filter (Not double!). */ #include "mbed.h" #include "config.h" #include "sounddata.h" #define TEST_OUTPUT_MODE 5 // mbed variables, Settings AnalogIn in(A0); AnalogOut out(PA_4); // digital pins DigitalOut led(LED1); DigitalOut outPulse(PA_6); // pulse output on tr connector DigitalOut mytoggle(PA_7); // User Button as interrupt InterruptIn mybutton(USER_BUTTON); // Serial over USB as input device Serial pc(SERIAL_TX, SERIAL_RX); // ADC/DAC declarations ADC_HandleTypeDef hadc1; DAC_HandleTypeDef hdac1; // Dac Register for direct method of setting DAC value`s __IO uint32_t Dac_Reg = 0; // Variables uint16_t ADCValueIn=0; uint16_t ADCValueOut=0; float ADCFloat=0; float ADCFloatFiltered=0; float OutputADCFloat=0; float ADC2Float=(2.0f/4095.0f); //ADCvalue*(2/0xFFF)-1.0f // 12 bits range float Float2ADC=(4095.0f/2.0f); //(ADCvalue+1.0f)*(0xFFF/2) // 12 bits range // float ADC2Float= 1.0; // float Float2ADC= 1.0; uint16_t ADCValueMax = 0; uint16_t ADCValueMin = 0xfff; // Definitions for software developer #define NUM_CYCLES_TO_CHECK_KEYBOARD_INPUT ((long)300000) // 0 - not check keyboard input #define SAMPLING_FREQUENCY_DELAY 2 // microseconds #define CONSTANT_SIGNAL_LEVEL_FOR_TEST 0.2 #define NUM_OF_CYCLES_BACK_TO_NORMAL 0 // User can play with this. Hysteresis, 0 - no hysteresis // global variables float scale_for_predefined_output = (float)SCALE_FOR_PREDEFINED_OUTPUT; int sampling_frequency_delay = SAMPLING_FREQUENCY_DELAY; int delay_after_signal_transmission = DELAY_AFTER_SIGNAL_TRANSMISSION; bool use_filter_with_predefined_output = USE_FILTER_WITH_PREDEFINED_OUTPUT; int num_of_cycles_to_detect_threshold_crossing = NUM_OF_CYCLES_TO_DETECT_THRESHOLD_CROSSING; int startPredefinedOutput = 0; int num_threshold_crossing = 0; int num_back_to_normal = 0; int signal_low_threshold = SIGNAL_LOW_THRESHOD; int UserButtonPressed; long NumCycles; // second-order sections filter variables - upto 8 sections #define MAX_SECTION_NUMBER 8 int NumSections = sizeof(SOSMat)/sizeof(float)/6; int NumSectionsHP = sizeof(SOSMatHP)/sizeof(float)/6; // Inputs float CurrInput [MAX_SECTION_NUMBER+1]; float LastInput [MAX_SECTION_NUMBER+1]; float LLastInput [MAX_SECTION_NUMBER+1]; float scaled_sounddata[AMOUNT_OF_SIGNIFICANT_SAMPLES]; char FilterType[5][32]; int LoopCount = 0; // trigger_pass variables float triggThresholdValue=TRIGGER_THRESHOLD_VALUE; // number of samples to count float sample_length=SAMPLE_LENGTH*(SampleRate/1000.0f); // compansate number of cycles based on sample rate float quiet_length=QUIET_LENGTH*(SampleRate/1000.0f); // compansate number of cycles based on sample rate bool trigger_HPF=TRIGGER_HPF; // Filter variables // high pass variables // high pass // tau=RC=1/2pif // α := RC / (RC + dt) :=Tau/(Tau+dt) // y[0] := x[0] // y[i] := α * y[i-1] + α * (x[i] - x[i-1]) // AHPF=ALPHA float Tau=TAU_AHPF/TWOPI; // time constat of the filter, (1khz -> 0.001 second) (converted to hz from rad/sec float AHPF=Tau/(Tau+1.0f/SampleRate); float LastY=0; float CurY=0; float LastU=0; float CurU=0; // Saturation variables float saturation_threshold=SATURATION_THRESHOLD; int num_saturation_samples=NUM_SATURATION_SAMPLES; bool saturation_detection=SATURATION_DETECTION; // Saturation delay uint32_t saturation_delay=SATURATION_DELAY*OPERATION_MS; // nop operation inline void NOP() { __ASM volatile ("nop"); // one tick operation, Use to adjust frequency by slowing down the proccess } // User Button Interrupt Service Routine (ISR) void pressed() { UserButtonPressed = 0; } int checkKeyboardInput(void) { if (pc.readable()) return 0; // means has input else return 1; // means no input } #include "adc_init.h" #include "iirlpnorm_filter.h" #include "high_path_filter.h" #include "no_filter.h" #include "predefined_output.h" #include "triggered_pass.h" void print_parameters() { printf("\r\n%s Digital Filter.\r\nSTART MAIN LOOP, use mode %d, loop #%d, number of sections: %d\r\n", FilterType[UseFilterMode], UseFilterMode, LoopCount, (UseFilterMode == IIRLPNORM_FILTER_MODE) ? NumSections : NumSectionsHP); if (UseFilterMode == PREDEFINED_OUTPUT_MODE) { printf("Signal threshould: %d\r\nSignal scale: %5.2f\r\nNumber of cycles to detect threshold crossing: %d\r\nDelay after signal in microseconds: %d\r\nUse filter: %s\r\n", signal_low_threshold, scale_for_predefined_output, num_of_cycles_to_detect_threshold_crossing, delay_after_signal_transmission, use_filter_with_predefined_output ? "Y" : "N"); } } // Main procedure int main() { char command[64]; int isInputNotValid; int k; bool isSignalClipped = false; strcpy(FilterType[0], "IIRLPNORM filter"); strcpy(FilterType[1], "High Pass filter"); strcpy(FilterType[2], "No filter"); strcpy(FilterType[3], "Predefined Output"); strcpy(FilterType[4], "Test Output"); ADC1_Init(); DAC1_Init(); HAL_ADC_Start(&hadc1); HAL_DAC_Start(&hdac1, DAC_CHANNEL_1); // define Dac Register for direct method of setting DAC value`s Dac_Reg = (uint32_t) (hdac1.Instance); Dac_Reg += __HAL_DHR12R1_ALIGNEMENT(DAC_ALIGN_12B_R); // set trigger state: outPulse.write(0); typedef void(*functionPtr)(void); functionPtr FilterFunction; // Assign ISR mybutton.fall(&pressed); LoopCount++; print_parameters(); if (UseFilterMode == PREDEFINED_OUTPUT_MODE) { // Prepare scaled sound data isSignalClipped = false; for (k=0; k < AMOUNT_OF_SIGNIFICANT_SAMPLES; k++ ) { scaled_sounddata[k] = sounddata[k]* scale_for_predefined_output; if (scaled_sounddata[k] < (float)-1.0) { scaled_sounddata[k] = (float)-1.0; isSignalClipped = true; } if (scaled_sounddata[k] > (float)1.0) { scaled_sounddata[k] = (float)1.0; isSignalClipped = true; } } } // Infinite loop while(true) { switch (UseFilterMode) { case IIRLPNORM_FILTER_MODE: FilterFunction = iirlpnorm_filter; printf("Running IIRLPNORM filter\r\n"); memset(CurrInput, 0, sizeof(CurrInput)); memset(LastInput, 0, sizeof(LastInput)); memset(LLastInput, 0, sizeof(LLastInput)); break; // end of case IIRLPNORM_FILTER_MODE case HIGH_PASS_FILTER_MODE: FilterFunction = highpath_filter; printf("Running High Path filter\r\n"); memset(CurrInput, 0, sizeof(CurrInput)); memset(LastInput, 0, sizeof(LastInput)); memset(LLastInput, 0, sizeof(LLastInput)); break; // end of case HIGH_PASS_FILTER_MODE case PREDEFINED_OUTPUT_MODE: FilterFunction = predefined_output; printf("Running Predefined Output\r\n"); memset(CurrInput, 0, sizeof(CurrInput)); memset(LastInput, 0, sizeof(LastInput)); memset(LLastInput, 0, sizeof(LLastInput)); num_threshold_crossing = 0; startPredefinedOutput = 0; num_back_to_normal = 0; break; // end of case PREDEFINED_OUTPUT_MODE case NO_FILTER_MODE: FilterFunction = no_filter; printf("Running No filter\r\n"); break; // end of case NO_FILTER_MODE case TRIGGERED_OUTPUT_MODE: FilterFunction = triggered_pass; printf("Running Triggered Mode\r\n"); break; // end of case Triggered Mode case TEST_OUTPUT_MODE: FilterFunction = test_output; printf("Running test output\r\n"); break; // end of case TEST_OUTPUT_MODE default: printf("Wrong User Filter Mode"); // Default - no filter FilterFunction = no_filter; printf("No filter\r\n"); break; } // end of switch (UserFilterMode) UserButtonPressed = 1; NumCycles = 0; ADCValueMax = 0; ADCValueMin = 0xfff; // ==================================================== // Start signal processing while(UserButtonPressed) { FilterFunction(); NumCycles++; // Check keyboard input each NUM_CYCLES_TO_CHECK_KEYBOARD_INPUT cycles if((NUM_CYCLES_TO_CHECK_KEYBOARD_INPUT > 0) && (NumCycles % NUM_CYCLES_TO_CHECK_KEYBOARD_INPUT == 0)) { // printf("Check keyboard input. Cycle: %d\n", NumCycles); UserButtonPressed = checkKeyboardInput(); } } // end of while(UserButtonPressed) // End of signal processing // ==================================================== // User button pressed // Main loop working with ADC/DAC is stopped // Here should be functionality which should be done before start another loop with ADC/DAC printf("\nKeyboard key or User button pressed! Exit from main loop.\r\n"); // Init filter variables memset(CurrInput, 0, sizeof(CurrInput)); memset(LastInput, 0, sizeof(LastInput)); memset(LLastInput, 0, sizeof(LLastInput)); // Input new use mode isInputNotValid = 1; while (isInputNotValid) { printf("Please, select use mode: \r\n"); printf("%d - IIRLPNORM filter\r\n", IIRLPNORM_FILTER_MODE); printf("%d - High Pass filter\r\n", HIGH_PASS_FILTER_MODE); printf("%d - No filter\r\n", NO_FILTER_MODE); printf("%d - Predefined Output\r\n", PREDEFINED_OUTPUT_MODE); printf("%d - Triggered Mode \r\n", TRIGGERED_OUTPUT_MODE); printf("Input your choice or hit Enter to continue main loop in the same use mode: "); memset(command, 0, sizeof(command)); gets(command); // printf("Command:%s; command length:%d\n", command, strlen(command)); if (strlen(command)-2 != 0 ) { // convert characters to integer; if convertion not succeeded return 0 (i.e. IIRLPNORM_FILTER_MODE) UseFilterMode = atoi(&command[strlen(command)-2]); } if (UseFilterMode >= IIRLPNORM_FILTER_MODE && UseFilterMode <= TRIGGERED_OUTPUT_MODE) { if (UseFilterMode == PREDEFINED_OUTPUT_MODE) { printf("Enter signal amplitude threshold to start generate predefined signal (default - %d): ", SIGNAL_LOW_THRESHOD); memset(command, 0, sizeof(command)); gets(command); signal_low_threshold = atoi(command); if (signal_low_threshold == 0) { printf("\r\nWrong input - default is taken\r\n"); signal_low_threshold = SIGNAL_LOW_THRESHOD; } // not used // // isSignalClipped = true; // while (isSignalClipped) { // printf("Enter amplitude scale parameter for predefined signal (default - %5.2f): ", SCALE_FOR_PREDEFINED_OUTPUT); // memset(command, 0, sizeof(command)); // gets(command); // scale_for_predefined_output = atof(command); // if (scale_for_predefined_output == float(0.0)) { // printf("\r\nWrong input - default is taken\r\n"); // scale_for_predefined_output = SCALE_FOR_PREDEFINED_OUTPUT; // } // isSignalClipped = false; // for (k=0; k < AMOUNT_OF_SIGNIFICANT_SAMPLES; k++ ) { // scaled_sounddata[k] = sounddata[k]* scale_for_predefined_output; // if (scaled_sounddata[k] < (float)-1.0) { // scaled_sounddata[k] = (float)-1.0; // isSignalClipped = true; // } // if (scaled_sounddata[k] > (float)1.0) { // scaled_sounddata[k] = (float)1.0; // isSignalClipped = true; // } // } // if (isSignalClipped) { // printf("With amplitude scale %5.2f, signal will be clipped !!!. Select smaller scale.\r\n",scale_for_predefined_output); // } // } // end of while (isSignalClipped) printf("Enter delay after signal in microseconds (default - %d): ", DELAY_AFTER_SIGNAL_TRANSMISSION); memset(command, 0, sizeof(command)); gets(command); delay_after_signal_transmission = atoi(command); if (delay_after_signal_transmission == 0) { printf("\r\nWrong input - default is taken\r\n"); delay_after_signal_transmission = DELAY_AFTER_SIGNAL_TRANSMISSION; } // printf("Enter number of cycles to detect threshold crossing (default - %d): ", NUM_OF_CYCLES_TO_DETECT_THRESHOLD_CROSSING); // memset(command, 0, sizeof(command)); // gets(command); // num_of_cycles_to_detect_threshold_crossing = atoi(command); // if (num_of_cycles_to_detect_threshold_crossing == 0) { // printf("\r\nWrong input - default is taken\r\n"); // num_of_cycles_to_detect_threshold_crossing = NUM_OF_CYCLES_TO_DETECT_THRESHOLD_CROSSING; // } // not implemeted filter not activated // //printf("Use high pass filter with predefined output: Y/N (default - %s): ", // USE_FILTER_WITH_PREDEFINED_OUTPUT ? "Y" : "N" ); // memset(command, 0, sizeof(command)); // gets(command); // if ((command[0] == 'Y') || (command[0] == 'y')) { // use_filter_with_predefined_output = true; // } else if ((command[0] == 'N') || (command[0] == 'n')) { // use_filter_with_predefined_output = false; // } else { // use_filter_with_predefined_output = USE_FILTER_WITH_PREDEFINED_OUTPUT; // } // // if (delay_after_signal_transmission == 0) { // delay_after_signal_transmission = USE_FILTER_WITH_PREDEFINED_OUTPUT; // } // memset(command, 0, sizeof(command)); isInputNotValid = 0; } else if (UseFilterMode == TEST_OUTPUT_MODE) { isInputNotValid = 0; } else if (UseFilterMode == NO_FILTER_MODE) { isInputNotValid = 0; } else if (UseFilterMode == HIGH_PASS_FILTER_MODE) { isInputNotValid = 0; } else if (UseFilterMode == TRIGGERED_OUTPUT_MODE) { // define threshold printf("Enter signal trigger threshold (default - %f): ", TRIGGER_THRESHOLD_VALUE); memset(command, 0, sizeof(command)); gets(command); triggThresholdValue = atof(command); if (triggThresholdValue == 0) { printf("\r\nWrong input - default is taken\r\n"); triggThresholdValue = TRIGGER_THRESHOLD_VALUE; } printf("\r\nChosen - %f\r\n",triggThresholdValue); // define record time printf("Enter record time (millis) (default - %f): ", SAMPLE_LENGTH); memset(command, 0, sizeof(command)); gets(command); sample_length = atof(command)*(SampleRate/1000.0f); // compansation for number of samples if (sample_length == 0) { printf("\r\nWrong input - default is taken\r\n"); sample_length = SAMPLE_LENGTH*(SampleRate/1000.0f); } printf("\r\n Signal samples - %f\r\n",sample_length); // define silence time printf("Enter silence time (millis) (default - %f): ", QUIET_LENGTH); memset(command, 0, sizeof(command)); gets(command); quiet_length = atof(command)*(SampleRate/1000.0f); // compansation for number of samples if (quiet_length == 0) { printf("\r\nWrong input - default is taken\r\n"); quiet_length = QUIET_LENGTH*(SampleRate/1000.0f); } printf("\r\n silence samples - %f\r\n",quiet_length); // enable TRIGGER HPF printf("Enter enable trigger HPF (default - %d): ", TRIGGER_HPF); memset(command, 0, sizeof(command)); gets(command); trigger_HPF = (bool)atoi(command); printf("\r\nChosen - %d\r\n",trigger_HPF); // enable Saturation Detector printf("Enter enable Saturation Detection (default - %d): ", SATURATION_DETECTION); memset(command, 0, sizeof(command)); gets(command); saturation_detection = (bool)atoi(command); printf("\r\nChosen - %d\r\n",saturation_detection); // no point asking quations if not enabled if (saturation_detection) { // set saturation threshold printf("Enter Saturation threshold (default - %f): ", SATURATION_THRESHOLD); memset(command, 0, sizeof(command)); gets(command); saturation_threshold =atof(command); if (saturation_threshold <= 0) { printf("\r\nWrong input - default is taken\r\n"); saturation_threshold = SATURATION_THRESHOLD; } printf("\r\nChosen - %f \r\n",saturation_threshold); // set saturation sample numbers printf("Enter Saturation sample number (default - %d): ", NUM_SATURATION_SAMPLES); memset(command, 0, sizeof(command)); gets(command); num_saturation_samples =atoi(command); if (num_saturation_samples == 0) { printf("\r\nWrong input - default is taken\r\n"); num_saturation_samples = NUM_SATURATION_SAMPLES; } printf("\r\nChosen - %d\r\n",num_saturation_samples); // set saturation delay period printf("Enter Saturation delay in millis (default - %d): ", SATURATION_DELAY); memset(command, 0, sizeof(command)); gets(command); float saturation_delay_float =atof(command); if (saturation_delay_float <= 0) { printf("\r\nWrong input - default is taken\r\n"); saturation_delay_float = SATURATION_DELAY; } saturation_delay=(uint32_t)(saturation_delay_float*OPERATION_MS); printf("\r\nChosen - %f , delay in cycle number %d \r\n",saturation_delay_float,saturation_delay); } // finish parameter settings isInputNotValid = 0; } else { printf("\r\nWrong input - try again\r\n"); } } LoopCount++; print_parameters(); } // end while(True) } }