Android 音频 alsa 拾音例子

Android4 之后使用的是 tinyasla

源码路径: external/tinyalsa/

拾音demo: tinycap.c

放音demo:tinyplay.c

可在 源码中执行

mmm external/tinyalsa/

编译后的执行文件在目录: out/target/product/msm8953_64/system/bin/

使用 tinycap  tinyplay 设置相应的声卡 即可拾音或放音,命令如下:

tinycap /sdcard/xxx.wav -D 0 -d 0 -c 1 -r 48000 -b 16 -p 240 -n 2
tinyplay /sdcard/xxx.wav -D 0 -d 0

使用 alsa API  的 demo 如下:

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
#LOCAL_CFLAGS := -D_POSIX_SOURCE

LOCAL_C_INCLUDES += $(TOP)/device/hisilicon/bigfish/external/alsa-lib/include



LOCAL_SRC_FILES :=	 alsa_main.c

LOCAL_MODULE := alsa_test

LOCAL_SHARED_LIBRARIES := \
  libcutils \
  libutils \
  libasound

include $(BUILD_EXECUTABLE)

 

#define ALSA_PCM_NEW_HW_PARAMS_API

#include <utils/Log.h>
#include <alsa/asoundlib.h>
#include <stdlib.h>
#include <signal.h>

#undef  LOG_TAG
#define LOG_TAG "alsatest"


#define filename(x) strrchr(x,'/')?strrchr(x,'/')+1:x

#if 1

#define logi(fmt,args...) printf("I \%s " fmt, LOG_TAG, ##args); printf("\n")
#define loge(fmt,args...) printf("E \%s " fmt, LOG_TAG, ##args); printf("\n")
#define logd(fmt,args...) printf("D \%s " fmt, LOG_TAG, ##args); printf("\n")

//#define logi(fmt,args...) ALOGI(fmt, ##args)
//#define loge(fmt,args...) ALOGE(fmt, ##args)
//#define logd(fmt,args...) ALOGD(fmt, ##args)
//#define logenter()        ALOGI("enter %s, %s", __func__, filename(__FILE__))
//#define logexit()         ALOGI("exit  %s, %s", __func__, filename(__FILE__))

#else

#define logi(fmt,args...) do{}while(0)
#define loge(fmt,args...) do{}while(0)
#define logd(fmt,args...) do{}while(0)
#define logenter()        do{}while(0)
#define logexit()         do{}while(0)

#endif

int capturing = 1;

void sigint_handler(int sig __unused)
{
    capturing = 0;
}

int main()
{
	int rc;
	int size;
	int dir;
	char *buffer;
	unsigned int channel;
	unsigned int rate;
	snd_pcm_uframes_t frames;
	snd_pcm_t *handle;
	snd_pcm_hw_params_t *params;
	FILE *out_fp;
	out_fp = fopen("a.raw", "wb");

	// 访问硬件,并判断硬件是否访问成功
	rc = snd_pcm_open(&handle, "hw:0,0", SND_PCM_STREAM_CAPTURE, 0);
	if(rc < 0)
	{
		loge("unable to open device: %s", snd_strerror(rc));
		return -1;
	}
	// 分配一个硬件参数结构体
	snd_pcm_hw_params_alloca(&params);
	// 使用默认参数
	snd_pcm_hw_params_any(handle, params);
	// interleaved mode 设置数据为交叉模式,即LRLRLR...
	snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
	// 设置数据编码格式为PCM、有符号、16bit、小端
	snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
	// 设置通道数
	channel = 2;
	snd_pcm_hw_params_set_channels(handle, params, channel);
	// 设置采样率
	rate = 48000;
	snd_pcm_hw_params_set_rate_near(handle, params, &rate, &dir);
	// 周期长度(帧数) 16bit * 2(双声道)
	frames = 32;
	snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
	// 将配置写入驱动程序中,判断是否已经配置正确
	rc = snd_pcm_hw_params(handle, params);
	if(rc < 0)
	{
		loge("unable to set hw parameters: %s", snd_strerror(rc));
		return -1;
	}

	// 得到一个周期的数据大小
	snd_pcm_hw_params_get_period_size(params, &frames, &dir);
	// 2 bytes sample, 2 channels;16位: 2*frames*channels
	size = frames * 2 * channel;
	buffer = (char *)malloc(size);
	// 得到一个周期的时间长度
	snd_pcm_hw_params_get_period_time(params, &rate, &dir);

	while(capturing)
	{
		// 捕获数据
		rc = snd_pcm_readi(handle, buffer, frames);
		if(rc == -EPIPE)
		{
			loge("overrun occured");
			snd_pcm_prepare(handle);
		}
		else if(rc < 0)
		{
			loge("error from read: %s", snd_strerror(rc));

		}
		else if(rc != (int)frames)
		{
			loge("short read %d frames", rc);
		}
		rc = fwrite(buffer, 1, size, out_fp);
		if(rc != size)
		{
			loge("short write %d bytes", rc);
		}
	}

	snd_pcm_drain(handle);
	snd_pcm_close(handle);
	free(buffer);
	fclose(out_fp);

	return 0;
}

源码下载链接 https://download.csdn.net/download/qq_38907791/10975134

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值