1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 #include <stdint.h> 17 #include <iostream> 18 #include <fstream> 19 #include <utils/String8.h> 20 #include "Log.h" 21 #include "StringUtil.h" 22 #include "audio/Buffer.h" 23 24 Buffer::Buffer(size_t capacity, size_t size, bool stereo) 25 : mCapacity(capacity), 26 mSize(size), 27 mHandled(0), 28 mStereo(stereo) 29 { 30 mData = new char[capacity]; 31 //LOGV("Buffer %d data %x", capacity, (unsigned int)mData); 32 // assume 4bytes alignment 33 ASSERT(((long)mData & 0x3) == 0); 34 // filling with zero just to make valgrind happy. 35 // Otherwise, valgrind will complain about uninitialized data for all captured data 36 memset(mData, capacity, 0); 37 }; 38 39 Buffer::~Buffer() 40 { 41 delete[] mData; 42 //LOGV("~Buffer %d", mCapacity); 43 } 44 45 void Buffer::changeToMono(ConvertOption option) 46 { 47 size_t newSize = mSize/2; 48 int16_t* data = reinterpret_cast<int16_t*>(mData); 49 if (option == EKeepCh0) { 50 for (size_t i = 0; i < newSize/2; i++) { //16bpp only 51 int16_t l = data[i * 2]; 52 data[i] = l; 53 } 54 } else if (option == EKeepCh1) { 55 for (size_t i = 0; i < newSize/2; i++) { //16bpp only 56 int16_t r = data[i * 2 + 1]; 57 data[i] = r; 58 } 59 } else { // average 60 for (size_t i = 0; i < newSize/2; i++) { //16bpp only 61 int16_t l = data[i * 2]; 62 int16_t r = data[i * 2 + 1]; 63 int16_t avr = (int16_t)(((int32_t)l + (int32_t)r)/2); 64 data[i] = avr; 65 } 66 } 67 mSize = newSize; 68 mHandled /= 2; 69 mStereo = false; 70 } 71 72 bool Buffer::changeToStereo() 73 { 74 //TODO ChangeToStereo 75 return false; 76 } 77 78 const char* EXTENSION_S16_STEREO = ".r2s"; 79 const char* EXTENSION_S16_MONO = ".r2m"; 80 Buffer* Buffer::loadFromFile(const android::String8& filename) 81 { 82 bool stereo; 83 if (StringUtil::endsWith(filename, EXTENSION_S16_STEREO)) { 84 stereo = true; 85 } else if (StringUtil::endsWith(filename, EXTENSION_S16_MONO)) { 86 stereo = false; 87 } else { 88 LOGE("Buffer::loadFromFile specified file %s has unknown extension.", filename.string()); 89 return NULL; 90 } 91 std::ifstream file(filename.string(), std::ios::in | std::ios::binary | 92 std::ios::ate); 93 if (!file.is_open()) { 94 LOGE("Buffer::loadFromFile cannot open file %s.", filename.string()); 95 return NULL; 96 } 97 size_t size = file.tellg(); 98 Buffer* buffer = new Buffer(size, size, stereo); 99 if (buffer == NULL) { 100 return NULL; 101 } 102 file.seekg(0, std::ios::beg); 103 file.read(buffer->mData, size); //TODO handle read error 104 file.close(); 105 return buffer; 106 } 107 108 bool Buffer::saveToFile(const android::String8& filename) 109 { 110 android::String8 filenameWithExtension(filename); 111 if (isStereo()) { 112 filenameWithExtension.append(EXTENSION_S16_STEREO); 113 } else { 114 filenameWithExtension.append(EXTENSION_S16_MONO); 115 } 116 std::ofstream file(filenameWithExtension.string(), std::ios::out | std::ios::binary | 117 std::ios::trunc); 118 if (!file.is_open()) { 119 LOGE("Buffer::saveToFile cannot create file %s.", 120 filenameWithExtension.string()); 121 return false; 122 } 123 file.write(mData, mSize); 124 bool writeOK = true; 125 if (file.rdstate() != std::ios_base::goodbit) { 126 LOGE("Got error while writing file %s %x", filenameWithExtension.string(), file.rdstate()); 127 writeOK = false; 128 } 129 file.close(); 130 return writeOK; 131 } 132 133 bool Buffer::operator == (const Buffer& b) const 134 { 135 if (mStereo != b.mStereo) { 136 LOGD("stereo mismatch %d %d", mStereo, b.mStereo); 137 return false; 138 } 139 if (mSize != b.mSize) { 140 LOGD("size mismatch %d %d", mSize, b.mSize); 141 return false; 142 } 143 for (size_t i = 0; i < mSize; i++) { 144 if (mData[i] != b.mData[i]) { 145 LOGD("%d %x vs %x", i, mData[i], b.mData[i]); 146 return false; 147 } 148 } 149 return true; 150 } 151