【2024 VeriHealthi 芯原杯】作业题目


题目如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


第二部分参考官方的SDK开发手册,使用Event接口。
官方SDK手册中对应的内容如下:
在这里插入图片描述
在这里插入图片描述
代码如下:

// main.c

#include <stdint.h>
#include "vs_conf.h"
#include "soc_init.h"
#include "soc_sysctl.h"
#include "bsp.h"
#include "uart_printf.h"
#include "board.h"
#include "osal_task_api.h"
#include "vpi_error.h"
#include "main.h"
#include "Part1_Homework.h"
#include "vpi_event.h"

int sys_manager_handler(void *cobj, uint32_t event_id, void *param);
int sys_manager_handler(void *cobj, uint32_t event_id, void *param)
{
    uart_printf("sys_manger got value from event:%lx", *(uint32_t *)param);
    return 0;
}

static void task_sys_mgr(void *param)
{
    void *pSysManager = vpi_event_new_manager(COBJ_SYS_MGR, sys_manager_handler);

    vpi_event_register(EVENT_SYS_TEST, pSysManager);

    while (1)
    {
        vpi_event_listen(pSysManager);
        uart_printf("sys_manger is working...\r\n");
}
    
}


int custom_manager_handler(void *cobj, uint32_t event_id, void *param);
int custom_manager_handler(void *cobj, uint32_t event_id, void *param)
{

    return 0;
}

static void task_custom_mgr(void *param)
{
    uint32_t param_value = 0xa5a5;
    void *pCustomManger = vpi_event_new_manager(COBJ_CUSTOM_MGR, custom_manager_handler);
    vpi_event_register(EVENT_SYS_TEST, pCustomManger);

    while (1)
    {
        vpi_event_notify(EVENT_SYS_TEST, &param_value);
        uart_printf("custom_manger is working...");
        osal_sleep(1000);
    }
    
}



int main(void)
{
    int ret;

    ret = soc_init();
    ret = vsd_to_vpi(ret);
    if (ret != VPI_SUCCESS) {
        if (ret == VPI_ERR_LICENSE)
            uart_printf("no sdk license!");
        else
            uart_printf("soc init error");
        goto exit;
    } else {
        uart_printf("soc init done");
    }
    // print_hello_verisilicon();
    // osal_create_task(task_init_app, "init_app", 512, 1, NULL);
    void *result;
    result = osal_create_task(task_sys_mgr, "task_sys_mgr", 256, 4, NULL);
    if(result != NULL) // 检查任务创建是否成功
    {
        uart_printf("task_sys_mgr created successfully.");
    }
    osal_create_task(task_custom_mgr, "task_custom_mgr", 256, 5, NULL);

    osal_start_scheduler();

exit:
    while (1)
        ;
    return 0;
}

仿真结果:
在这里插入图片描述


第三部分

// zcr_energy.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include <string.h>
#include "zcr_energy.h"


float ste_treshold;
float zcr_treshold;

void setThreshold(int n_threshold, float **df) {
    float thres_zcr_tab[n_threshold];
    float thres_ste_tab[n_threshold];
    for (int i = 0; i < n_threshold; i++) {
        float zcr, ste;
        classifyFrame(df[i], FRAME_SIZE, NULL, &zcr, &ste);
        thres_ste_tab[i] = ste;
        thres_zcr_tab[i] = zcr;
    }

    ste_treshold = max(thres_ste_tab) * 1e1;
    zcr_treshold = min(thres_zcr_tab);
}

void classifyFrame(float *samples, int frame_size, int *classification, float *zcr, float *ste) {
    float temp = 0;
    float energy = 0;
    for (int i = 0; i < frame_size; i++) {
        temp = samples[i] * hamming_window(frame_size)[frame_size - 1 - i];
        energy += temp;
    }
    *ste = energy / frame_size;

    *zcr = sum(abs(diff(samples > 0))) / frame_size;

    if (*zcr < zcr_treshold && *ste > ste_treshold) {
        *classification = 1;
    } else if (*zcr > zcr_treshold && *ste < ste_treshold) {
        *classification = 0;
    } else {
        *classification = 2;
    }
}

void plotFrame(float *samples, int frame_size) {
    for (int i = 0; i < frame_size; i++) {
        printf("%f ", samples[i]);
    }
    printf(" ");
}

