提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、混音播放源码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <tinyalsa/asoundlib.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <endian.h>
#include <threads.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#define IN_FILE1 "data/1.wav"
#define IN_FILE2 "data/2.wav"
#define OUT_FILE "data/remix.pcm"
#define SIZE_AUDIO_FRAME (2)
static int stream_close_flag = 0;
void stream_close(int sig)
{
/* allow the stream to be closed gracefully */
signal(sig, SIG_IGN);
stream_close_flag = 1;
}
void Mix(char sourseFile[10][SIZE_AUDIO_FRAME],int number,char *objectFile)
{
//归一化混音
int const MAX=32767;
int const MIN=-32768;
double f=1;
int output;
int i = 0,j = 0;
for (i=0; i < SIZE_AUDIO_FRAME/2; i++)
{
int temp=0;
for (j=0;j<number;j++)
{
temp+=*(short*)(sourseFile[j]+i*2);
}
output=(int)(temp*f);
if (output>MAX)
{
f=(double)MAX/(double)(output);
output=MAX;
}
if (output<MIN)
{
f=(double)MIN/(double)(output);
output=MIN;
}
if (f<1)
{
f+=((double)1-f)/(double)32;
}
*(short*)(objectFile+i*2)=(short)output;
}
}
int check_param(struct pcm_params *params, unsigned int param, unsigned int value,
char *param_name, char *param_unit)
{
unsigned int min;
unsigned int max;
int is_within_bounds = 1;
min = pcm_params_get_min(params, param);
if (value < min) {
fprintf(stderr, "%s is %u%s, device only supports >= %u%s\n", param_name, value,
param_unit, min, param_unit);
is_within_bounds = 0;
}
max = pcm_params_get_max(params, param);
if (value > max) {
fprintf(stderr, "%s is %u%s, device only supports <= %u%s\n", param_name, value,
param_unit, max, param_unit);
is_within_bounds = 0;
}
return is_within_bounds;
}
int sample_is_playable(unsigned int card, unsigned int device, unsigned int channels,
unsigned int rate, unsigned int bits, unsigned int period_size,
unsigned int period_count)
{
struct pcm_params *params;
int can_play;
params = pcm_params_get(card, device, PCM_OUT);
if (params == NULL) {
fprintf(stderr, "Unable to open PCM device %u.\n", device);
return 0;
}
can_play = check_param(params, PCM_PARAM_RATE, rate, "Sample rate", "Hz");
can_play &= check_param(params, PCM_PARAM_CHANNELS, channels, "Sample", " channels");
can_play &= check_param(params, PCM_PARAM_SAMPLE_BITS, bits, "Bitrate", " bits");
can_play &= check_param(params, PCM_PARAM_PERIOD_SIZE, period_size, "Period size", " frames");
can_play &= check_param(params, PCM_PARAM_PERIODS, period_count, "Period count", " periods");
pcm_params_free(params);
return can_play;
}
int playback_thread()
{
printf("playback_thread excute!!!\n");
// FILE *file;
int file;
struct pcm_config config;
struct pcm *pcm;
unsigned int size, read_sz;
char *buffer;
int num_read;
config.channels = 2;
config.rate = 11025;
config.period_count = 4;
config.period_size = 1024;
config.format = PCM_FORMAT_S16_LE;
config.start_threshold = 0;
config.stop_threshold = 0;
config.silence_threshold = 0;
config.avail_min = 0;
unsigned int flag = PCM_OUT;
char *filename = OUT_FILE;
file = open(filename, O_RDONLY | O_CREAT | O_TRUNC, 0777);
if (/*!file*/ file < 0) {
fprintf(stderr, "Unable to open file '%s'\n", filename);
return 1;
}
int flags;
flags = fcntl(file, F_GETFL, 0);
fcntl(file, F_SETFL, flags & ~O_NONBLOCK);
if (!sample_is_playable(0, 0, config.channels, config.rate, 16, config.period_size, config.period_count)) {
printf("parameters error\n");
return -1;
}
pcm = pcm_open(0, 0, flag, &config);
if (!pcm || !pcm_is_ready(pcm)) {
fprintf(stderr, "Unable to open PCM device %u (%s)\n",
0, pcm_get_error(pcm));
return -1;
}
size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));
buffer = malloc(size);
if (!buffer) {
fprintf(stderr, "Unable to allocate %d bytes\n", size);
free(buffer);
pcm_close(pcm);
return -1;
}
signal(SIGINT, stream_close);
do {
//read_sz = size < data_sz ? size : data_sz;
read_sz = size;
// num_read = fread(buffer, 1, read_sz, file);
num_read = read(file, buffer, read_sz);
if (num_read > 3) {
printf("---------------4-num_read = %d \n", num_read);
if (pcm_write(pcm, buffer, num_read)) {
fprintf(stderr, "Error playing sample\n");
break;
}
//data_sz -= num_read;
}
if(num_read < 2){
printf("---------------5-num_read = %d <3 process maybe enter read block!!!--------\n", num_read);
continue;
}
} while (!stream_close_flag);
free(buffer);
pcm_close(pcm);
return 0;
}
int multi_source_mix_thread()
{
// FILE * fp1,*fp2,*fpm;
int fd1, fd2, fdm;
// fp1 = fopen(IN_FILE1,"rb");
// fp2 = fopen(IN_FILE2,"rb");
// fpm = fopen(OUT_FILE,"wb");
fd1 = open(IN_FILE1, O_RDONLY);
fd2 = open(IN_FILE2, O_RDONLY);
fdm = open(OUT_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0777);
if(fd1 < 0 || fd2 < 0 || fdm < 0){
printf("file open error!!!\n");
}
int flags;
flags = fcntl(fd1, F_GETFL, 0);
fcntl(fd1, F_SETFL, flags & ~O_NONBLOCK);
flags = fcntl(fd2, F_GETFL, 0);
fcntl(fd2, F_SETFL, flags & ~O_NONBLOCK);
short data1,data2,data_mix;
int ret1,ret2;
char sourseFile[10][2];
while(1)
{
//混音
// ret1 = fread(&data1,2,1,fp1);
// ret2 = fread(&data2,2,1,fp2);
ret1 = read(fd1, &data1, 2);
ret2 = read(fd2, &data2, 2);
*(short*) sourseFile[0] = data1;
*(short*) sourseFile[1] = data2;
if((ret1 == 2) /*ret1>0*/ && (ret2 == 2) /*ret2>0*/)
{
Mix(sourseFile,2,(char *)&data_mix);
/*
if( data1 < 0 && data2 < 0)
data_mix = data1+data2 - (data1 * data2 / -(pow(2,16-1)-1));
else
data_mix = data1+data2 - (data1 * data2 / (pow(2,16-1)-1));*/
if(data_mix > pow(2,16-1) || data_mix < -pow(2,16-1))
printf("mix error\n");
}
else if( (ret1 == 2)/*(ret1 > 0)*/ && (ret2 < 2)/*(ret2==0)*/)
{
data_mix = data1;
}
else if( (ret2 == 2) && (ret1 < 2)/*(ret2 > 0) && (ret1==0)*/)
{
data_mix = data2;
}
else if( (ret1 < 2) && (ret2 < 2)/*(ret1 == 0) && (ret2 == 0)*/ )
{
printf("ret1 < 2 && ret2 < 2, process will enter block!!!\n");
continue;
}
// fwrite(&data_mix,2,1,fpm);
write(fdm, &data_mix, 2);
}
// fclose(fp1);
// fclose(fp2);
// fclose(fpm);
close(fd1);
close(fd2);
close(fdm);
printf("Done!\n");
return 0;
}
int main()
{
printf("main !!!\n");
thrd_t thread1;
thrd_t thread2;
thrd_create(&thread1, multi_source_mix_thread, "th1");
thrd_create(&thread2, playback_thread, "th2");
thrd_join(thread1,NULL);
printf("main thread1 end!!!\n");
thrd_join(thread2,NULL);
printf("main thread2 end!!!\n");
}
二、编译文件
cc_library {
name: "libtinyalsa",
host_supported: true,
vendor_available: true,
vndk: {
enabled: true,
},
srcs: [
"mixer.c",
"pcm.c",
],
cflags: ["-Werror", "-Wno-macro-redefined"],
export_include_dirs: ["include"],
local_include_dirs: ["include"],
target: {
darwin: {
enabled: false,
},
},
}
cc_binary {
name: "multiSourceMixer",
host_supported: true,
srcs: ["multiSourceMixer.c"],
shared_libs: ["libtinyalsa"],
cflags: ["-Werror"],
target: {
darwin: {
enabled: false,
},
},
}