alsa录音数据转化成DB值算法

#include "tcp.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include <math.h>
#include "sys/stat.h"
#include "fcntl.h"
#include "sys/ioctl.h"
#include "signal.h"
#include "sys/select.h"
#include "poll.h"

void thread_func(void *s)
{
    long loops;
    int rc;
    int size;
    snd_pcm_t *handle;
    snd_pcm_hw_params_t *params;
    unsigned int val;
    int dir;
    snd_pcm_uframes_t frames;
    char *buffer;
    
    /* Open PCM device for playback. */
    rc = snd_pcm_open(&handle, "hw:1,0",
                        SND_PCM_STREAM_CAPTURE, 0);
    if (rc < 0)
    {
        fprintf(stderr,"unable to open pcm device: %s
",snd_strerror(rc));
        exit(1);
    }
    
    /* Allocate a hardware parameters object. */
    snd_pcm_hw_params_alloca(&params);
    
    /* Fill it in with default values. */
    snd_pcm_hw_params_any(handle, params);
    
    /* Set the desired hardware parameters. */
    
    /* Interleaved mode */
    snd_pcm_hw_params_set_access(handle, params,
                        SND_PCM_ACCESS_RW_INTERLEAVED);
    
    /* Signed 16-bit little-endian format */
    snd_pcm_hw_params_set_format(handle, params,
                                SND_PCM_FORMAT_S16_LE);
    
    /* Two channels (stereo) */
    snd_pcm_hw_params_set_channels(handle, params, 4);
    
    /* 44100 bits/second sampling rate (CD quality) */
    val = 44100;
    snd_pcm_hw_params_set_rate_near(handle, params,
                                    &val, &dir);
    
    
    /* Set period size to 32 frames. */
    frames = 1024;
    snd_pcm_hw_params_set_period_size_near(handle,
                                params, &frames, &dir);
    
    /* Write the parameters to the driver */
    rc = snd_pcm_hw_params(handle, params);
    if (rc < 0) {
        fprintf(stderr,
                "unable to set hw parameters: %s
",
                snd_strerror(rc));
        exit(1);
    }
    
    /* Use a buffer large enough to hold one period */
    snd_pcm_hw_params_get_period_size(params, &frames,
                                        &dir);
    size = frames * 8; /* 2 bytes/sample, 2 channels */
    buffer = (char *) malloc(size);
    
    /* We want to loop for 5 seconds */
    snd_pcm_hw_params_get_period_time(params,&val, &dir);
    /* 5 seconds in microseconds divided by
    * period time */
    loops = 3000000 / val;

    while (Mic_test) //循环录音 5 s  
    {
        loops--;
        rc = snd_pcm_readi(handle, buffer, frames);
        if (rc == 0) //没有读取到数据 
        {
            fprintf(stderr, "end of file on input
");
            break;
        } 
        else if (rc != size)//实际读取 的数据 小于 要读取的数据 
        {
        //fprintf(stderr,"short read: read %d bytes
", rc);
        }
        TransformData(buffer,32);
    }
    snd_pcm_drain(handle);
    snd_pcm_close(handle);
    free(buffer);
}


int TransformData(char *input_buffer, int frames)
{
    char msg[1024] ;
    int couns;
    //4 channels
    double doub_ch0 = 0.f;
    double doub_ch1 = 0.f;
    double doub_ch2 = 0.f;
    double doub_ch3 = 0.f;

    short short_ch0 = 0;
    short short_ch1 = 0;
    short short_ch2 = 0;
    short short_ch3 = 0;

    double sum0 = 0.f;
    double sum1 = 0.f;
    double sum2 = 0.f;
    double sum3 = 0.f;
    couns++;
    if(couns > 6){
        float f_2_15 = powf(2, 15);

        // 2 bytes -- PCM_FORMAT_S16_LE
        for(int i=0; i<frames * (DEVICES_MIC_CHS * 2); i=i + (DEVICES_MIC_CHS * 2) ){

                // pcm reconstruction, little endian
                short_ch0 = ( *(input_buffer + i + 1) <<8 | *(input_buffer + i + 0) );
                short_ch1 = ( *(input_buffer + i + 3) <<8 | *(input_buffer + i + 2) );
                short_ch2 = ( *(input_buffer + i + 5) <<8 | *(input_buffer + i + 4) );
                short_ch3 = ( *(input_buffer + i + 7) <<8 | *(input_buffer + i + 6) );

                doub_ch0 = short_ch0 / f_2_15;
                doub_ch1 = short_ch1 / f_2_15;
                doub_ch2 = short_ch2 / f_2_15;
                doub_ch3 = short_ch3 / f_2_15;

                sum0 += doub_ch0 * doub_ch0;
                sum1 += doub_ch1 * doub_ch1;
                sum2 += doub_ch2 * doub_ch2;
                sum3 += doub_ch3 * doub_ch3;
        }
        //printf(" ---- dB ---- ch0:%d  ch1:%d  ch2:%d  ch3:%d  
", short_ch0, short_ch1, short_ch2, short_ch3 );
        doub_ch0 = sqrt(sum0 / frames); doub_ch0 = 20 * log10(doub_ch0);
        doub_ch1 = sqrt(sum1 / frames); doub_ch1 = 20 * log10(doub_ch1);
        doub_ch2 = sqrt(sum2 / frames); doub_ch2 = 20 * log10(doub_ch2);
        doub_ch3 = sqrt(sum3 / frames); doub_ch3 = 20 * log10(doub_ch3);
        
        sprintf(msg,"ch0:%.1f  ch1:%.1f  ch2:%.1f  ch3:%.1f  
", doub_ch0, doub_ch1, doub_ch2, doub_ch3);
        //printf(" msg = [%d]-- 
",strlen(msg));
        write(connfd, msg, strlen(msg));
        printf(" msg = [%s]-- 
",msg);
        couns = 0;
    }
    return 0;
}
#include <string>
#include <vector>
#include "linux/input.h"
#include <iostream>


#define ALSA_PCM_NEW_HW_PARAMS_API
#include <time.h>
#include <alsa/asoundlib.h>
#define DEVICES_MIC_CHS 4

//#define _GLIBCXX_USE_CXX11_ABI 0
using namespace std;

enum EventType {
    ledLightOut = 0x00,
    ledWhiteOut ,
    LedRedLight ,
    LedGreenLight,
    LedBlueLight ,
    LedWaterLamp
};

#define MAXLINE 4096
#define BUFFSIZE 9600       // 48K / 20 * 4
#define BUFFSIZE_MIC 3200
#define X 17
#define Y 21
#define ROW 21

static int Volumecount;
static int lightecount;
static bool Mic_test = false; 
static vector<string> shell_answer;
static std::vector<std::string> get_info;
static std::vector<std::string> get_info_2;
static std::vector<std::string> get_wifi_ip;
static struct input_event inputevent;
static int cycle = 1, mic_begin = 0, no_write = 0;
static int check_sta_to_end =0, enter_fact=0;
static int led_row = 0;
static int Led_len = 0;
static void Led_switch();


string array;
const char *abc;
char *str_return;
char VERSION[100];
char ss[4096];
int connfd;

编译时参考之前个人项目使用指令 g++ -o tcp tcp.cpp tcp.h -lasound -lpthread -lm