void diff(float *array, float *result, int n) {
    for (int i = 1; i < n; i++) {
        result[i - 1] = array[i] - array[i - 1];
    }
}

void hamming_window(float *window, int n) {
    for (int i = 0; i < n; i++) {
        window[i] = 0.54 - 0.46 * cos(2 * M_PI * i / (n - 1));
    }
}
int main() {
    // Load audio file
    static const float y[] = {
        /* import data */
    };

    // Normalize audio data
    float min_abs = fabs(y[0]);
    for (i = 1; i < FRAME_SIZE; i++) {
        if (fabs(y[i]) < min_abs) {
            min_abs = fabs(y[i]);
        }
    }
    for (i = 0; i < FRAME_SIZE; i++) {
        y[i] /= min_abs;
    }

    // Set frame size and duration
    int frame_size = FRAME_SIZE;
    float frame_duration = FRAME_DURATION;
    int n = FRAME_SIZE / frame_size;

    // Allocate memory for frames
    float **df = (float **)malloc(n * sizeof(float *));
    for (i = 0; i < n; i++) {
        df[i] = (float *)malloc(frame_size * sizeof(float));
    }

    // Read frames
    int temp = 0;
    for (i = 0; i < n; i++) {
        memcpy(df[i], y + temp, frame_size * sizeof(float));
        temp += frame_size;
    }

    // Set thresholds
    setThreshold((N_THRESHOLD / FRAME_DURATION), df);

    // Process frames
    for (i = 0; i < n; i++) {
        int classification;
        float zcr, ste;
        classifyFrame(df[i], frame_size, &classification, &zcr, &ste);
        printf("Frame %d: classification = %d, zcr = %f, ste = %f", i, classification, zcr, ste);
        plotFrame(df[i], frame_size);
    }

    // Free memory
    for (i = 0; i < n; i++) {
        free(df[i]);
    }
    free(df);

    return 0;
}
# zcr_energy.py

import librosa
import librosa.display
import numpy as np
import matplotlib.pyplot as plt
import math
import pandas as pd

from IPython.display import Audio
from scipy.signal.windows import hamming

filename = r'xxxxx\xxx.wav'
y, sr = librosa.load(filename, sr = 8000)


# write the data with 14 bit depth
y = np.float16(y)
y = y*pow(2,-2)

# Normalizing
def normalize(x):
    return (x-min(abs(x)))/(max(x)-min(abs(x)))

# Class

class Frame:
    
    # Thresholds init
    zcr_treshold = 0
    ste_treshold = 0


    def __init__(self, samples):

        self.frame_size = len(samples)
        self.samples = np.array(samples)
        self.classification = 0
        self.zcr = 0
        self.ste = 0
        self.classification_vector = []

        # Hamming window init for each frame
        self.hamm_window = hamming(self.frame_size)


    # Function to calculate Zero crossing rate
    def zero_crossing_rate(self):

        return sum(abs(np.diff(self.samples > 0))) / len(self.samples)
    
    # Function to calculate Short Time Energy
    def short_time_energy(self):
        temp = 0
        energy = 0
        for i, value in enumerate(self.samples):
            temp = pow(self.samples[i]*self.hamm_window[len(self.hamm_window) - 1 - i],2)
            energy += temp
        return energy / len(self.samples)
    
    
   # Function to calulate the parameters of the frame
    def calculate_frame_parameters(self):
        self.zcr = self.zero_crossing_rate()
        self.ste = self.short_time_energy()


    # Function to classify the frame as voiced/ unvoiced / DN
    def classify(self):

        self.calculate_frame_parameters()

        if self.zcr < Frame.zcr_treshold and self.ste > Frame.ste_treshold:
            self.classification = 1

        elif self.zcr > Frame.zcr_treshold and self.ste < Frame.ste_treshold:
            self.classification = 0

        else:
            self.classification = 2
            

        

    # decode to string voiced / unvoiced / DN frame
    def decodeFrame(self):
        if(self.classification == 0):
            return 'unvoiced'
        elif self.classification == 1:
            return 'voiced'
        else:
            return 'DN'
    


    # Function to print the parameters
    def getParameters(self):
        print('zero crossing rate: {}'.format(self.zcr))
        print('short time energy: {}'.format(self.ste))
        print('classification: {}'.format(self.decodeFrame()))
        print('length in samples: {}'.format(len(self.samples)))
        

    # Function to plot the frame
    def plotFrame(self):
        plt.plot(self.samples)
        plt.grid()
        plt.show()

    
 
