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