fifo_threads.cpp revision 3ddacbbcd6c119d3c47a50a9291fdff91fb98386
13ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten/* 23ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * Copyright (C) 2016 The Android Open Source Project 33ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * 43ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 53ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * you may not use this file except in compliance with the License. 63ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * You may obtain a copy of the License at 73ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * 83ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 93ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * 103ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * Unless required by applicable law or agreed to in writing, software 113ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 123ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * See the License for the specific language governing permissions and 143ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten * limitations under the License. 153ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten */ 163ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 173ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten#include <pthread.h> 183ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten#include <stdio.h> 193ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten#include <unistd.h> 203ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten#include <audio_utils/fifo.h> 213ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kastenextern "C" { 223ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten#include "getch.h" 233ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten} 243ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 253ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kastenstruct Context { 263ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_writer *mInputWriter; 273ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_reader *mInputReader; 283ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_writer *mTransferWriter; 293ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_reader *mTransferReader; 303ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_writer *mOutputWriter; 313ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_reader *mOutputReader; 323ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten}; 333ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 343ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kastenvoid *input_routine(void *arg) 353ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten{ 363ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten Context *context = (Context *) arg; 373ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten for (;;) { 383ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten struct timespec timeout; 393ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten timeout.tv_sec = 3; 403ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten timeout.tv_nsec = 0; 413ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten char buffer[4]; 423ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten ssize_t actual = context->mInputReader->read(buffer, sizeof(buffer), &timeout); 433ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten if (actual == 0) { 443ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten (void) write(1, "t", 1); 453ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } else if (actual > 0) { 463ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten actual = context->mTransferWriter->write(buffer, actual, &timeout); 473ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten //printf("transfer.write actual = %d\n", (int) actual); 483ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } else { 493ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten printf("input.read actual = %d\n", (int) actual); 503ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } 513ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } 523ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten return NULL; 533ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten} 543ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 553ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kastenvoid *output_routine(void *arg) 563ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten{ 573ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten Context *context = (Context *) arg; 583ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten for (;;) { 593ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten struct timespec timeout; 603ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten timeout.tv_sec = 5; 613ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten timeout.tv_nsec = 0; 623ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten char buffer[4]; 633ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten ssize_t actual = context->mTransferReader->read(buffer, sizeof(buffer), &timeout); 643ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten if (actual == 0) { 653ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten (void) write(1, "T", 1); 663ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } else if (actual > 0) { 673ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten actual = context->mOutputWriter->write(buffer, actual, &timeout); 683ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten //printf("output.write actual = %d\n", (int) actual); 693ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } else { 703ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten printf("transfer.read actual = %d\n", (int) actual); 713ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } 723ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } 733ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten return NULL; 743ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten} 753ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 763ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kastenint main(int argc, char **argv) 773ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten{ 783ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten set_conio_terminal_mode(); 793ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten argc = argc + 0; 803ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten argv = &argv[0]; 813ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 823ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten char inputBuffer[64]; 833ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo inputFifo(sizeof(inputBuffer) /*frameCount*/, 1 /*frameSize*/, inputBuffer); 843ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_writer inputWriter(inputFifo); 853ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_reader inputReader(inputFifo, true /*readerThrottlesWriter*/); 863ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten inputWriter.setHighLevelTrigger(3); 873ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 883ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten char transferBuffer[64]; 893ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo transferFifo(sizeof(transferBuffer) /*frameCount*/, 1 /*frameSize*/, 903ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten transferBuffer); 913ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_writer transferWriter(transferFifo); 923ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_reader transferReader(transferFifo, true /*readerThrottlesWriter*/); 933ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten transferWriter.setEffectiveFrames(2); 943ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 953ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten char outputBuffer[64]; 963ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo outputFifo(sizeof(outputBuffer) /*frameCount*/, 1 /*frameSize*/, outputBuffer); 973ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_writer outputWriter(outputFifo); 983ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten audio_utils_fifo_reader outputReader(outputFifo, true /*readerThrottlesWriter*/); 993ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 1003ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten Context context; 1013ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten context.mInputWriter = &inputWriter; 1023ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten context.mInputReader = &inputReader; 1033ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten context.mTransferWriter = &transferWriter; 1043ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten context.mTransferReader = &transferReader; 1053ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten context.mOutputWriter = &outputWriter; 1063ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten context.mOutputReader = &outputReader; 1073ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 1083ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten pthread_t input_thread; 1093ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten int ok = pthread_create(&input_thread, (const pthread_attr_t *) NULL, input_routine, 1103ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten (void *) &context); 1113ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten pthread_t output_thread; 1123ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten ok = pthread_create(&output_thread, (const pthread_attr_t *) NULL, output_routine, 1133ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten (void *) &context); 1143ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten ok = ok + 0; 1153ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten 1163ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten for (;;) { 1173ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten char buffer[1]; 1183ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten struct timespec timeout; 1193ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten timeout.tv_sec = 0; 1203ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten timeout.tv_nsec = 0; 1213ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten ssize_t actual = outputReader.read(buffer, sizeof(buffer), &timeout); 1223ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten if (actual == 1) { 1233ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten printf("%c", buffer[0]); 1243ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten fflush(stdout); 1253ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } else if (actual != 0) { 1263ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten printf("outputReader.read actual = %d\n", (int) actual); 1273ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } 1283ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten if (kbhit()) { 1293ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten int ch = getch(); 1303ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten if (ch <= 0 || ch == 3) { 1313ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten break; 1323ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } 1333ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten buffer[0] = ch; 1343ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten actual = inputWriter.write(buffer, sizeof(buffer), &timeout); 1353ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten if (actual != 1) { 1363ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten printf("inputWriter.write actual = %d\n", (int) actual); 1373ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } 1383ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } 1393ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten } 1403ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten reset_terminal_mode(); 1413ddacbbcd6c119d3c47a50a9291fdff91fb98386Glenn Kasten} 142