Lines Matching full:patch
112 /* Connect a patch between several source and sink ports */
113 status_t PatchPanel::createAudioPatch_l(const struct audio_patch* patch, in createAudioPatch_l() argument
118 //before processing the create patch request. in createAudioPatch_l()
121 if (handle == NULL || patch == NULL) { in createAudioPatch_l()
125 __func__, patch->num_sources, patch->num_sinks, *handle); in createAudioPatch_l()
129 if (!audio_patch_is_valid(patch) || (patch->num_sinks == 0 && patch->num_sources != 2)) { in createAudioPatch_l()
133 // only the audio policy manager can request a patch creation with 2 sources. in createAudioPatch_l()
134 if (patch->num_sources > 2) { in createAudioPatch_l()
142 ALOGV("%s() removing patch handle %d", __func__, *handle); in createAudioPatch_l()
143 Patch &removedPatch = iter->second; in createAudioPatch_l()
144 // free resources owned by the removed patch if applicable in createAudioPatch_l()
145 // 1) if a software patch is present, release the playback and capture threads and in createAudioPatch_l()
150 // 2) if the new patch and old patch source or sink are devices from different in createAudioPatch_l()
158 (patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE || in createAudioPatch_l()
160 patch->sources[0].ext.device.hw_module)) { in createAudioPatch_l()
162 } else if (patch->num_sinks == 0 || in createAudioPatch_l()
164 (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE || in createAudioPatch_l()
166 patch->sinks[0].ext.device.hw_module))) { in createAudioPatch_l()
167 // Note on (patch->num_sinks == 0): this situation should not happen as in createAudioPatch_l()
169 // in case, systematically clear the HAL patch. in createAudioPatch_l()
180 // hal patch has not been released in createAudioPatch_l()
181 // Note that no patch leak at hal layer as halHandle is reused. in createAudioPatch_l()
182 reuseExistingHalPatch = (hwDevice == 0) && patchesHaveSameRoute(*patch, oldPatch); in createAudioPatch_l()
188 Patch newPatch{*patch, endpointPatch}; in createAudioPatch_l()
191 switch (patch->sources[0].type) { in createAudioPatch_l()
193 audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module; in createAudioPatch_l()
199 for (unsigned int i = 0; i < patch->num_sinks; i++) { in createAudioPatch_l()
201 if ((patch->sinks[i].type == AUDIO_PORT_TYPE_MIX || in createAudioPatch_l()
202 (patch->sinks[i].type == AUDIO_PORT_TYPE_DEVICE && in createAudioPatch_l()
203 patch->sinks[i].ext.device.hw_module != srcModule)) && in createAudioPatch_l()
204 patch->num_sinks > 1) { in createAudioPatch_l()
210 if (patch->sinks[i].type != patch->sinks[0].type) { in createAudioPatch_l()
211 ALOGW("%s() different sink types in same patch not supported", __func__); in createAudioPatch_l()
218 // - special patch request with 2 sources (reuse one existing output mix) OR in createAudioPatch_l()
222 if ((patch->num_sources == 2) || in createAudioPatch_l()
223 ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) && in createAudioPatch_l()
224 ((patch->sinks[0].ext.device.hw_module != srcModule) || in createAudioPatch_l()
226 audio_devices_t outputDevice = patch->sinks[0].ext.device.type; in createAudioPatch_l()
227 String8 outputDeviceAddress = String8(patch->sinks[0].ext.device.address); in createAudioPatch_l()
228 if (patch->num_sources == 2) { in createAudioPatch_l()
229 if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX || in createAudioPatch_l()
230 (patch->num_sinks != 0 && patch->sinks[0].ext.device.hw_module != in createAudioPatch_l()
231 patch->sources[1].ext.mix.hw_module)) { in createAudioPatch_l()
237 patch->sources[1].ext.mix.handle); in createAudioPatch_l()
243 // existing playback thread is reused, so it is not closed when patch is cleared in createAudioPatch_l()
251 if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { in createAudioPatch_l()
252 config.sample_rate = patch->sinks[0].sample_rate; in createAudioPatch_l()
254 if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { in createAudioPatch_l()
255 config.channel_mask = patch->sinks[0].channel_mask; in createAudioPatch_l()
257 if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) { in createAudioPatch_l()
258 config.format = patch->sinks[0].format; in createAudioPatch_l()
260 if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) { in createAudioPatch_l()
261 flags = patch->sinks[0].flags.output; in createAudioPatch_l()
265 patch->sinks[0].ext.device.hw_module, in createAudioPatch_l()
280 audio_devices_t device = patch->sources[0].ext.device.type; in createAudioPatch_l()
281 String8 address = String8(patch->sources[0].ext.device.address); in createAudioPatch_l()
285 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { in createAudioPatch_l()
286 config.sample_rate = patch->sources[0].sample_rate; in createAudioPatch_l()
290 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { in createAudioPatch_l()
291 config.channel_mask = patch->sources[0].channel_mask; in createAudioPatch_l()
296 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) { in createAudioPatch_l()
297 config.format = patch->sources[0].format; in createAudioPatch_l()
302 patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ? in createAudioPatch_l()
303 patch->sources[0].flags.input : AUDIO_INPUT_FLAG_NONE; in createAudioPatch_l()
307 if (patch->num_sources == 2 in createAudioPatch_l()
308 && patch->sources[1].ext.mix.usecase.stream in createAudioPatch_l()
336 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { in createAudioPatch_l()
338 patch->sinks[0].ext.mix.handle); in createAudioPatch_l()
341 patch->sinks[0].ext.mix.handle); in createAudioPatch_l()
344 __func__, patch->sinks[0].ext.mix.handle); in createAudioPatch_l()
350 status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle); in createAudioPatch_l()
355 // remove stale audio patch with same input as sink if any in createAudioPatch_l()
364 status = hwDevice->createAudioPatch(patch->num_sources, in createAudioPatch_l()
365 patch->sources, in createAudioPatch_l()
366 patch->num_sinks, in createAudioPatch_l()
367 patch->sinks, in createAudioPatch_l()
374 audio_module_handle_t srcModule = patch->sources[0].ext.mix.hw_module; in createAudioPatch_l()
383 for (unsigned int i = 0; i < patch->num_sinks; i++) { in createAudioPatch_l()
384 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) { in createAudioPatch_l()
386 __func__, patch->sinks[i].type); in createAudioPatch_l()
391 if (patch->sinks[i].ext.device.hw_module != srcModule) { in createAudioPatch_l()
396 patch->sinks[i].ext.device.type); in createAudioPatch_l()
397 device->setAddress(patch->sinks[i].ext.device.address); in createAudioPatch_l()
398 device->applyAudioPortConfig(&patch->sinks[i]); in createAudioPatch_l()
402 patch->sources[0].ext.mix.handle); in createAudioPatch_l()
405 patch->sources[0].ext.mix.handle); in createAudioPatch_l()
408 __func__, patch->sources[0].ext.mix.handle); in createAudioPatch_l()
418 // if the same HAL patch is reused (see calls to mAfPatchPanelCallback below) in createAudioPatch_l()
421 // end point patches are skipped so we do not compare against this patch in createAudioPatch_l()
434 status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle); in createAudioPatch_l()
440 // remove stale audio patch with same output as source if any in createAudioPatch_l()
504 PatchPanel::Patch::~Patch() in ~Patch()
506 ALOGE_IF(isSoftware(), "Software patch connections leaked %d %d", in ~Patch()
510 status_t PatchPanel::Patch::createConnections_l(const sp<IAfPatchPanel>& panel) in createConnections_l()
512 // create patch from source device to record thread input in createConnections_l()
515 addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(), in createConnections_l()
523 // create patch from playback thread output to sink device in createConnections_l()
526 PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(), in createConnections_l()
677 void PatchPanel::Patch::clearConnections_l(const sp<IAfPatchPanel>& panel) in clearConnections_l()
688 status_t PatchPanel::Patch::getLatencyMs(double* latencyMs) const in getLatencyMs()
718 // the total patch latency. This requires that frame counts are reported by the in getLatencyMs()
727 // It is possible that the patch track and patch record have a large time disparity because in getLatencyMs()
732 // If the timestamps aren't sampled close enough, the patch latency is not in getLatencyMs()
747 String8 PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const in dump()
750 String8 result = String8::format("Patch %d: %s (thread %p => thread %p)", in dump()
774 /* Disconnect a patch */
778 //before processing the release patch request. in releaseAudioPatch_l()
789 Patch &removedPatch = iter->second; in releaseAudioPatch_l()
791 const struct audio_patch &patch = removedPatch.mAudioPatch; in releaseAudioPatch_l() local
793 const struct audio_port_config &src = patch.sources[0]; in releaseAudioPatch_l()
808 if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) { in releaseAudioPatch_l()
809 audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle; in releaseAudioPatch_l()
842 // Check whether the removed patch Hal Handle is used in another non-Endpoint patch. in releaseAudioPatch_l()
843 // Since this is a non-Endpoint patch, the removed patch is not considered (it is in releaseAudioPatch_l()
895 const Patch &patch = patch_iter->second; in getDownstreamSoftwarePatches() local
898 patch.mPlayback.const_thread()->id(), in getDownstreamSoftwarePatches()
899 patch.mRecord.const_thread()->id()); in getDownstreamSoftwarePatches()
901 ALOGE("Stale patch handle in the cache: %d", patchHandle); in getDownstreamSoftwarePatches()
912 AudioHwDevice *audioHwDevice, audio_io_handle_t stream, struct audio_patch *patch) in notifyStreamOpened() argument
916 if (patch != nullptr) { in notifyStreamOpened()
922 *patch = iter->second.mAudioPatch; in notifyStreamOpened()
955 const struct audio_patch *patch) in addSoftwarePatchToInsertedModules_l() argument
959 mAfPatchPanelCallback->updateDownStreamPatches_l(patch, mInsertedModules[module].streams); in addSoftwarePatchToInsertedModules_l()
997 for (const auto& patch : module.second.sw_patches) { in dump() local
998 moduleDump.appendFormat("%d ", patch); in dump()