🌐 English

    Audio Playback API#

    Plays WAVE format music files with an .wav extension. Two methods are supported:

    • The playSound function plays audio from start to finish once initiated and cannot be stopped mid-way.
    • The SoundPlayer object utilizes a user-defined event callback class derived from MediaObserver.

    Header File#

    OasisMedia.h

    Functions#

    int32_t playSound ( const char * file_path , const char * snd_path )
    OasisMedia.h
    Plays a WAVE file. Returns immediately. If called consecutively, the audio is mixed and played back.
    Parameters
    file_path  The path to the WAVE file.
    snd_path  The audio device path created by calling createAudioDevice.
    Return Value
    • 0: Success
    • -1: Failure
    void waitForAllPlaySoundDone ( int32_t max_timeout )
    OasisMedia.h
    Waits until all audio playbacks initiated by calling the playSound function are completed.
    Parameters
    max_timeout  The maximum waiting time. Measured in milliseconds.
    SoundPlayerRef createSoundPlayer ( const char * file_path , key_value_map_t & parameters )
    OasisMedia.h
    Creates a SoundPlayer object.
    Parameters
    file_path  The path to the WAVE file.
    parameters  The key-value map required to create the SoundPlayer object.
    Return Value
    Returns a SoundPlayer object on success. Returns nullptr on failure.

    The key-value map required to create a SoundPlayer object is as follows:

    Key
    Default
    M
    Description
    snd-path
    The audio device path created by calling createAudioDevice.
    int32_t setSoundPlayerObserver ( const SoundPlayerRef & sound_player , const std::shared_ptr<MediaObserver> & observer , void * user_data )
    OasisMedia.h
    Configures the MediaObserver.
    Parameters
    sound_player  The SoundPlayer object.
    observer  A user-defined observer object derived from MediaObserver.
    user_data  User-defined data to be used as a parameter for the callback functions of the MediaObserver.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t destroySoundPlayer ( const SoundPlayerRef & sound_player )
    OasisMedia.h
    Releases the SoundPlayer object.
    Parameters
    sound_player  The SoundPlayer object.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t startSoundPlayer ( const SoundPlayerRef & sound_player )
    OasisMedia.h
    Starts audio playback.
    Parameters
    sound_player  The SoundPlayer object.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t stopSoundPlayer ( const SoundPlayerRef & sound_player )
    OasisMedia.h
    Stops audio playback.
    Parameters
    sound_player  The SoundPlayer object.
    Return Value
    • 0: Success
    • -1: Failure
    bool isSoundPlaying ( const SoundPlayerRef & sound_player )
    OasisMedia.h
    Verifies whether playback is in progress.
    Parameters
    sound_player  The SoundPlayer object.
    Return Value
    • true: Playback is in progress.
    • false: Playback is not in progress.

    Example#

    Below is an example of playing a WAV file.

    Defines a user-defined Observer class derived from MediaObserver.

    class SoundPlayingObserver : public oasis::MediaObserver
    {
    public:
        SoundPlayingObserver();
        virtual ~SoundPlayingObserver();
    
    public:
        virtual void onStarted(void* user_data, const char* file_path);
        virtual void onStopped(void* user_data, media_report_reason_t reason, void* details);
        virtual void onError(void* user_data, media_report_reason_t reason, void* details);
        virtual void onInfo(void* user_data, MediaInfo* info);
    
    };
    
    SoundPlayingObserver::SoundPlayingObserver() 
    {
    }
    
    SoundPlayingObserver::~SoundPlayingObserver()
    {
    }
    
    void SoundPlayingObserver::onStarted(void* user_data, const char* file_path)
    {
        fprintf(stdout, "Playing started, file path \"%s\"\n", file_path);
    }
    
    void SoundPlayingObserver::onStopped(void* user_data, media_report_reason_t reason, void* details)
    {
        fprintf(stdout, "Playing stopped, reason: %d\n", reason);
      got_interrupt = true;
    }
    
    void SoundPlayingObserver::onError(void* user_data, media_report_reason_t reason, void* details)
    {
      got_interrupt = true;
    }
    
    void SoundPlayingObserver::onInfo(void* user_data, MediaInfo* info)
    {
        int h, m, s, u;
        parseUsec(info->durationUs, h, m, s, u);
        int ch, cm, cs, cu;
        parseUsec(info->currentTimestampUs, ch, cm, cs, cu);
    
        fprintf(stdout, "Playing duration %02d:%02d:%02d.%06d, current %02d:%02d:%02d.%06d                    \r", h, m, s, u, ch, cm, cs, cu);
      fflush(stdout);
    }
    

    Initializes Oasis.

        oasis::key_value_map_t parameters;
    
        parameters["offs-disable"] = "1";
        if(oasis::initialize(parameters) < 0) {
            DLOG(DLOG_ERROR, "Oasis init failed\n");
            return -1;
        }  
    

    Initializes the audio device.

    #if 0
    #define SND_PATH "default"
    #else
    #define SND_PATH "hw:0,0"
    #endif
    
      parameters["types"]="source,sink";
      parameters["path"]=SND_PATH;
      parameters["always-on"]="1";
      parameters["channels"]="2";
      parameters["aec-disabled"]="1";
      parameters["snd-input-channels"]="2";
      parameters["snd-input-sample-size"]="16";
      parameters["snd-input-sampling-duration-msec"]="40";
      parameters["snd-input-sampling-rate"]="48000";
    
      createAudioDevice(parameters);
    

    Creates the player object and starts playback.

      SoundPlayerRef player = nullptr;
      std::shared_ptr<SoundPlayingObserver> observer = std::make_shared<SoundPlayingObserver>();
    
      parameters.clear();
    
      parameters["snd-path"] = SND_PATH;
    
      player = createSoundPlayer(argv[1], parameters);
      ASSERT(player);
      if(player != nullptr) {
        //set observer.
        setSoundPlayerObserver(player, observer, nullptr);
        if(startSoundPlayer(player) == 0) {
        } else {
          fprintf(stdout, "playing \"%s\" start failed.\n", argv[1]);       
        }
      } else {
        fprintf(stdout, "playing \"%s\" creation failed.\n", argv[1]);  
      }    
    

    Terminates once playback is finished.

      do {
        usleep(100000);
      } while(got_interrupt == false);
    
      if(player) {
        destroySoundPlayer(player);
      }
    
        oasis::finalize();
    

    Below is the complete code:

    #include "OasisAPI.h"
    #include "OasisLog.h"
    #include "OasisUtil.h"
    #include "OasisMedia.h"
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <dirent.h>
    
    #include <thread>
    #include <mutex>
    #include <memory>
    #include <condition_variable>
    
    
    #undef DLOG_TAG
    #define DLOG_TAG "Sound"
    
    
    #define OFFS_QUEUE_SIZE_KBYTES  (40*1024)
    #define OFFS_CACHE_SIZE_KBYTES  (1024)
    #define OFFS_WRITE_ALIGNMENT_BYTES  8192
    #define MEDIA_CACHE_SIZE_KBYTES (40*1024)
    
    using namespace oasis;
    
    bool got_interrupt = false;
    
    #include <signal.h>
    
    class SoundPlayingObserver : public oasis::MediaObserver
    {
    public:
        SoundPlayingObserver();
        virtual ~SoundPlayingObserver();
    
    public:
        virtual void onStarted(void* user_data, const char* file_path);
        virtual void onStopped(void* user_data, media_report_reason_t reason, void* details);
        virtual void onError(void* user_data, media_report_reason_t reason, void* details);
        virtual void onInfo(void* user_data, MediaInfo* info);
    
    };
    
    SoundPlayingObserver::SoundPlayingObserver() 
    {
    }
    
    SoundPlayingObserver::~SoundPlayingObserver()
    {
    }
    
    void SoundPlayingObserver::onStarted(void* user_data, const char* file_path)
    {
        fprintf(stdout, "Playing started, file path \"%s\"\n", file_path);
    }
    
    void SoundPlayingObserver::onStopped(void* user_data, media_report_reason_t reason, void* details)
    {
        fprintf(stdout, "Playing stopped, reason: %d\n", reason);
        got_interrupt = true;
    }
    
    void SoundPlayingObserver::onError(void* user_data, media_report_reason_t reason, void* details)
    {
        fprintf(stdout, "Playing Error, reason: %d\n", reason);
        got_interrupt = true;
    }
    
    void SoundPlayingObserver::onInfo(void* user_data, MediaInfo* info)
    {
        int h, m, s, u;
        parseUsec(info->durationUs, h, m, s, u);
        int ch, cm, cs, cu;
        parseUsec(info->currentTimestampUs, ch, cm, cs, cu);
    
        fprintf(stdout, "Playing duration %02d:%02d:%02d.%06d, current %02d:%02d:%02d.%06d                    \r", h, m, s, u, ch, cm, cs, cu);
        fflush(stdout);
    }
    
    
    void cancel_handler(int sig)
    {
        got_interrupt = true;
    }
    
    int main(int argc, char *argv[])
    {
        int32_t err;
    
        signal(SIGINT, cancel_handler);
    
        oasis::key_value_map_t parameters;
    
        if(argc < 2) {
            fprintf(stdout, "USAGE: %s <wave file path>\n", argv[0]);
            return -1;
        }
    
        if(access(argv[1], F_OK)) {
            fprintf(stderr, "file not found: %s\n", argv[1]);
            return -1;
        }
    
        parameters["offs-disable"] = "1";
    
        if(oasis::initialize(parameters) < 0) {
            DLOG(DLOG_ERROR, "Oasis init failed\n");
            return -1;
        }
    
    #if 0
    #define SND_PATH "default"
    #else
    #define SND_PATH "hw:0,0"
    #endif
    
        parameters["types"]="source,sink";
        parameters["path"]=SND_PATH;
        parameters["always-on"]="1";
        parameters["channels"]="2";
        parameters["aec-disabled"]="1";
        parameters["snd-input-channels"]="2";
        parameters["snd-input-sample-size"]="16";
        parameters["snd-input-sampling-duration-msec"]="40";
        parameters["snd-input-sampling-rate"]="48000";
        //parameters["snd-input-sampling-rate"]="22050";
    
        createAudioDevice(parameters);
    
        SoundPlayerRef player = nullptr;
        std::shared_ptr<SoundPlayingObserver> observer = std::make_shared<SoundPlayingObserver>();
    
        parameters.clear();
    
        parameters["snd-path"] = SND_PATH;
    
        player = createSoundPlayer(argv[1], parameters);
        ASSERT(player);
        if(player != nullptr) {
            //set observer.
            setSoundPlayerObserver(player, observer, nullptr);
            if(startSoundPlayer(player) == 0) {
            } else {
                fprintf(stdout, "playing \"%s\" start failed.\n", argv[1]);     
            }
        } else {
            fprintf(stdout, "playing \"%s\" creation failed.\n", argv[1]);  
        }    
    
        fprintf(stdout, "Enter Ctrl+C to exit...\n");
    
        do {
            usleep(100000);
        } while(got_interrupt == false);
    
        if(player) {
            destroySoundPlayer(player);
        }
    
        oasis::finalize();
    
        return 0;
    }