1 /* 2 * Copyright 2015 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 #ifndef OBOE_STREAM_BUILDER_H_ 18 #define OBOE_STREAM_BUILDER_H_ 19 20 #include "oboe/Definitions.h" 21 #include "oboe/AudioStreamBase.h" 22 #include "oboe/Utilities.h" 23 #include "ResultWithValue.h" 24 25 namespace oboe { 26 27 // This depends on AudioStream, so we use forward declaration, it will close and delete the stream 28 struct StreamDeleterFunctor; 29 using ManagedStream = std::unique_ptr<AudioStream, StreamDeleterFunctor>; 30 31 /** 32 * Factory class for an audio Stream. 33 */ 34 class AudioStreamBuilder : public AudioStreamBase { 35 public: 36 AudioStreamBuilder()37 AudioStreamBuilder() : AudioStreamBase() {} 38 AudioStreamBuilder(const AudioStreamBase & audioStreamBase)39 AudioStreamBuilder(const AudioStreamBase &audioStreamBase): AudioStreamBase(audioStreamBase) {} 40 41 /** 42 * Request a specific number of channels. 43 * 44 * Default is kUnspecified. If the value is unspecified then 45 * the application should query for the actual value after the stream is opened. 46 * 47 * As the channel count here may be different from the corresponding channel count of 48 * provided channel mask used in setChannelMask(). The last called will be respected 49 * if this function and setChannelMask() are called. 50 */ setChannelCount(int channelCount)51 AudioStreamBuilder *setChannelCount(int channelCount) { 52 mChannelCount = channelCount; 53 mChannelMask = ChannelMask::Unspecified; 54 return this; 55 } 56 57 /** 58 * Request a specific channel mask. 59 * 60 * Default is kUnspecified. If the value is unspecified then the application 61 * should query for the actual value after the stream is opened. 62 * 63 * As the corresponding channel count of provided channel mask here may be different 64 * from the channel count used in setChannelCount(). The last called will be respected 65 * if this function and setChannelCount() are called. 66 * 67 * As the setChannelMask API is available on Android 32+, this call will only take effects 68 * on Android 32+. 69 */ setChannelMask(ChannelMask channelMask)70 AudioStreamBuilder *setChannelMask(ChannelMask channelMask) { 71 mChannelMask = channelMask; 72 mChannelCount = getChannelCountFromChannelMask(channelMask); 73 return this; 74 } 75 76 /** 77 * Request the direction for a stream. The default is Direction::Output. 78 * 79 * @param direction Direction::Output or Direction::Input 80 */ setDirection(Direction direction)81 AudioStreamBuilder *setDirection(Direction direction) { 82 mDirection = direction; 83 return this; 84 } 85 86 /** 87 * Request a specific sample rate in Hz. 88 * 89 * Default is kUnspecified. If the value is unspecified then 90 * the application should query for the actual value after the stream is opened. 91 * 92 * Technically, this should be called the "frame rate" or "frames per second", 93 * because it refers to the number of complete frames transferred per second. 94 * But it is traditionally called "sample rate". Se we use that term. 95 * 96 */ setSampleRate(int32_t sampleRate)97 AudioStreamBuilder *setSampleRate(int32_t sampleRate) { 98 mSampleRate = sampleRate; 99 return this; 100 } 101 102 /** 103 * @deprecated use `setFramesPerDataCallback` instead. 104 */ setFramesPerCallback(int framesPerCallback)105 AudioStreamBuilder *setFramesPerCallback(int framesPerCallback) { 106 return setFramesPerDataCallback(framesPerCallback); 107 } 108 109 /** 110 * Request a specific number of frames for the data callback. 111 * 112 * Default is kUnspecified. If the value is unspecified then 113 * the actual number may vary from callback to callback. 114 * 115 * If an application can handle a varying number of frames then we recommend 116 * leaving this unspecified. This allow the underlying API to optimize 117 * the callbacks. But if your application is, for example, doing FFTs or other block 118 * oriented operations, then call this function to get the sizes you need. 119 * 120 * Calling setFramesPerDataCallback() does not guarantee anything about timing. 121 * This just collects the data into a the number of frames that your app requires. 122 * We encourage leaving this unspecified in most cases. 123 * 124 * If this number is larger than the burst size, some bursts will not receive a callback. 125 * If this number is smaller than the burst size, there may be multiple callbacks in a single 126 * burst. 127 * 128 * @param framesPerCallback 129 * @return pointer to the builder so calls can be chained 130 */ setFramesPerDataCallback(int framesPerCallback)131 AudioStreamBuilder *setFramesPerDataCallback(int framesPerCallback) { 132 mFramesPerCallback = framesPerCallback; 133 return this; 134 } 135 136 /** 137 * Request a sample data format, for example Format::Float. 138 * 139 * Default is Format::Unspecified. If the value is unspecified then 140 * the application should query for the actual value after the stream is opened. 141 */ setFormat(AudioFormat format)142 AudioStreamBuilder *setFormat(AudioFormat format) { 143 mFormat = format; 144 return this; 145 } 146 147 /** 148 * Set the requested buffer capacity in frames. 149 * BufferCapacityInFrames is the maximum possible BufferSizeInFrames. 150 * 151 * The final stream capacity may differ. For AAudio it should be at least this big. 152 * For OpenSL ES, it could be smaller. 153 * 154 * Default is kUnspecified. 155 * 156 * @param bufferCapacityInFrames the desired buffer capacity in frames or kUnspecified 157 * @return pointer to the builder so calls can be chained 158 */ setBufferCapacityInFrames(int32_t bufferCapacityInFrames)159 AudioStreamBuilder *setBufferCapacityInFrames(int32_t bufferCapacityInFrames) { 160 mBufferCapacityInFrames = bufferCapacityInFrames; 161 return this; 162 } 163 164 /** 165 * Get the audio API which will be requested when opening the stream. No guarantees that this is 166 * the API which will actually be used. Query the stream itself to find out the API which is 167 * being used. 168 * 169 * If you do not specify the API, then AAudio will be used if isAAudioRecommended() 170 * returns true. Otherwise OpenSL ES will be used. 171 * 172 * @return the requested audio API 173 */ getAudioApi()174 AudioApi getAudioApi() const { return mAudioApi; } 175 176 /** 177 * If you leave this unspecified then Oboe will choose the best API 178 * for the device and SDK version at runtime. 179 * 180 * This should almost always be left unspecified, except for debugging purposes. 181 * Specifying AAudio will force Oboe to use AAudio on 8.0, which is extremely risky. 182 * Specifying OpenSLES should mainly be used to test legacy performance/functionality. 183 * 184 * If the caller requests AAudio and it is supported then AAudio will be used. 185 * 186 * @param audioApi Must be AudioApi::Unspecified, AudioApi::OpenSLES or AudioApi::AAudio. 187 * @return pointer to the builder so calls can be chained 188 */ setAudioApi(AudioApi audioApi)189 AudioStreamBuilder *setAudioApi(AudioApi audioApi) { 190 mAudioApi = audioApi; 191 return this; 192 } 193 194 /** 195 * Is the AAudio API supported on this device? 196 * 197 * AAudio was introduced in the Oreo 8.0 release. 198 * 199 * @return true if supported 200 */ 201 static bool isAAudioSupported(); 202 203 /** 204 * Is the AAudio API recommended this device? 205 * 206 * AAudio may be supported but not recommended because of version specific issues. 207 * AAudio is not recommended for Android 8.0 or earlier versions. 208 * 209 * @return true if recommended 210 */ 211 static bool isAAudioRecommended(); 212 213 /** 214 * Request a mode for sharing the device. 215 * The requested sharing mode may not be available. 216 * So the application should query for the actual mode after the stream is opened. 217 * 218 * @param sharingMode SharingMode::Shared or SharingMode::Exclusive 219 * @return pointer to the builder so calls can be chained 220 */ setSharingMode(SharingMode sharingMode)221 AudioStreamBuilder *setSharingMode(SharingMode sharingMode) { 222 mSharingMode = sharingMode; 223 return this; 224 } 225 226 /** 227 * Request a performance level for the stream. 228 * This will determine the latency, the power consumption, and the level of 229 * protection from glitches. 230 * 231 * @param performanceMode for example, PerformanceMode::LowLatency 232 * @return pointer to the builder so calls can be chained 233 */ setPerformanceMode(PerformanceMode performanceMode)234 AudioStreamBuilder *setPerformanceMode(PerformanceMode performanceMode) { 235 mPerformanceMode = performanceMode; 236 return this; 237 } 238 239 240 /** 241 * Set the intended use case for an output stream. 242 * 243 * The system will use this information to optimize the behavior of the stream. 244 * This could, for example, affect how volume and focus is handled for the stream. 245 * The usage is ignored for input streams. 246 * 247 * The default, if you do not call this function, is Usage::Media. 248 * 249 * Added in API level 28. 250 * 251 * @param usage the desired usage, eg. Usage::Game 252 */ setUsage(Usage usage)253 AudioStreamBuilder *setUsage(Usage usage) { 254 mUsage = usage; 255 return this; 256 } 257 258 /** 259 * Set the type of audio data that an output stream will carry. 260 * 261 * The system will use this information to optimize the behavior of the stream. 262 * This could, for example, affect whether a stream is paused when a notification occurs. 263 * The contentType is ignored for input streams. 264 * 265 * The default, if you do not call this function, is ContentType::Music. 266 * 267 * Added in API level 28. 268 * 269 * @param contentType the type of audio data, eg. ContentType::Speech 270 */ setContentType(ContentType contentType)271 AudioStreamBuilder *setContentType(ContentType contentType) { 272 mContentType = contentType; 273 return this; 274 } 275 276 /** 277 * Set the input (capture) preset for the stream. 278 * 279 * The system will use this information to optimize the behavior of the stream. 280 * This could, for example, affect which microphones are used and how the 281 * recorded data is processed. 282 * 283 * The default, if you do not call this function, is InputPreset::VoiceRecognition. 284 * That is because VoiceRecognition is the preset with the lowest latency 285 * on many platforms. 286 * 287 * Added in API level 28. 288 * 289 * @param inputPreset the desired configuration for recording 290 */ setInputPreset(InputPreset inputPreset)291 AudioStreamBuilder *setInputPreset(InputPreset inputPreset) { 292 mInputPreset = inputPreset; 293 return this; 294 } 295 296 /** Set the requested session ID. 297 * 298 * The session ID can be used to associate a stream with effects processors. 299 * The effects are controlled using the Android AudioEffect Java API. 300 * 301 * The default, if you do not call this function, is SessionId::None. 302 * 303 * If set to SessionId::Allocate then a session ID will be allocated 304 * when the stream is opened. 305 * 306 * The allocated session ID can be obtained by calling AudioStream::getSessionId() 307 * and then used with this function when opening another stream. 308 * This allows effects to be shared between streams. 309 * 310 * Session IDs from Oboe can be used the Android Java APIs and vice versa. 311 * So a session ID from an Oboe stream can be passed to Java 312 * and effects applied using the Java AudioEffect API. 313 * 314 * Allocated session IDs will always be positive and nonzero. 315 * 316 * Added in API level 28. 317 * 318 * @param sessionId an allocated sessionID or SessionId::Allocate 319 */ setSessionId(SessionId sessionId)320 AudioStreamBuilder *setSessionId(SessionId sessionId) { 321 mSessionId = sessionId; 322 return this; 323 } 324 325 /** 326 * Request a stream to a specific audio input/output device given an audio device ID. 327 * 328 * In most cases, the primary device will be the appropriate device to use, and the 329 * deviceId can be left kUnspecified. 330 * 331 * The ID could be obtained from the Java AudioManager. 332 * AudioManager.getDevices() returns an array of AudioDeviceInfo, 333 * which contains a getId() method. That ID can be passed to this function. 334 * 335 * It is possible that you may not get the device that you requested. 336 * So if it is important to you, you should call 337 * stream->getDeviceId() after the stream is opened to 338 * verify the actual ID. 339 * 340 * Note that when using OpenSL ES, this will be ignored and the created 341 * stream will have deviceId kUnspecified. 342 * 343 * @param deviceId device identifier or kUnspecified 344 * @return pointer to the builder so calls can be chained 345 */ setDeviceId(int32_t deviceId)346 AudioStreamBuilder *setDeviceId(int32_t deviceId) { 347 mDeviceId = deviceId; 348 return this; 349 } 350 351 /** 352 * Specify whether this stream audio may or may not be captured by other apps or the system. 353 * 354 * The default is AllowedCapturePolicy::Unspecified which maps to AAUDIO_ALLOW_CAPTURE_BY_ALL. 355 * 356 * Note that an application can also set its global policy, in which case the most restrictive 357 * policy is always applied. See android.media.AudioAttributes.setAllowedCapturePolicy. 358 * 359 * Added in API level 29 to AAudio. 360 * 361 * @param inputPreset the desired level of opt-out from being captured. 362 * @return pointer to the builder so calls can be chained 363 */ setAllowedCapturePolicy(AllowedCapturePolicy allowedCapturePolicy)364 AudioStreamBuilder *setAllowedCapturePolicy(AllowedCapturePolicy allowedCapturePolicy) { 365 mAllowedCapturePolicy = allowedCapturePolicy; 366 return this; 367 } 368 369 /** Indicates whether this input stream must be marked as privacy sensitive or not. 370 * 371 * When PrivacySensitiveMode::Enabled, this input stream is privacy sensitive and any 372 * concurrent capture is not permitted. 373 * 374 * This is off (PrivacySensitiveMode::Disabled) by default except when the input preset is 375 * InputPreset::VoiceRecognition or InputPreset::Camcorder 376 * 377 * Always takes precedence over default from input preset when set explicitly. 378 * 379 * Only relevant if the stream direction is Direction::Input and AAudio is used. 380 * 381 * Added in API level 30 to AAudio. 382 * 383 * @param privacySensitive PrivacySensitiveMode::Enabled if capture from this stream must be 384 * marked as privacy sensitive, PrivacySensitiveMode::Disabled if stream should be marked as 385 * not sensitive. 386 * @return pointer to the builder so calls can be chained 387 */ setPrivacySensitiveMode(PrivacySensitiveMode privacySensitiveMode)388 AudioStreamBuilder *setPrivacySensitiveMode(PrivacySensitiveMode privacySensitiveMode) { 389 mPrivacySensitiveMode = privacySensitiveMode; 390 return this; 391 } 392 393 /** 394 * Specifies whether the audio data of this output stream has already been processed for spatialization. 395 * 396 * If the stream has been processed for spatialization, setting this to true will prevent issues such as 397 * double-processing on platforms that will spatialize audio data. 398 * 399 * This is false by default. 400 * 401 * Available since API level 32. 402 * 403 * @param isContentSpatialized whether the content is already spatialized 404 * @return pointer to the builder so calls can be chained 405 */ setIsContentSpatialized(bool isContentSpatialized)406 AudioStreamBuilder *setIsContentSpatialized(bool isContentSpatialized) { 407 mIsContentSpatialized = isContentSpatialized; 408 return this; 409 } 410 411 /** 412 * Sets the behavior affecting whether spatialization will be used. 413 * 414 * The AAudio system will use this information to select whether the stream will go through a 415 * spatializer effect or not when the effect is supported and enabled. 416 * 417 * This is SpatializationBehavior::Never by default. 418 * 419 * Available since API level 32. 420 * 421 * @param spatializationBehavior the desired spatialization behavior 422 * @return pointer to the builder so calls can be chained 423 */ setSpatializationBehavior(SpatializationBehavior spatializationBehavior)424 AudioStreamBuilder *setSpatializationBehavior(SpatializationBehavior spatializationBehavior) { 425 mSpatializationBehavior = spatializationBehavior; 426 return this; 427 } 428 429 /** 430 * Specifies an object to handle data related callbacks from the underlying API. 431 * 432 * <strong>Important: See AudioStreamCallback for restrictions on what may be called 433 * from the callback methods.</strong> 434 * 435 * We pass a shared_ptr so that the sharedDataCallback object cannot be deleted 436 * before the stream is deleted. 437 * 438 * @param sharedDataCallback 439 * @return pointer to the builder so calls can be chained 440 */ setDataCallback(std::shared_ptr<AudioStreamDataCallback> sharedDataCallback)441 AudioStreamBuilder *setDataCallback(std::shared_ptr<AudioStreamDataCallback> sharedDataCallback) { 442 // Use this raw pointer in the rest of the code to retain backwards compatibility. 443 mDataCallback = sharedDataCallback.get(); 444 // Hold a shared_ptr to protect the raw pointer for the lifetime of the stream. 445 mSharedDataCallback = sharedDataCallback; 446 return this; 447 } 448 449 /** 450 * Pass a raw pointer to a data callback. This is not recommended because the dataCallback 451 * object might get deleted by the app while it is being used. 452 * 453 * @deprecated Call setDataCallback(std::shared_ptr<AudioStreamDataCallback>) instead. 454 * @param dataCallback 455 * @return pointer to the builder so calls can be chained 456 */ setDataCallback(AudioStreamDataCallback * dataCallback)457 AudioStreamBuilder *setDataCallback(AudioStreamDataCallback *dataCallback) { 458 mDataCallback = dataCallback; 459 mSharedDataCallback = nullptr; 460 return this; 461 } 462 463 /** 464 * Specifies an object to handle error related callbacks from the underlying API. 465 * This can occur when a stream is disconnected because a headset is plugged in or unplugged. 466 * It can also occur if the audio service fails or if an exclusive stream is stolen by 467 * another stream. 468 * 469 * <strong>Important: See AudioStreamCallback for restrictions on what may be called 470 * from the callback methods.</strong> 471 * 472 * <strong>When an error callback occurs, the associated stream must be stopped and closed 473 * in a separate thread.</strong> 474 * 475 * We pass a shared_ptr so that the errorCallback object cannot be deleted before the stream is deleted. 476 * If the stream was created using a shared_ptr then the stream cannot be deleted before the 477 * error callback has finished running. 478 * 479 * @param sharedErrorCallback 480 * @return pointer to the builder so calls can be chained 481 */ setErrorCallback(std::shared_ptr<AudioStreamErrorCallback> sharedErrorCallback)482 AudioStreamBuilder *setErrorCallback(std::shared_ptr<AudioStreamErrorCallback> sharedErrorCallback) { 483 // Use this raw pointer in the rest of the code to retain backwards compatibility. 484 mErrorCallback = sharedErrorCallback.get(); 485 // Hold a shared_ptr to protect the raw pointer for the lifetime of the stream. 486 mSharedErrorCallback = sharedErrorCallback; 487 return this; 488 } 489 490 /** 491 * Pass a raw pointer to an error callback. This is not recommended because the errorCallback 492 * object might get deleted by the app while it is being used. 493 * 494 * @deprecated Call setErrorCallback(std::shared_ptr<AudioStreamErrorCallback>) instead. 495 * @param errorCallback 496 * @return pointer to the builder so calls can be chained 497 */ setErrorCallback(AudioStreamErrorCallback * errorCallback)498 AudioStreamBuilder *setErrorCallback(AudioStreamErrorCallback *errorCallback) { 499 mErrorCallback = errorCallback; 500 mSharedErrorCallback = nullptr; 501 return this; 502 } 503 504 /** 505 * Specifies an object to handle data or error related callbacks from the underlying API. 506 * 507 * This is the equivalent of calling both setDataCallback() and setErrorCallback(). 508 * 509 * <strong>Important: See AudioStreamCallback for restrictions on what may be called 510 * from the callback methods.</strong> 511 * 512 * @deprecated Call setDataCallback(std::shared_ptr<AudioStreamDataCallback>) and 513 * setErrorCallback(std::shared_ptr<AudioStreamErrorCallback>) instead. 514 * @param streamCallback 515 * @return pointer to the builder so calls can be chained 516 */ setCallback(AudioStreamCallback * streamCallback)517 AudioStreamBuilder *setCallback(AudioStreamCallback *streamCallback) { 518 // Use the same callback object for both, dual inheritance. 519 mDataCallback = streamCallback; 520 mErrorCallback = streamCallback; 521 return this; 522 } 523 524 /** 525 * If true then Oboe might convert channel counts to achieve optimal results. 526 * On some versions of Android for example, stereo streams could not use a FAST track. 527 * So a mono stream might be used instead and duplicated to two channels. 528 * On some devices, mono streams might be broken, so a stereo stream might be opened 529 * and converted to mono. 530 * 531 * Default is false. 532 */ setChannelConversionAllowed(bool allowed)533 AudioStreamBuilder *setChannelConversionAllowed(bool allowed) { 534 mChannelConversionAllowed = allowed; 535 return this; 536 } 537 538 /** 539 * If true then Oboe might convert data formats to achieve optimal results. 540 * On some versions of Android, for example, a float stream could not get a 541 * low latency data path. So an I16 stream might be opened and converted to float. 542 * 543 * Default is false. 544 */ setFormatConversionAllowed(bool allowed)545 AudioStreamBuilder *setFormatConversionAllowed(bool allowed) { 546 mFormatConversionAllowed = allowed; 547 return this; 548 } 549 550 /** 551 * Specify the quality of the sample rate converter in Oboe. 552 * 553 * If set to None then Oboe will not do sample rate conversion. But the underlying APIs might 554 * still do sample rate conversion if you specify a sample rate. 555 * That can prevent you from getting a low latency stream. 556 * 557 * If you do the conversion in Oboe then you might still get a low latency stream. 558 * 559 * Default is SampleRateConversionQuality::None 560 */ setSampleRateConversionQuality(SampleRateConversionQuality quality)561 AudioStreamBuilder *setSampleRateConversionQuality(SampleRateConversionQuality quality) { 562 mSampleRateConversionQuality = quality; 563 return this; 564 } 565 566 /** 567 * Declare the name of the package creating the stream. 568 * 569 * This is usually {@code Context#getPackageName()}. 570 * 571 * The default, if you do not call this function, is a random package in the calling uid. 572 * The vast majority of apps have only one package per calling UID. 573 * If an invalid package name is set, input streams may not be given permission to 574 * record when started. 575 * 576 * The package name is usually the applicationId in your app's build.gradle file. 577 * 578 * Available since API level 31. 579 * 580 * @param packageName packageName of the calling app. 581 */ setPackageName(std::string packageName)582 AudioStreamBuilder *setPackageName(std::string packageName) { 583 mPackageName = packageName; 584 return this; 585 } 586 587 /** 588 * Declare the attribution tag of the context creating the stream. 589 * 590 * This is usually {@code Context#getAttributionTag()}. 591 * 592 * The default, if you do not call this function, is null. 593 * 594 * Available since API level 31. 595 * 596 * @param attributionTag attributionTag of the calling context. 597 */ setAttributionTag(std::string attributionTag)598 AudioStreamBuilder *setAttributionTag(std::string attributionTag) { 599 mAttributionTag = attributionTag; 600 return this; 601 } 602 603 /** 604 * @return true if AAudio will be used based on the current settings. 605 */ willUseAAudio()606 bool willUseAAudio() const { 607 return (mAudioApi == AudioApi::AAudio && isAAudioSupported()) 608 || (mAudioApi == AudioApi::Unspecified && isAAudioRecommended()); 609 } 610 611 /** 612 * Create and open a stream object based on the current settings. 613 * 614 * The caller owns the pointer to the AudioStream object 615 * and must delete it when finished. 616 * 617 * @deprecated Use openStream(std::shared_ptr<oboe::AudioStream> &stream) instead. 618 * @param stream pointer to a variable to receive the stream address 619 * @return OBOE_OK if successful or a negative error code 620 */ 621 Result openStream(AudioStream **stream); 622 623 /** 624 * Create and open a stream object based on the current settings. 625 * 626 * The caller shares the pointer to the AudioStream object. 627 * The shared_ptr is used internally by Oboe to prevent the stream from being 628 * deleted while it is being used by callbacks. 629 * 630 * @param stream reference to a shared_ptr to receive the stream address 631 * @return OBOE_OK if successful or a negative error code 632 */ 633 Result openStream(std::shared_ptr<oboe::AudioStream> &stream); 634 635 /** 636 * Create and open a ManagedStream object based on the current builder state. 637 * 638 * The caller must create a unique ptr, and pass by reference so it can be 639 * modified to point to an opened stream. The caller owns the unique ptr, 640 * and it will be automatically closed and deleted when going out of scope. 641 * 642 * @deprecated Use openStream(std::shared_ptr<oboe::AudioStream> &stream) instead. 643 * @param stream Reference to the ManagedStream (uniqueptr) used to keep track of stream 644 * @return OBOE_OK if successful or a negative error code. 645 */ 646 Result openManagedStream(ManagedStream &stream); 647 648 private: 649 650 /** 651 * Use this internally to implement opening with a shared_ptr. 652 * 653 * @param stream pointer to a variable to receive the stream address 654 * @return OBOE_OK if successful or a negative error code. 655 */ 656 Result openStreamInternal(AudioStream **streamPP); 657 658 /** 659 * @param other 660 * @return true if channels, format and sample rate match 661 */ 662 bool isCompatible(AudioStreamBase &other); 663 664 /** 665 * Create an AudioStream object. The AudioStream must be opened before use. 666 * 667 * The caller owns the pointer. 668 * 669 * @return pointer to an AudioStream object or nullptr. 670 */ 671 oboe::AudioStream *build(); 672 673 AudioApi mAudioApi = AudioApi::Unspecified; 674 }; 675 676 } // namespace oboe 677 678 #endif /* OBOE_STREAM_BUILDER_H_ */ 679