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