题目如下:
第二部分参考官方的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, ¶m_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()