audioloop.cpp revision f4b0e603d3e27728ca19c02a44342607a54db7d4
1/* 2 * Copyright (C) 2014 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 <binder/ProcessState.h> 18#include <media/mediarecorder.h> 19#include <media/stagefright/foundation/ADebug.h> 20#include <media/stagefright/AMRWriter.h> 21#include <media/stagefright/AudioPlayer.h> 22#include <media/stagefright/AudioSource.h> 23#include <media/stagefright/MediaDefs.h> 24#include <media/stagefright/MetaData.h> 25#include <media/stagefright/OMXClient.h> 26#include <media/stagefright/OMXCodec.h> 27#include "SineSource.h" 28 29using namespace android; 30 31static void usage(const char* name) 32{ 33 fprintf(stderr, "Usage: %s [-d duration] [-m] [-w] [<output-file>]\n", name); 34 fprintf(stderr, "Encodes either a sine wave or microphone input to AMR format\n"); 35 fprintf(stderr, " -d duration in seconds, default 5 seconds\n"); 36 fprintf(stderr, " -m use microphone for input, default sine source\n"); 37 fprintf(stderr, " -w use AMR wideband (default narrowband)\n"); 38 fprintf(stderr, " <output-file> output file for AMR encoding," 39 " if unspecified, decode to speaker.\n"); 40} 41 42int main(int argc, char* argv[]) 43{ 44 static const int channels = 1; // not permitted to be stereo now 45 unsigned duration = 5; 46 bool useMic = false; 47 bool outputWBAMR = false; 48 bool playToSpeaker = true; 49 const char* fileOut = NULL; 50 int ch; 51 while ((ch = getopt(argc, argv, "d:mw")) != -1) { 52 switch (ch) { 53 case 'd': 54 duration = atoi(optarg); 55 break; 56 case 'm': 57 useMic = true; 58 break; 59 case 'w': 60 outputWBAMR = true; 61 break; 62 default: 63 usage(argv[0]); 64 return -1; 65 } 66 } 67 argc -= optind; 68 argv += optind; 69 if (argc == 1) { 70 fileOut = argv[0]; 71 } 72 const int32_t kSampleRate = outputWBAMR ? 16000 : 8000; 73 const int32_t kBitRate = outputWBAMR ? 16000 : 8000; 74 75 android::ProcessState::self()->startThreadPool(); 76 OMXClient client; 77 CHECK_EQ(client.connect(), (status_t)OK); 78 sp<MediaSource> source; 79 80 if (useMic) { 81 // talk into the appropriate microphone for the duration 82 source = new AudioSource( 83 AUDIO_SOURCE_MIC, 84 kSampleRate, 85 channels); 86 } else { 87 // use a sine source at 500 hz. 88 source = new SineSource(kSampleRate, channels); 89 } 90 91 sp<MetaData> meta = new MetaData; 92 meta->setCString( 93 kKeyMIMEType, 94 outputWBAMR ? MEDIA_MIMETYPE_AUDIO_AMR_WB 95 : MEDIA_MIMETYPE_AUDIO_AMR_NB); 96 97 meta->setInt32(kKeyChannelCount, channels); 98 meta->setInt32(kKeySampleRate, kSampleRate); 99 meta->setInt32(kKeyBitRate, kBitRate); 100 int32_t maxInputSize; 101 if (source->getFormat()->findInt32(kKeyMaxInputSize, &maxInputSize)) { 102 meta->setInt32(kKeyMaxInputSize, maxInputSize); 103 } 104 105 sp<MediaSource> encoder = OMXCodec::Create( 106 client.interface(), 107 meta, true /* createEncoder */, 108 source); 109 110 if (fileOut != NULL) { 111 // target file specified, write encoded AMR output 112 sp<AMRWriter> writer = new AMRWriter(fileOut); 113 writer->addSource(encoder); 114 writer->start(); 115 sleep(duration); 116 writer->stop(); 117 } else { 118 // otherwise decode to speaker 119 sp<MediaSource> decoder = OMXCodec::Create( 120 client.interface(), 121 meta, false /* createEncoder */, 122 encoder); 123 124 if (playToSpeaker) { 125 AudioPlayer *player = new AudioPlayer(NULL); 126 player->setSource(decoder); 127 player->start(); 128 sleep(duration); 129 source->stop(); // must stop source otherwise delete player will hang 130 delete player; // there is no player->stop()... 131 } else { 132 CHECK_EQ(decoder->start(), (status_t)OK); 133 MediaBuffer* buffer; 134 while (decoder->read(&buffer) == OK) { 135 // do something with buffer (save it eventually?) 136 // need to stop after some count though... 137 putchar('.'); 138 fflush(stdout); 139 buffer->release(); 140 buffer = NULL; 141 } 142 CHECK_EQ(decoder->stop(), (status_t)OK); 143 } 144 } 145 146 return 0; 147} 148