# setting the duration of single frame
f_d = 0.1
frame_size = int(f_d * sr)
n = int(len(y)/frame_size)

# setting min duration of single frame
f_d_min = 0.02
frame_size_min = int(f_d_min * sr)

df = [[0]*frame_size]*n
temp = 0

# Read data
for i in range (0,n):
    df[i] = y[temp : frame_size + temp]
    temp += frame_size


# Function to set thresholds

def setThreshold(n_threshold, df):
    thres_zcr_tab = []
    thres_ste_tab = []
    for i in range(0,n_threshold):
        frame_set = Frame(df[i])
        frame_set.calculate_frame_parameters()
        thres_ste_tab.append(frame_set.ste)
        thres_zcr_tab.append(frame_set.zcr)


    Frame.ste_treshold = max(thres_ste_tab) *1e1
    Frame.zcr_treshold = min(thres_zcr_tab) 

# first x seconds is supposed to be noise
t_threshold = 0.2
n_threshold = int(t_threshold/f_d)

# Set thresholds
setThreshold(n_threshold,df)

# arrays
frames_to_process = []
frames_processed = []

# compute all frames
for i, values in enumerate(df):
    if len(frames_to_process) == 0:
        frame0 = Frame(df[i])
        frames_to_process.append(frame0)

        # untill the array is empty
        while len(frames_to_process) != 0:
            
            
            frame0 = frames_to_process[0]

            # classify the frame
            frame0.classify()
            
            # If the frame is too short, it i classified as unvoiced
            if frame0.frame_size < frame_size_min:
                frame0.classification = 0


            
            # If DN
            if frame0.classification == 2:
                
                frame1 = Frame(frame0.samples[0:int(frame0.frame_size/2)])

                frame2 = Frame(frame0.samples[int(frame0.frame_size/2):])
                
                frames_to_process.remove(frame0)

                frames_to_process.insert(0,frame1)
                frames_to_process.insert(1,frame2)
            else:
                frames_processed.append(frame0)
                frames_to_process.remove(frame0)
        
        
print('number of frames processed: {}'.format(len(frames_processed)))

# to the plots
vector_ste_thres = []
vector_zcr_thres = []
vector_zcr=[]
vector_ste=[]
vector_classification = []
for value in frames_processed:
    
    #ZCR to plots
    temp = [value.zcr]*value.frame_size
    vector_zcr += temp

    #STE to plots
    temp = [value.ste]*value.frame_size
    vector_ste +=temp

    #classification
    temp = [value.classification]*value.frame_size
    vector_classification += temp

    vector_ste_thres += [Frame.ste_treshold]*value.frame_size
    vector_zcr_thres += [Frame.zcr_treshold]*value.frame_size

#Plots
plt.style.use('ggplot')
fig1, ax1 = plt.subplots()
fig2, ax2 = plt.subplots()
fig3, ax3 = plt.subplots()

ax1.plot(y,color='royalblue', label = 'signal')
ax1.plot(vector_classification,color = 'r', linestyle = '--', label = 'voiced/unvoiced', linewidth = 1, alpha = 0.7)
ax1.set_title('Analysed signal')
ax1.set_xlabel('samples')
ax1.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05), shadow=True, ncol=2)

ax2.plot(vector_ste, color = 'm', linestyle = '-', label = 'Short time energy rate', linewidth = 1)
ax2.set_xlabel('samples')
ax2.set_ylabel('energy of the single frame')
ax2.set_title('Short time energy rate')
ax2.plot(vector_ste_thres, 'r--', label = 'ste threshold', linewidth = 1, alpha = 0.7)

ax3.plot(vector_zcr, color = 'c',linestyle = '-', label = 'Zero crossing rate', linewidth =1)
ax3.set_xlabel('samples')
ax3.set_ylabel('zero crossing rate')
ax3.set_title('Zero crossing rate')
ax3.plot(vector_zcr_thres, 'r--', label = 'zcr threshold', linewidth = 1, alpha = 0.7)

plt.show()

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值