加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
asr.c 4.69 KB
一键复制 编辑 原始数据 按行查看 历史
刘煜 提交于 2024-03-11 16:05 . 增加语音识别示例代码
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <cjson/cJSON.h>
#include "auth.h"
char* ak = "API Key";
char* sk = "Secret Key";
//从文件中读取音频数据
//file: 文件名
//buf: 缓冲区指针的地址
//return: 读取数据大小
size_t load_file(char* file, char** buf)
{
FILE* fp = fopen(file, "r");
if (!fp)
{
perror("fopen");
return 0;
}
//获取文件大小
if (fseek(fp, 0, SEEK_END) < 0)
{
perror("fseek");
fclose(fp);
return 0;
}
long size = ftell(fp);
if (size < 0)
{
perror("ftell");
fclose(fp);
return 0;
}
//分配缓冲区,并将文件中的数据读入到缓冲区中
*buf = malloc(size);
if (!*buf)
{
perror("malloc");
fclose(fp);
return 0;
}
//将文件指针移动到文件头
fseek(fp, 0, SEEK_SET);
size_t readn = fread(*buf, 1, size, fp);
if (readn != size)
{
fprintf(stderr, "file size: %ld, read: %zd\n", size, readn);
}
fclose(fp);
return readn;
}
//发送HTTP请求报文,并返回服务器响应报文
//token: 访问API需要的access token
//audio: 需要转换的音频数据
//size: 音频数据的大小
//return: 服务器返回的响应报文
char* send_request(char* token, char* audio, size_t size)
{
char* respdata = NULL;
size_t respsize = 0;
FILE* fp = open_memstream(&respdata, &respsize);
if (!fp)
{
perror("open_memstream");
return NULL;
}
CURL* client = curl_easy_init();
if (!client)
{
perror("curl_easy_init");
fclose(fp);
return NULL;
}
//设置API地址和参数
char* url = NULL;
asprintf(&url, "http://vop.baidu.com/server_api?dev_pid=1537&cuid=liuyu&token=%s", token);
curl_easy_setopt(client, CURLOPT_URL, url);
//增加请求头部字段
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: audio/pcm;rate=16000");
curl_easy_setopt(client, CURLOPT_HTTPHEADER, headers);
//发送POST请求
curl_easy_setopt(client, CURLOPT_POST, 1);
curl_easy_setopt(client, CURLOPT_POSTFIELDS, audio);
curl_easy_setopt(client, CURLOPT_POSTFIELDSIZE, size);
//将服务器返回的响应报文保存到文件流中
curl_easy_setopt(client, CURLOPT_WRITEDATA, fp);
//发送请求消息
CURLcode error = curl_easy_perform(client);
if (error != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform: %s\n", curl_easy_strerror(error));
free(url);
curl_slist_free_all(headers);
curl_easy_cleanup(client);
fclose(fp);
return NULL;
}
free(url);
curl_slist_free_all(headers);
curl_easy_cleanup(client);
//关闭文件流之后才能访问内存中的数据
fclose(fp);
return respdata;
}
//解析服务器响应报文,打印识别结果
void process_response(char* respdata)
{
//解析json
cJSON* root = cJSON_Parse(respdata);
if (!root)
{
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL)
{
fprintf(stderr, "Error before: %s\n", error_ptr);
}
return;
}
//获取错误码
cJSON* err_no = cJSON_GetObjectItem(root, "err_no");
if (!err_no)
{
fprintf(stderr, "err_no attribute not found\n");
cJSON_Delete(root);
return;
}
if (err_no->valueint != 0)
{
cJSON* err_msg = cJSON_GetObjectItem(root, "err_msg");
if (err_msg)
{
fprintf(stderr, "Error: %s\n", err_msg->valuestring);
}
cJSON_Delete(root);
return;
}
//获取转换结果
cJSON* result = cJSON_GetObjectItem(root, "result");
if (!result)
{
fprintf(stderr, "result attribute not found\n");
cJSON_Delete(root);
return;
}
if (!cJSON_IsArray(result))
{
fprintf(stderr, "result attribute format error\n");
cJSON_Delete(root);
return;
}
int n = cJSON_GetArraySize(result);
for (int i = 0; i < n; i++)
{
cJSON* item = cJSON_GetArrayItem(result, i);
puts(item->valuestring);
}
cJSON_Delete(root);
}
int main(int argc, char** argv)
{
char* token = get_token(ak, sk);
if (!token)
{
return EXIT_FAILURE;
}
char* audio = NULL;
size_t size = load_file(argv[1], &audio);
if (!size)
{
free(token);
return EXIT_FAILURE;
}
char* response = send_request(token, audio, size);
free(audio);
free(token);
if (!response)
{
return EXIT_FAILURE;
}
process_response(response);
free(response);
return 0;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化