Examples
The most basic operation this extension can provide is to load a sound from disk and play it. More detailed usages can also wait for the sound to finish playing by periodically polling it, or query the length of a sound asset. The example below will demonstrate all usages:
Python
import omni.kit.uiaudio
import time
def play_one_shot_ui_sound(filename: str, count: int = 1, delay_ms: int = 0, wait: bool = False) -> bool:
uiaudio = omni.kit.uiaudio.get_ui_audio_interface()
snd = uiaudio.create_sound(filename)
if count <= 0:
count = 1
if snd == None:
return False
length = uiaudio.get_sound_length(snd)
print(f"The sound asset is {length}s long.")
for i in range(count - 1):
uiaudio.play_sound(snd)
# wait a bit before starting the next sound. Note that a sleep like this shouldn't be used
# in production code since it will lock up the UI or other threads. An `asyncio.sleep()`
# call should be used instead on async functions.
time.sleep(delay_ms / 1000.0)
uiaudio.play_sound(snd)
if wait:
while uiaudio.is_sound_playing(snd):
time.sleep(0.250)
snd = None
print("done!")
play_one_shot_ui_sound("soundToPlay.mp3")
play_one_shot_ui_sound("soundToPlay.mp3", 2, 500, True)
play_one_shot_ui_sound("soundToPlay.mp3", 1, 5000, True)
play_one_shot_ui_sound("soundToPlay.mp3", 2, 500)
C++
First, include the header files necessary for the example:
#include <omni/audio/IUiAudio.h>
#include <carb/InterfaceUtils.h>
#include <carb/logging/Log.h>
#include <chrono>
#include <thread>
Then create a helper function that can play a sound by a requested filename:
/** Loads a sound asset, plays it twice, and optionally waits for it to finish playing.
*
* @param[in] filename The name and path to the local file asset to be loaded. This must be
* either an WAV, MP3, FLAC, Ogg/Vorbis, or Opus formatted file. This
* may not be an empty string or `nullptr`.
* @param[in] count The total number of times to play the sound. Note that setting this
* to a value larger than 1 will cause this call to block for `(count - 1) *
* delayMs` milliseconds.
* @param[in] delayMs The delay in milliseconds between playing the sound the first and
* second times. Set this to 0 to have both instances of the sound play
* only once.
* @param[in] wait Set to `true` to block this function from returning until the last
* instance of the requested sound is finished playing. Set to `false` to
* simply fire-and-forget the sound.
* @returns `true` if the sounds were successfully queued. Returns `false` if the asset could
* not be loaded or coud not be played.
*/
bool playOneShotUiSound(const char* filename, size_t count = 1, size_t delayMs = 0, bool wait = false)
{
auto uiAudio = carb::getCachedInterface<omni::audio::IUiAudio>();
std::unique_ptr<omni::audio::UiSound> snd;
double length;
if (count == 0)
count = 1;
if (uiAudio == nullptr)
{
CARB_LOG_WARN("failed to acquire the `omni::audio::IUiAudio` interface.");
return false;
}
snd.reset(uiAudio->createSound(filename));
if (snd == nullptr)
{
CARB_LOG_WARN("failed to load the sound asset '%s' from disk.", filename);
return false;
}
length = uiAudio->getSoundLength(snd.get());
CARB_LOG_VERBOSE("The sound asset is %gs long.", length);
for (size_t i = 0; i < count - 1; i++)
{
uiAudio->playSound(snd.get());
carb::cpp::this_thread::sleep_for(std::chrono::milliseconds(delayMs));
}
uiAudio->playSound(snd.get());
if (wait)
{
while (uiAudio->isSoundPlaying(snd.get()))
carb::cpp::this_thread::sleep_for(std::chrono::milliseconds(250));
}
snd.reset();
CARB_LOG_VERBOSE("done!");
return true;
}