From 619dc98f4423a73772bea3b801f0b8de4b6c5590 Mon Sep 17 00:00:00 2001 From: "ithink.chan" Date: Tue, 14 Apr 2020 16:43:13 +0800 Subject: [PATCH] =?UTF-8?q?SndDelay=20=E5=8D=87=E7=BA=A7=E5=88=B0=201.1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ithink.chan --- Linux/Application/ALSA/SndDelay/Android.mk | 9 +++ Linux/Application/ALSA/SndDelay/LICENSE | 3 + Linux/Application/ALSA/SndDelay/README.md | 6 ++ Linux/Application/ALSA/SndDelay/SndDelay.c | 72 ++++++++++++++-------- 4 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 Linux/Application/ALSA/SndDelay/Android.mk create mode 100644 Linux/Application/ALSA/SndDelay/LICENSE create mode 100644 Linux/Application/ALSA/SndDelay/README.md diff --git a/Linux/Application/ALSA/SndDelay/Android.mk b/Linux/Application/ALSA/SndDelay/Android.mk new file mode 100644 index 0000000..403e28f --- /dev/null +++ b/Linux/Application/ALSA/SndDelay/Android.mk @@ -0,0 +1,9 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_CFLAGS += -pie -fPIE +LOCAL_LDFLAGS += -pie -fPIE +LOCAL_LDLIBS += -pthread +LOCAL_MODULE := SndDelay +LOCAL_SRC_FILES := SndDelay.c +LOCAL_SYSTEM_SHARED_LIBRARIES := libasound libc +include $(BUILD_EXECUTABLE) diff --git a/Linux/Application/ALSA/SndDelay/LICENSE b/Linux/Application/ALSA/SndDelay/LICENSE new file mode 100644 index 0000000..3db68ad --- /dev/null +++ b/Linux/Application/ALSA/SndDelay/LICENSE @@ -0,0 +1,3 @@ +Copyright (C) 2006 by Rob Landley +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Linux/Application/ALSA/SndDelay/README.md b/Linux/Application/ALSA/SndDelay/README.md new file mode 100644 index 0000000..1fa6cd8 --- /dev/null +++ b/Linux/Application/ALSA/SndDelay/README.md @@ -0,0 +1,6 @@ +# auto-audio-snddelay + +通过示波器测量 mic 与 speaker 之间声音的相位差来获取声音虚拟化的读写总延时。 + +Makefile 文件用于编译 Linux 系统下的可执行程序。 +Android.mk 用于编译 Android 系统下的工具程序,将 Android.mk 和源码文件置于 external 文件夹下的独立文件夹下,之后在该文件夹下通过 mm 命令进行独立编译(Android 已整体编译过)。之后在 out/target/product/\/system/bin/ 下可找到 SndDelay 程序。 diff --git a/Linux/Application/ALSA/SndDelay/SndDelay.c b/Linux/Application/ALSA/SndDelay/SndDelay.c index c4a312e..ca13939 100644 --- a/Linux/Application/ALSA/SndDelay/SndDelay.c +++ b/Linux/Application/ALSA/SndDelay/SndDelay.c @@ -13,23 +13,33 @@ #include #include -#define PERIOD_CNT 16 -#define PERIOD_FRAMES 512 -#define PERIOD_BYTES 2048 +#define PERIOD_CNT 4 +#define PERIOD_FRAMES 4096 +#define PERIOD_BYTES (4*PERIOD_FRAMES) #define BUF_SZ (PERIOD_CNT * PERIOD_FRAMES) #define TOTAL_BUF (PERIOD_CNT * PERIOD_BYTES) -void init_pcm(snd_pcm_t *handle) +void init_pcm(snd_pcm_t *handle, int type) { int err; snd_pcm_hw_params_t *hw_params; - // snd_pcm_sw_params_t *sw_params; + snd_pcm_sw_params_t *sw_params; unsigned int rate = 48000; unsigned int periods = PERIOD_CNT; snd_pcm_uframes_t period_size = PERIOD_FRAMES; snd_pcm_uframes_t buffer_size = BUF_SZ; + if (0==type) { + periods = 4; + period_size = PERIOD_FRAMES; + buffer_size = BUF_SZ; + } else { + periods = 4; + period_size = PERIOD_FRAMES; + buffer_size = BUF_SZ; + } + if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { printf ("cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)); @@ -81,14 +91,14 @@ void init_pcm(snd_pcm_t *handle) exit (1); } - /*snd_pcm_sw_params_alloca (&sw_params); + snd_pcm_sw_params_alloca (&sw_params); if ((err = snd_pcm_sw_params_current(handle, sw_params)) < 0) { printf ("cannot get current software parameters (%s)\n", snd_strerror (err)); exit (1); } - if ((err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, 0)) < 0) { + if ((err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, 16384)) < 0) { printf ("cannot set threshold (%s)\n", snd_strerror (err)); exit (1); @@ -97,7 +107,8 @@ void init_pcm(snd_pcm_t *handle) printf ("cannot set software parameters (%s)\n", snd_strerror (err)); exit (1); - }*/ + } + if ((err = snd_pcm_prepare (handle)) < 0) { printf ("cannot prepare audio interface for use (%s)\n", snd_strerror (err)); @@ -116,7 +127,7 @@ snd_pcm_t* init_playback(char output[]) snd_strerror (err)); exit (1); } - init_pcm(playback_handle); + init_pcm(playback_handle, 0); return playback_handle; } @@ -131,14 +142,14 @@ snd_pcm_t* init_capture(char input[]) snd_strerror (err)); exit (1); } - init_pcm(capture_handle); + init_pcm(capture_handle, 1); return capture_handle; } pthread_mutex_t Mtx; pthread_cond_t Cond; snd_pcm_sframes_t Remains = 0; -char Buf[2][PERIOD_BYTES]; +char Buf[2][4*PERIOD_BYTES]; typedef enum _pcm_stream_type { PCM_PB = 0, // playback @@ -164,13 +175,18 @@ static void* pcm_op_thread (void *arg) { unsigned long long offset = 0; - pthread_mutex_lock (&Mtx); + /*pthread_mutex_lock (&Mtx); pthread_cond_wait (&Cond, &Mtx); remains = Remains; - pthread_mutex_unlock (&Mtx); - + pthread_mutex_unlock (&Mtx);*/ + remains = 4*PERIOD_FRAMES; while (0!=remains) { - frames = snd_pcm_writei (stream->handle, &Buf[x][offset], remains); + frames = snd_pcm_writei (stream->handle, &Buf[x][offset], 4*PERIOD_FRAMES); + if (0>frames) { + // frames = snd_pcm_recover (stream->handle, remains, 0); + continue; + } + remains -= frames; offset += frames*(PERIOD_BYTES/PERIOD_FRAMES); } @@ -178,11 +194,16 @@ static void* pcm_op_thread (void *arg) break; } case PCM_CPT: - remains = snd_pcm_readi (stream->handle, Buf[x], PERIOD_FRAMES); - pthread_mutex_lock (&Mtx); + remains = snd_pcm_readi (stream->handle, Buf[x], 4*PERIOD_FRAMES); + if (0>remains) { + // remains = snd_pcm_recover (stream->handle, PERIOD_FRAMES, 0); + continue; + } + + /*pthread_mutex_lock (&Mtx); Remains = remains; pthread_cond_signal (&Cond); - pthread_mutex_unlock (&Mtx); + pthread_mutex_unlock (&Mtx);*/ x = (x+1)%2; break; default: @@ -197,13 +218,15 @@ int main (int argc, char *argv[]) pcm_stream_t playback_stream; pcm_stream_t capture_stream; + /*char buf[PERIOD_BYTES]; + snd_pcm_sframes_t frames = 0, remains = 0;*/ pthread_mutexattr_t mux_attr; pthread_attr_t thr_attr; int rc; if (argc==2) { if (0==strcmp("-v", argv[1])) { - printf ("SndDelay Version 1.0\r\n"); + printf ("SndDelay Version 1.1\r\n"); exit (0); } if (0==strcmp("-h", argv[1])) { @@ -217,11 +240,6 @@ int main (int argc, char *argv[]) exit (0); } - if (argc!=3) { - printf ("SndDelay \r\nExp: SndDelay plughw:0,0 hw:0,1\r\n"); - exit (0); - } - playback_stream.handle = init_playback(argv[1]); playback_stream.type = PCM_PB; capture_stream.handle = init_capture(argv[2]); @@ -246,9 +264,11 @@ int main (int argc, char *argv[]) /*while (1) { unsigned long long offset = 0; - remains = snd_pcm_readi (capture_handle, buf, PERIOD_FRAMES); + remains = snd_pcm_readi (capture_stream.handle, buf, PERIOD_FRAMES); + if (0>remains) continue; while (0!=remains) { - frames = snd_pcm_writei (playback_handle, &buf[offset], remains); + frames = snd_pcm_writei (playback_stream.handle, &buf[offset], remains); + if (0>frames) continue; remains -= frames; offset += frames*(PERIOD_BYTES/PERIOD_FRAMES); }