1 /* 2 * Copyright (C) 2017 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 "chre/platform/platform_audio.h" 18 19 #include <cinttypes> 20 21 #include "chre/core/event_loop_manager.h" 22 #include "chre/platform/fatal_error.h" 23 #include "chre/platform/log.h" 24 #include "chre/platform/system_time.h" 25 #include "chre/util/dynamic_vector.h" 26 27 namespace chre { 28 namespace { 29 30 //! The list of audio sources provided by the simulator. 31 DynamicVector<UniquePtr<AudioSource>> gAudioSources; 32 33 } // namespace 34 35 PlatformAudio::PlatformAudio() {} 36 37 PlatformAudio::~PlatformAudio() {} 38 39 void PlatformAudio::init() { 40 // TODO: Implement this. 41 } 42 43 void audioSourceCallback(void *cookie) { 44 auto *audioSource = static_cast<AudioSource *>(cookie); 45 46 auto &dataEvent = audioSource->dataEvent; 47 Nanoseconds samplingTime = 48 AudioRequestManager::getDurationFromSampleCountAndRate( 49 audioSource->numSamples, 50 static_cast<uint32_t>(audioSource->audioInfo.samplerate)); 51 dataEvent.timestamp = 52 (SystemTime::getMonotonicTime() - samplingTime).toRawNanoseconds(); 53 dataEvent.sampleCount = audioSource->numSamples; 54 55 if (dataEvent.format == CHRE_AUDIO_DATA_FORMAT_16_BIT_SIGNED_PCM) { 56 uint32_t intervalNumSamples = 57 AudioRequestManager::getSampleCountFromRateAndDuration( 58 static_cast<uint32_t>(audioSource->audioInfo.samplerate), 59 audioSource->eventDelay); 60 if (intervalNumSamples > audioSource->numSamples) { 61 sf_count_t seekAmount = intervalNumSamples - audioSource->numSamples; 62 sf_seek(audioSource->audioFile, -seekAmount, SEEK_CUR); 63 } 64 65 sf_count_t readCount = sf_read_short( 66 audioSource->audioFile, const_cast<int16_t *>(dataEvent.samplesS16), 67 static_cast<sf_count_t>(dataEvent.sampleCount)); 68 if (readCount != dataEvent.sampleCount) { 69 LOGI("TODO: File done, suspend the source"); 70 } else { 71 EventLoopManagerSingleton::get() 72 ->getAudioRequestManager() 73 .handleAudioDataEvent(&audioSource->dataEvent); 74 } 75 } else { 76 FATAL_ERROR("Unimplemented data format"); 77 } 78 } 79 80 void PlatformAudio::setHandleEnabled(uint32_t handle, bool enabled) { 81 // TODO: Implement this. 82 } 83 84 bool PlatformAudio::requestAudioDataEvent(uint32_t handle, uint32_t numSamples, 85 Nanoseconds eventDelay) { 86 LOGD("Request for audio data made for handle %" PRIu32 " with %" PRIu32 87 " samples and %" PRIu64 " delivery interval", 88 handle, numSamples, eventDelay.toRawNanoseconds()); 89 auto &source = gAudioSources[handle]; 90 source->numSamples = numSamples; 91 source->eventDelay = eventDelay; 92 return source->timer.set(audioSourceCallback, source.get(), eventDelay); 93 } 94 95 void PlatformAudio::cancelAudioDataEventRequest(uint32_t handle) { 96 LOGD("Cancelling audio request for handle %" PRIu32, handle); 97 auto &source = gAudioSources[handle]; 98 source->timer.cancel(); 99 } 100 101 void PlatformAudio::releaseAudioDataEvent(struct chreAudioDataEvent *event) { 102 // TODO(P1-41459d): Implement this API in terms of libsndfile. 103 } 104 105 size_t PlatformAudio::getSourceCount() { 106 return gAudioSources.size(); 107 } 108 109 bool PlatformAudio::getAudioSource(uint32_t handle, 110 chreAudioSource *audioSource) const { 111 bool success = (handle < gAudioSources.size()); 112 if (success) { 113 const auto &source = gAudioSources[handle]; 114 // TODO(P1-b9ff35): Ensure that name never exceeds 40 bytes in length. 115 audioSource->name = source->audioFilename.c_str(); 116 audioSource->sampleRate = 117 static_cast<uint32_t>(source->audioInfo.samplerate); 118 audioSource->minBufferDuration = 119 source->minBufferDuration.toRawNanoseconds(); 120 audioSource->maxBufferDuration = 121 source->maxBufferDuration.toRawNanoseconds(); 122 audioSource->format = source->dataEvent.format; 123 } 124 125 return success; 126 } 127 128 void PlatformAudioBase::addAudioSource(UniquePtr<AudioSource> &source) { 129 LOGI("Adding audio source - filename: %s, min buf size: %" PRIu64 130 "ms, max buf size: %" PRIu64 "ms", 131 source->audioFilename.c_str(), 132 Milliseconds(source->minBufferDuration).getMilliseconds(), 133 Milliseconds(source->maxBufferDuration).getMilliseconds()); 134 auto &audioInfo = source->audioInfo; 135 source->audioFile = 136 sf_open(source->audioFilename.c_str(), SFM_READ, &audioInfo); 137 auto sampleCount = AudioRequestManager::getSampleCountFromRateAndDuration( 138 static_cast<uint32_t>(source->audioInfo.samplerate), 139 source->maxBufferDuration); 140 if (source->audioFile == nullptr) { 141 FATAL_ERROR("Failed to open provided audio file %s", 142 source->audioFilename.c_str()); 143 } else if ((audioInfo.format & SF_FORMAT_ULAW) == SF_FORMAT_ULAW) { 144 source->dataEvent.format = CHRE_AUDIO_DATA_FORMAT_8_BIT_U_LAW; 145 source->dataEvent.samplesULaw8 = 146 static_cast<uint8_t *>(malloc(sizeof(uint8_t) * sampleCount)); 147 } else if ((audioInfo.format & SF_FORMAT_PCM_16) == SF_FORMAT_PCM_16) { 148 source->dataEvent.format = CHRE_AUDIO_DATA_FORMAT_16_BIT_SIGNED_PCM; 149 source->dataEvent.samplesS16 = 150 static_cast<int16_t *>(malloc(sizeof(uint16_t) * sampleCount)); 151 } else { 152 FATAL_ERROR("Invalid format 0x%08x", audioInfo.format); 153 } 154 155 source->dataEvent.version = CHRE_AUDIO_DATA_EVENT_VERSION; 156 memset(source->dataEvent.reserved, 0, sizeof(source->dataEvent.reserved)); 157 source->dataEvent.handle = static_cast<uint32_t>(gAudioSources.size()); 158 source->dataEvent.sampleRate = 159 static_cast<uint32_t>(source->audioInfo.samplerate); 160 gAudioSources.push_back(std::move(source)); 161 } 162 163 } // namespace chre 164