xref: /aosp_15_r20/system/media/audio_utils/tests/fifo_threads.cpp (revision b9df5ad1c9ac98a7fefaac271a55f7ae3db05414)
1*b9df5ad1SAndroid Build Coastguard Worker /*
2*b9df5ad1SAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*b9df5ad1SAndroid Build Coastguard Worker  *
4*b9df5ad1SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*b9df5ad1SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*b9df5ad1SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*b9df5ad1SAndroid Build Coastguard Worker  *
8*b9df5ad1SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*b9df5ad1SAndroid Build Coastguard Worker  *
10*b9df5ad1SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*b9df5ad1SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*b9df5ad1SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b9df5ad1SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*b9df5ad1SAndroid Build Coastguard Worker  * limitations under the License.
15*b9df5ad1SAndroid Build Coastguard Worker  */
16*b9df5ad1SAndroid Build Coastguard Worker 
17*b9df5ad1SAndroid Build Coastguard Worker #include <errno.h>
18*b9df5ad1SAndroid Build Coastguard Worker #include <pthread.h>
19*b9df5ad1SAndroid Build Coastguard Worker #include <stdio.h>
20*b9df5ad1SAndroid Build Coastguard Worker #include <unistd.h>
21*b9df5ad1SAndroid Build Coastguard Worker #include <audio_utils/fifo.h>
22*b9df5ad1SAndroid Build Coastguard Worker 
23*b9df5ad1SAndroid Build Coastguard Worker extern "C" {
24*b9df5ad1SAndroid Build Coastguard Worker #include "getch.h"
25*b9df5ad1SAndroid Build Coastguard Worker }
26*b9df5ad1SAndroid Build Coastguard Worker 
27*b9df5ad1SAndroid Build Coastguard Worker struct Context {
28*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_writer *mInputWriter;
29*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_reader *mInputReader;
30*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_writer *mTransferWriter;
31*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_reader *mTransferReader;
32*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_writer *mOutputWriter;
33*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_reader *mOutputReader;
34*b9df5ad1SAndroid Build Coastguard Worker };
35*b9df5ad1SAndroid Build Coastguard Worker 
input_routine(void * arg)36*b9df5ad1SAndroid Build Coastguard Worker void *input_routine(void *arg)
37*b9df5ad1SAndroid Build Coastguard Worker {
38*b9df5ad1SAndroid Build Coastguard Worker     Context *context = (Context *) arg;
39*b9df5ad1SAndroid Build Coastguard Worker     for (;;) {
40*b9df5ad1SAndroid Build Coastguard Worker         struct timespec timeout;
41*b9df5ad1SAndroid Build Coastguard Worker         timeout.tv_sec = 30;
42*b9df5ad1SAndroid Build Coastguard Worker         timeout.tv_nsec = 0;
43*b9df5ad1SAndroid Build Coastguard Worker         char buffer[4];
44*b9df5ad1SAndroid Build Coastguard Worker         ssize_t actual = context->mInputReader->read(buffer, sizeof(buffer), &timeout);
45*b9df5ad1SAndroid Build Coastguard Worker         // TODO this test is unreadable
46*b9df5ad1SAndroid Build Coastguard Worker         if (actual > 0) {
47*b9df5ad1SAndroid Build Coastguard Worker             if ((size_t) actual > sizeof(buffer)) {
48*b9df5ad1SAndroid Build Coastguard Worker                 printf("input.read actual = %d\n", (int) actual);
49*b9df5ad1SAndroid Build Coastguard Worker                 abort();
50*b9df5ad1SAndroid Build Coastguard Worker             }
51*b9df5ad1SAndroid Build Coastguard Worker             ssize_t actual2 = context->mTransferWriter->write(buffer, actual, &timeout);
52*b9df5ad1SAndroid Build Coastguard Worker             if (actual2 != actual) {
53*b9df5ad1SAndroid Build Coastguard Worker                 printf("transfer.write(%d) = %d\n", (int) actual, (int) actual2);
54*b9df5ad1SAndroid Build Coastguard Worker             }
55*b9df5ad1SAndroid Build Coastguard Worker             //sleep(10);
56*b9df5ad1SAndroid Build Coastguard Worker         } else if (actual == -ETIMEDOUT) {
57*b9df5ad1SAndroid Build Coastguard Worker             (void) write(1, "t", 1);
58*b9df5ad1SAndroid Build Coastguard Worker         } else {
59*b9df5ad1SAndroid Build Coastguard Worker             printf("input.read actual = %d\n", (int) actual);
60*b9df5ad1SAndroid Build Coastguard Worker         }
61*b9df5ad1SAndroid Build Coastguard Worker     }
62*b9df5ad1SAndroid Build Coastguard Worker     return NULL;
63*b9df5ad1SAndroid Build Coastguard Worker }
64*b9df5ad1SAndroid Build Coastguard Worker 
65*b9df5ad1SAndroid Build Coastguard Worker volatile bool outputPaused = false;
66*b9df5ad1SAndroid Build Coastguard Worker 
output_routine(void * arg)67*b9df5ad1SAndroid Build Coastguard Worker void *output_routine(void *arg)
68*b9df5ad1SAndroid Build Coastguard Worker {
69*b9df5ad1SAndroid Build Coastguard Worker     Context *context = (Context *) arg;
70*b9df5ad1SAndroid Build Coastguard Worker     for (;;) {
71*b9df5ad1SAndroid Build Coastguard Worker         if (outputPaused) {
72*b9df5ad1SAndroid Build Coastguard Worker             sleep(1);
73*b9df5ad1SAndroid Build Coastguard Worker             continue;
74*b9df5ad1SAndroid Build Coastguard Worker         }
75*b9df5ad1SAndroid Build Coastguard Worker         struct timespec timeout;
76*b9df5ad1SAndroid Build Coastguard Worker         timeout.tv_sec = 60;
77*b9df5ad1SAndroid Build Coastguard Worker         timeout.tv_nsec = 0;
78*b9df5ad1SAndroid Build Coastguard Worker         char buffer[4];
79*b9df5ad1SAndroid Build Coastguard Worker         ssize_t actual = context->mTransferReader->read(buffer, sizeof(buffer), &timeout);
80*b9df5ad1SAndroid Build Coastguard Worker         if (actual > 0) {
81*b9df5ad1SAndroid Build Coastguard Worker             if ((size_t) actual > sizeof(buffer)) {
82*b9df5ad1SAndroid Build Coastguard Worker                 printf("transfer.read actual = %d\n", (int) actual);
83*b9df5ad1SAndroid Build Coastguard Worker                 abort();
84*b9df5ad1SAndroid Build Coastguard Worker             }
85*b9df5ad1SAndroid Build Coastguard Worker             ssize_t actual2 = context->mOutputWriter->write(buffer, actual, NULL /*timeout*/);
86*b9df5ad1SAndroid Build Coastguard Worker             if (actual2 != actual) {
87*b9df5ad1SAndroid Build Coastguard Worker                 printf("output.write(%d) = %d\n", (int) actual, (int) actual2);
88*b9df5ad1SAndroid Build Coastguard Worker             }
89*b9df5ad1SAndroid Build Coastguard Worker         } else if (actual == -ETIMEDOUT) {
90*b9df5ad1SAndroid Build Coastguard Worker             (void) write(1, "T", 1);
91*b9df5ad1SAndroid Build Coastguard Worker         } else {
92*b9df5ad1SAndroid Build Coastguard Worker             printf("transfer.read actual = %d\n", (int) actual);
93*b9df5ad1SAndroid Build Coastguard Worker         }
94*b9df5ad1SAndroid Build Coastguard Worker     }
95*b9df5ad1SAndroid Build Coastguard Worker     return NULL;
96*b9df5ad1SAndroid Build Coastguard Worker }
97*b9df5ad1SAndroid Build Coastguard Worker 
main(int argc,char ** argv)98*b9df5ad1SAndroid Build Coastguard Worker int main(int argc, char **argv)
99*b9df5ad1SAndroid Build Coastguard Worker {
100*b9df5ad1SAndroid Build Coastguard Worker     set_conio_terminal_mode();
101*b9df5ad1SAndroid Build Coastguard Worker     argc = argc + 0;
102*b9df5ad1SAndroid Build Coastguard Worker     argv = &argv[0];
103*b9df5ad1SAndroid Build Coastguard Worker 
104*b9df5ad1SAndroid Build Coastguard Worker     char inputBuffer[16];
105*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo inputFifo(sizeof(inputBuffer) /*frameCount*/, 1 /*frameSize*/, inputBuffer,
106*b9df5ad1SAndroid Build Coastguard Worker             true /*throttlesWriter*/);
107*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_writer inputWriter(inputFifo);
108*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_reader inputReader(inputFifo, true /*throttlesWriter*/);
109*b9df5ad1SAndroid Build Coastguard Worker     //inputWriter.setHysteresis(sizeof(inputBuffer) * 1/4, sizeof(inputBuffer) * 3/4);
110*b9df5ad1SAndroid Build Coastguard Worker 
111*b9df5ad1SAndroid Build Coastguard Worker     char transferBuffer[64];
112*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo transferFifo(sizeof(transferBuffer) /*frameCount*/, 1 /*frameSize*/,
113*b9df5ad1SAndroid Build Coastguard Worker             transferBuffer, true /*throttlesWriter*/);
114*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_writer transferWriter(transferFifo);
115*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_reader transferReader(transferFifo, true /*throttlesWriter*/);
116*b9df5ad1SAndroid Build Coastguard Worker     transferReader.setHysteresis(sizeof(transferBuffer) * 3/4, sizeof(transferBuffer) * 1/4);
117*b9df5ad1SAndroid Build Coastguard Worker     //transferWriter.setEffective(8);
118*b9df5ad1SAndroid Build Coastguard Worker 
119*b9df5ad1SAndroid Build Coastguard Worker     char outputBuffer[64];
120*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo outputFifo(sizeof(outputBuffer) /*frameCount*/, 1 /*frameSize*/, outputBuffer,
121*b9df5ad1SAndroid Build Coastguard Worker             true /*throttlesWriter*/);
122*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_writer outputWriter(outputFifo);
123*b9df5ad1SAndroid Build Coastguard Worker     audio_utils_fifo_reader outputReader(outputFifo, true /*readerThrottlesWriter*/);
124*b9df5ad1SAndroid Build Coastguard Worker 
125*b9df5ad1SAndroid Build Coastguard Worker     Context context;
126*b9df5ad1SAndroid Build Coastguard Worker     context.mInputWriter = &inputWriter;
127*b9df5ad1SAndroid Build Coastguard Worker     context.mInputReader = &inputReader;
128*b9df5ad1SAndroid Build Coastguard Worker     context.mTransferWriter = &transferWriter;
129*b9df5ad1SAndroid Build Coastguard Worker     context.mTransferReader = &transferReader;
130*b9df5ad1SAndroid Build Coastguard Worker     context.mOutputWriter = &outputWriter;
131*b9df5ad1SAndroid Build Coastguard Worker     context.mOutputReader = &outputReader;
132*b9df5ad1SAndroid Build Coastguard Worker 
133*b9df5ad1SAndroid Build Coastguard Worker     pthread_t input_thread;
134*b9df5ad1SAndroid Build Coastguard Worker     int ok = pthread_create(&input_thread, (const pthread_attr_t *) NULL, input_routine,
135*b9df5ad1SAndroid Build Coastguard Worker             (void *) &context);
136*b9df5ad1SAndroid Build Coastguard Worker     pthread_t output_thread;
137*b9df5ad1SAndroid Build Coastguard Worker     ok = pthread_create(&output_thread, (const pthread_attr_t *) NULL, output_routine,
138*b9df5ad1SAndroid Build Coastguard Worker             (void *) &context);
139*b9df5ad1SAndroid Build Coastguard Worker     ok = ok + 0;
140*b9df5ad1SAndroid Build Coastguard Worker 
141*b9df5ad1SAndroid Build Coastguard Worker     for (;;) {
142*b9df5ad1SAndroid Build Coastguard Worker         char buffer[4];
143*b9df5ad1SAndroid Build Coastguard Worker         ssize_t actual = outputReader.read(buffer, sizeof(buffer), NULL /*timeout*/);
144*b9df5ad1SAndroid Build Coastguard Worker         if (actual > 0) {
145*b9df5ad1SAndroid Build Coastguard Worker             printf("%.*s", (int) actual, buffer);
146*b9df5ad1SAndroid Build Coastguard Worker             fflush(stdout);
147*b9df5ad1SAndroid Build Coastguard Worker         } else if (actual != 0) {
148*b9df5ad1SAndroid Build Coastguard Worker             printf("outputReader.read actual = %d\n", (int) actual);
149*b9df5ad1SAndroid Build Coastguard Worker         }
150*b9df5ad1SAndroid Build Coastguard Worker         if (kbhit()) {
151*b9df5ad1SAndroid Build Coastguard Worker             int ch = getch();
152*b9df5ad1SAndroid Build Coastguard Worker             if (ch <= 0 || ch == '\003' /*control-C*/) {
153*b9df5ad1SAndroid Build Coastguard Worker                 break;
154*b9df5ad1SAndroid Build Coastguard Worker             }
155*b9df5ad1SAndroid Build Coastguard Worker             if (ch == 'p')
156*b9df5ad1SAndroid Build Coastguard Worker                 outputPaused = true;
157*b9df5ad1SAndroid Build Coastguard Worker             else if (ch == 'p')
158*b9df5ad1SAndroid Build Coastguard Worker                 outputPaused = false;
159*b9df5ad1SAndroid Build Coastguard Worker             buffer[0] = ch;
160*b9df5ad1SAndroid Build Coastguard Worker             actual = inputWriter.write(buffer, 1, NULL /*timeout*/);
161*b9df5ad1SAndroid Build Coastguard Worker             if (actual != 1) {
162*b9df5ad1SAndroid Build Coastguard Worker                 printf("inputWriter.write actual = %d\n", (int) actual);
163*b9df5ad1SAndroid Build Coastguard Worker             }
164*b9df5ad1SAndroid Build Coastguard Worker         }
165*b9df5ad1SAndroid Build Coastguard Worker     }
166*b9df5ad1SAndroid Build Coastguard Worker     reset_terminal_mode();
167*b9df5ad1SAndroid Build Coastguard Worker }
168