main.cpp 4.1 KB
#include "blc_channel.h"
#include "blc_program.h"
#include <unistd.h> //getpid
#include <sys/time.h>

int main(int argc, char **argv){
    blc_array array;
    blc_channel input_channel, output_channel;
    char const  *output_channel_name, *input_channel_name, *delay_str, *period_str, *gain_str;
    float gain;
    int64_t period, delay;
    int delay_iterations, iteration, i;
    
    blc_program_set_description("Copy the input signla in the output modifying it (delay, gain, ...)");
    blc_program_add_option(&delay_str, 'd', "delay", "integer", "delay applying to the input signal in ms", NULL);
    blc_program_add_option(&gain_str, 'g', "gain", "float", "gain to which the signal will be multiply", NULL);
    blc_program_add_option(&period_str, 'p', "period", "integer", "sampling period in ms", "10");
    blc_program_add_option(&output_channel_name, 'o', "output", "blc_channel", "name of the output channel", NULL);
    blc_program_add_parameter(&input_channel_name, "blc_channel", 1, "Input channel", NULL);
    blc_program_init(&argc, &argv, NULL);
    
    if (output_channel_name==NULL) SYSTEM_ERROR_CHECK(asprintf((char**)&output_channel_name, "/%s%d", blc_program_name, getpid()), -1, NULL); //This will not be free
    
    input_channel.open(input_channel_name, BLC_CHANNEL_READ);
    
    period=strtod(period_str, NULL)*1000;
    
    if (delay_str){
        delay=strtod(delay_str, NULL)*1000;
        delay_iterations=delay/period;
        if (delay<=period) EXIT_ON_ERROR("Delay (%dms) cannot be shorter than the sampling period (%dms)", delay/1000, period/1000);
        //We create a table capable of saving all intermediate iterations
        array.init('UIN8', 'NDEF', 2, input_channel.size, delay_iterations);
    }
    else delay=0;
    
    if (gain_str) {
        gain=strtof(gain_str, NULL);
    }
    else gain=1.0f;
    
    output_channel.create_or_open(output_channel_name, BLC_CHANNEL_WRITE, input_channel.type, input_channel.format, input_channel.dims_nb, input_channel.dims);
    output_channel.publish();
    
    iteration=0;
    BLC_COMMAND_LOOP(period){
        if (delay){
            if (gain_str){
                switch (input_channel.type){
                    case 'UIN8':
                        FOR(i, input_channel.total_length){
                            array.uchars[array.dims[array.dims_nb-1].step*iteration+i]=CLIP_UCHAR(input_channel.uchars[i]*gain);
                        }
                        break;
                    case 'FL32':
                        FOR(i, input_channel.total_length){
                            array.floats[array.dims[array.dims_nb-1].step*iteration+i]=input_channel.floats[i]*gain;
                        }
                        break;
                    default:
                        EXIT_ON_ARRAY_ERROR(&input_channel, "You can only apply gain on type 'UIN8' or 'FL32'");
                        break;
                }
            }else memcpy(array.uchars+array.dims[array.dims_nb-1].step*iteration, input_channel.data, input_channel.size);
            
            iteration++;
            if (iteration==delay_iterations) iteration=0;
            
            memcpy(output_channel.data, array.uchars+array.dims[array.dims_nb-1].step*iteration, output_channel.size);
        }
        else {
            if (gain_str){
                switch (input_channel.type){
                    case 'UIN8':
                        FOR(i, input_channel.total_length){
                            output_channel.uchars[i]=CLIP_UCHAR(input_channel.uchars[i]*gain);
                        }
                        break;
                    case 'FL32':
                        FOR(i, input_channel.total_length){
                            output_channel.floats[i]=input_channel.floats[i]*gain;
                        }
                        break;
                    default:
                        EXIT_ON_ARRAY_ERROR(&input_channel, "You can only apply gain on type 'UIN8' or 'FL32'");
                        break;
                }
            }
            else memcpy(output_channel.data, input_channel.data, input_channel.size);
        }
    }
    
    return EXIT_SUCCESS;
}