基于全志A133 修改tinyplay工具源码(解决生产工具通过adb shell调用tinyplay工具循环播放.wav音频,并且执行完指令后脱离终端) - Android10

源码

一、修改Android.bp源码 - - 将tinyplay.c编译成静态可执行文件

  将对应的Android.bp文件中添加 static_executable: true, 即可。

二、修改tinyplay.c源码

1、通过输入的参数控制循环播放次数

在这里插入图片描述
  上图修改就是实现音频循环的关键了,下面就需要通过参数调用这个函数实现循环播放次数了。
在这里插入图片描述

2、使用守护进程使adb shell执行tinyplay工具脱离终端

  原因:因为生产工具使用的使adb shell执行tinyplay工具来播放对应的wav格式的音频文件,而执行adb shell指令播放音频需要播放完毕后才会退出adb shell,这样就导致生产工具执行不能边播放音频,边执行下一条指令了,因此需要执行tinyplay工具时,让其成为守护进程,脱离终端,那么adb shell就会退出,此时生产工具才能执行下一条指令,不会被阻塞。
  以下是我之前写的博客,有对守护进程相关的讲解。
博客链接

三、源码修改补丁

diff --git a/android/external/tinyalsa/Android.bp b/android/external/tinyalsa/Android.bp
index 090d91c0f8..f8ab2516a9 100644
--- a/android/external/tinyalsa/Android.bp
+++ b/android/external/tinyalsa/Android.bp
@@ -24,8 +24,10 @@ cc_binary {
     name: "tinyplay",
     host_supported: true,
     srcs: ["tinyplay.c"],
-    shared_libs: ["libtinyalsa"],
+    static_libs: ["libtinyalsa"],
+	stl: "libc++_static",
     cflags: ["-Werror"],
+	static_executable: true,
     target: {
         darwin: {
             enabled: false,
@@ -36,27 +38,31 @@ cc_binary {
 cc_binary {
     name: "tinycap",
     srcs: ["tinycap.c"],
-    shared_libs: ["libtinyalsa"],
+    static_libs: ["libtinyalsa"],
     cflags: ["-Werror"],
+	static_executable: true,
 }
 
 cc_binary {
     name: "tinymix",
     srcs: ["tinymix.c"],
-    shared_libs: ["libtinyalsa"],
+    static_libs: ["libtinyalsa"],
     cflags: ["-Werror", "-Wall"],
+	static_executable: true,
 }
 
 cc_binary {
     name: "tinyhostless",
     srcs: ["tinyhostless.c"],
-    shared_libs: ["libtinyalsa"],
+    static_libs: ["libtinyalsa"],
     cflags: ["-Werror"],
+	static_executable: true,
 }
 
 cc_binary {
     name: "tinypcminfo",
     srcs: ["tinypcminfo.c"],
-    shared_libs: ["libtinyalsa"],
+    static_libs: ["libtinyalsa"],
     cflags: ["-Werror"],
+	static_executable: true,
 }
diff --git a/android/external/tinyalsa/tinyplay.c b/android/external/tinyalsa/tinyplay.c
index 0354df6cb8..702b1f677d 100644
--- a/android/external/tinyalsa/tinyplay.c
+++ b/android/external/tinyalsa/tinyplay.c
@@ -33,6 +33,10 @@
 #include <string.h>
 #include <signal.h>
 #include <endian.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/stat.h>
 
 #define ID_RIFF 0x46464952
 #define ID_WAVE 0x45564157
@@ -59,17 +63,17 @@ struct chunk_fmt {
     uint16_t bits_per_sample;
 };
 
-static int close = 0;
+static int tiny_close = 0;
 
 void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
                  unsigned int rate, unsigned int bits, unsigned int period_size,
-                 unsigned int period_count, uint32_t data_sz);
+                 unsigned int period_count, uint32_t data_sz, unsigned int play_count);
 
 void stream_close(int sig)
 {
     /* allow the stream to be closed gracefully */
     signal(sig, SIG_IGN);
-    close = 1;
+    tiny_close = 1;
 }
 
 int main(int argc, char **argv)
@@ -84,81 +88,133 @@ int main(int argc, char **argv)
     unsigned int period_count = 4;
     char *filename;
     int more_chunks = 1;
-
-    if (argc < 2) {
-        fprintf(stderr, "Usage: %s file.wav [-D card] [-d device] [-p period_size]"
-                " [-n n_periods] \n", argv[0]);
-        return 1;
+    unsigned int play_count = 1;    //播放次数初始为1次
+    pid_t pid;
+    int i;
+
+    pid = fork();
+    if(pid < 0)
+    {
+        fprintf(stderr, "fork failed");
+        exit(1);
     }
 
-    filename = argv[1];
-    file = fopen(filename, "rb");
-    if (!file) {
-        fprintf(stderr, "Unable to open file '%s'\n", filename);
-        return 1;
+    if(pid > 0) {
+        fprintf(stderr, "parent\n");
+        sleep(1);
+        exit(0);
     }
 
-    fread(&riff_wave_header, sizeof(riff_wave_header), 1, file);
-    if ((riff_wave_header.riff_id != ID_RIFF) ||
-        (riff_wave_header.wave_id != ID_WAVE)) {
-        fprintf(stderr, "Error: '%s' is not a riff/wave file\n", filename);
-        fclose(file);
-        return 1;
-    }
+    if(pid == 0) {
+        fprintf(stderr, "child\n");
 
-    do {
-        fread(&chunk_header, sizeof(chunk_header), 1, file);
-
-        switch (chunk_header.id) {
-        case ID_FMT:
-            fread(&chunk_fmt, sizeof(chunk_fmt), 1, file);
-            /* If the format header is larger, skip the rest */
-            if (chunk_header.sz > sizeof(chunk_fmt))
-                fseek(file, chunk_header.sz - sizeof(chunk_fmt), SEEK_CUR);
-            break;
-        case ID_DATA:
-            /* Stop looking for chunks */
-            more_chunks = 0;
-            chunk_header.sz = le32toh(chunk_header.sz);
-            break;
-        default:
-            /* Unknown chunk, skip bytes */
-            fseek(file, chunk_header.sz, SEEK_CUR);
-        }
-    } while (more_chunks);
-
-    /* parse command line arguments */
-    argv += 2;
-    while (*argv) {
-        if (strcmp(*argv, "-d") == 0) {
-            argv++;
-            if (*argv)
-                device = atoi(*argv);
-        }
-        if (strcmp(*argv, "-p") == 0) {
-            argv++;
-            if (*argv)
-                period_size = atoi(*argv);
+        /* 创建新会话,脱离控制终端 */
+        if(setsid() < 0) {
+            fprintf(stderr,"setsid error\n");
+            exit(-1);
         }
-        if (strcmp(*argv, "-n") == 0) {
-            argv++;
-            if (*argv)
-                period_count = atoi(*argv);
+        /* 设置单曲工作目录为根目录 */
+        if(0 > chdir("/")) {
+            fprintf(stderr,"setsid error\n");
+            exit(-1);
         }
-        if (strcmp(*argv, "-D") == 0) {
-            argv++;
-            if (*argv)
-                card = atoi(*argv);
+        /* 重设文件权限掩码 umask */
+        umask(0);
+        /* 关闭所有文件描述符 */
+        for(i = 0; i < sysconf(_SC_OPEN_MAX); i++) {
+            close(i);
         }
-        if (*argv)
-            argv++;
-    }
+        /* 将文件描述符号为0、1、2定位到/dev/null */
+        open("/dev/null", O_RDWR);
+        dup(0);
+        dup(0);
+        /* 忽略SIGCHLD信号 */
+        signal(SIGCHLD, SIG_IGN);
+
+        for( ; ; ) {
+            /*****************************************************/
+            if (argc < 2) {
+                fprintf(stderr, "Usage: %s file.wav [-D card] [-d device] [-p period_size]"
+                        " [-n n_periods] \n", argv[0]);
+                return 1;
+            }
 
-    play_sample(file, card, device, chunk_fmt.num_channels, chunk_fmt.sample_rate,
-                chunk_fmt.bits_per_sample, period_size, period_count, chunk_header.sz);
+            filename = argv[1];
+            file = fopen(filename, "rb");
+            if (!file) {
+                fprintf(stderr, "Unable to open file '%s'\n", filename);
+                return 1;
+            }
 
-    fclose(file);
+            fread(&riff_wave_header, sizeof(riff_wave_header), 1, file);
+            if ((riff_wave_header.riff_id != ID_RIFF) ||
+                (riff_wave_header.wave_id != ID_WAVE)) {
+                fprintf(stderr, "Error: '%s' is not a riff/wave file\n", filename);
+                fclose(file);
+                return 1;
+            }
 
+            do {
+                fread(&chunk_header, sizeof(chunk_header), 1, file);
+
+                switch (chunk_header.id) {
+                case ID_FMT:
+                    fread(&chunk_fmt, sizeof(chunk_fmt), 1, file);
+                    /* If the format header is larger, skip the rest */
+                    if (chunk_header.sz > sizeof(chunk_fmt))
+                        fseek(file, chunk_header.sz - sizeof(chunk_fmt), SEEK_CUR);
+                    break;
+                case ID_DATA:
+                    /* Stop looking for chunks */
+                    more_chunks = 0;
+                    chunk_header.sz = le32toh(chunk_header.sz);
+                    break;
+                default:
+                    /* Unknown chunk, skip bytes */
+                    fseek(file, chunk_header.sz, SEEK_CUR);
+                }
+            } while (more_chunks);
+
+            /* parse command line arguments */
+            argv += 2;
+            while (*argv) {
+                if (strcmp(*argv, "-d") == 0) {
+                    argv++;
+                    if (*argv)
+                        device = atoi(*argv);
+                }
+                if (strcmp(*argv, "-p") == 0) {
+                    argv++;
+                    if (*argv)
+                        period_size = atoi(*argv);
+                }
+                if (strcmp(*argv, "-n") == 0) {
+                    argv++;
+                    if (*argv)
+                        period_count = atoi(*argv);
+                }
+                if (strcmp(*argv, "-D") == 0) {
+                    argv++;
+                    if (*argv)
+                        card = atoi(*argv);
+                }
+                if (strcmp(*argv, "-pp") == 0) {
+                    argv++;
+                    if (*argv)
+                        play_count = atoi(*argv);
+                }
+                if (*argv)
+                    argv++;
+            }
+            fprintf(stderr,"chunk_fmt.num_channels huidu = %d\n", chunk_fmt.num_channels);
+            play_sample(file, card, device, chunk_fmt.num_channels, chunk_fmt.sample_rate,
+                        chunk_fmt.bits_per_sample, period_size, period_count, chunk_header.sz, play_count);
+
+            fclose(file);
+            exit(0);
+            /*****************************************************/        
+        }    
+    }
     return 0;
 }
 
@@ -212,13 +268,14 @@ int sample_is_playable(unsigned int card, unsigned int device, unsigned int chan
 
 void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
                  unsigned int rate, unsigned int bits, unsigned int period_size,
-                 unsigned int period_count, uint32_t data_sz)
+                 unsigned int period_count, uint32_t data_sz, unsigned int play_count)
 {
     struct pcm_config config;
     struct pcm *pcm;
     char *buffer;
     unsigned int size, read_sz;
     int num_read;
+    uint32_t data_sz_save = data_sz;    //保存播放音频的字节数
 
     memset(&config, 0, sizeof(config));
     config.channels = channels;
@@ -260,17 +317,26 @@ void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned in
     /* catch ctrl-c to shutdown cleanly */
     signal(SIGINT, stream_close);
 
-    do {
-        read_sz = size < data_sz ? size : data_sz;
-        num_read = fread(buffer, 1, read_sz, file);
-        if (num_read > 0) {
-            if (pcm_write(pcm, buffer, num_read)) {
-                fprintf(stderr, "Error playing sample\n");
-                break;
+    /* 通过play_count变量判断循环播放次数 */
+    while(play_count > 0) {
+
+        do {
+            read_sz = size < data_sz ? size : data_sz;
+            num_read = fread(buffer, 1, read_sz, file);
+            if (num_read > 0) {
+                if (pcm_write(pcm, buffer, num_read)) {
+                    fprintf(stderr, "Error playing sample\n");
+                    break;
+                }
+                data_sz -= num_read;
             }
-            data_sz -= num_read;
-        }
-    } while (!close && num_read > 0 && data_sz > 0);
+        } while (!tiny_close && num_read > 0 && data_sz > 0);
+
+        data_sz = data_sz_save; //播放完一下,将音频数据个数兼数据位置恢复到起始位置
+        fseek(file, 0, SEEK_SET);   //文件指针回到起始位置
+        play_count--;   //播放次数减一
+    }
+
 
     free(buffer);
     pcm_close(pcm);

关于audacity软件

  这个软件可以裁剪音频,特别是做一些音频测试相关的,比如左、右声道单独测试什么,网上直接搜索就有了,我也上传了资源->链接

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邓家文007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值