audio rework

This commit is contained in:
h4570
2022-08-11 23:18:50 +02:00
parent 74c642bd83
commit 472ab5c2ad
20 changed files with 706 additions and 386 deletions
+28
View File
@@ -0,0 +1,28 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, Tyra - https://github.com/h4570/tyrav2
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#pragma once
namespace Tyra {
enum AdpcmResult {
ADPCM_OK,
/** When provided channel by user is currently in use */
ADPCM_CHANNEL_USED,
/** When user did not provided channel and all are in use */
ADPCM_NO_FREE_CHANNELS,
ADPCM_ERROR
};
} // namespace Tyra
+5 -126
View File
@@ -11,151 +11,30 @@
#pragma once
#include "./audio_listener.hpp"
#include <audsrv.h>
#include <string>
#include "./audio_adpcm.hpp"
#include "./audio_song.hpp"
namespace Tyra {
struct AudioListenerRef {
AudioListener* listener;
u32 id;
};
/**
* Class responsible for audio playing.
* There are two main features:
* - WAV song (background music)
* - ADPCM samples
*/
/** Class responsible for audio. */
class Audio {
public:
/** Constructor is called by the engine. */
Audio();
~Audio();
void init();
/**
* Load 24bit 22kHz Stereo WAV.
* Can be used multiple times for song switching.
* @param t_path Example: "host:song.wav" or "host:folder/song.wav"
*/
void loadSong(const char* t_path);
/**
* Load 24bit 22kHz Stereo WAV.
* Can be used multiple times for song switching.
* @param t_path Example: "host:song.wav" or "host:folder/song.wav"
*/
inline void loadSong(const std::string& t_path) { loadSong(t_path.c_str()); }
void playSong();
void stopSong();
const u8& isSongPlaying() const { return songPlaying; }
const u8& isSongLoaded() const { return songLoaded; }
/**
* Set song loop/noloop.
* @returns Looping state is 0 - noloop / 1 - loop
*/
const u8& isSongInLoop() const { return songInLoop; }
/**
* Set song loop/noloop.
* @param t_set false - noloop, true - loop
*/
void setSongLoop(const u8& t_set) { songInLoop = t_set; }
const u8& getVolume() const { return tyraVolume; }
/**
* Set song volume.
* @param t_vol Value 0-100
*/
void setSongVolume(const u8& t_vol);
/**
* If you want to synchronize some actions with
* background song, add audio listener.
* @returns Listener id.
*/
u32 addSongListener(AudioListener* t_listener);
/** Remove song listener. */
void removeSongListener(const u32& t_id);
/**
* Load ADPCM sample.
* ADPCM sample is an output from "Convert WAV to ADPCM" task (adpenc tool).
* Adpenc expects 22kHz 16bit file.
* @param t_path Example: "host:hit.adpcm" or "host:folder/jump.adpcm"
*/
audsrv_adpcm_t* loadADPCM(const char* t_path);
/**
* Load ADPCM sample.
* ADPCM sample is an output from "Convert WAV to ADPCM" task (adpenc tool).
* Adpenc expects 22kHz 16bit file.
* @param t_path Example: "host:hit.adpcm" or "host:folder/jump.adpcm"
*/
inline audsrv_adpcm_t* loadADPCM(const std::string& t_path) {
return loadADPCM(t_path.c_str());
}
/**
* Play ADPCM sample.
* ADPCM sample can't be stopped.
* @param t_adpcm ADPCM data, created by loadADPCM();
*/
void playADPCM(audsrv_adpcm_t* t_adpcm);
/**
* Play ADPCM sample.
* ADPCM sample can't be stopped.
* @param t_adpcm ADPCM data, created by loadADPCM();
* @param t_ch Channel (0-23). Type -1 for use any free channel.
*/
void playADPCM(audsrv_adpcm_t* t_adpcm, const s8& t_ch);
/**
* Set ADPCM volume.
* @param t_vol Value 0-100
* @param t_ch Channel (0-23)
*/
void setADPCMVolume(const u8& t_vol, const s8& t_ch) {
audsrv_adpcm_set_volume(t_ch, t_vol);
}
AudioSong song;
AudioAdpcm adpcm;
void work();
private:
u8 songLoaded, tyraVolume, audsrvVolume, songPlaying, songInLoop,
songFinished;
FILE* wav;
audsrv_fmt_t format;
std::vector<AudioListenerRef*> songListeners;
ee_thread_t thread;
int threadId;
static const u16 threadStackSize;
u8* threadStack;
ee_sema_t sema;
s32 fillbufferSema;
static const u16 chunkSize;
char* chunk;
s32 chunkReadStatus;
void setSongFormat();
void unloadSong();
void rewindSongToStart();
u32 getSongListenersCount() const { return songListeners.size(); }
void initSema();
void initAUDSRV();
void initThread();
};
+77
View File
@@ -0,0 +1,77 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, Tyra - https://github.com/h4570/tyrav2
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include "./audio_listener_ref.hpp"
#include "./adpcm_result.hpp"
#include <audsrv.h>
#include <string>
namespace Tyra {
/**
* Class responsible for playing ADPCM samples.
* ADPCM sample can't be stopped.
*/
class AudioAdpcm {
public:
AudioAdpcm();
~AudioAdpcm();
void init();
/**
* Load ADPCM sample.
* ADPCM sample is an output from "Convert WAV to ADPCM" task (adpenc tool).
* Adpenc expects 22kHz 16bit file.
* @param t_path Example: "host:hit.adpcm" or "host:folder/jump.adpcm"
*/
audsrv_adpcm_t* load(const char* t_path);
audsrv_adpcm_t* load(const std::string& t_path);
/**
* Frees up all memory taken by samples, and stops all voices from
* being played.
*/
void reset();
/**
* Try play ADPCM sample if channel(s) is not occupied.
* @param t_adpcm ADPCM data, created by load();
* @param t_ch Channel (0-23). Type -1 for use any free channel.
*/
AdpcmResult tryPlay(audsrv_adpcm_t* t_adpcm);
AdpcmResult tryPlay(audsrv_adpcm_t* t_adpcm, const s8& t_ch);
/**
* Play ADPCM sample, if channel is occupied, wait for it.
* If not used properly, can hugely reduce performance.
* @param t_adpcm ADPCM data, created by load();
* @param t_ch Channel (0-23). Type -1 for use any free channel.
*/
void playWait(audsrv_adpcm_t* t_adpcm);
void playWait(audsrv_adpcm_t* t_adpcm, const s8& t_ch);
/**
* Set ADPCM volume.
* @param t_vol Value 0-100
* @param t_ch Channel (0-23)
*/
void setVolume(const u8& t_vol, const s8& t_ch) {
audsrv_adpcm_set_volume(t_ch, t_vol);
}
private:
void initAUDSRV();
};
} // namespace Tyra
+24
View File
@@ -0,0 +1,24 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, Tyra - https://github.com/h4570/tyrav2
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include "./audio_listener.hpp"
#include <tamtypes.h>
namespace Tyra {
struct AudioListenerRef {
AudioListener* listener;
u32 id;
};
} // namespace Tyra
+90
View File
@@ -0,0 +1,90 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, Tyra - https://github.com/h4570/tyrav2
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include "./audio_listener_ref.hpp"
#include <audsrv.h>
#include <string>
#include <vector>
#include <kernel.h>
namespace Tyra {
/** Class responsible for background audio playing. */
class AudioSong {
public:
AudioSong();
~AudioSong();
void init();
bool inLoop;
/**
* Load 24bit 22kHz Stereo WAV.
* Can be used multiple times for song switching.
* @param t_path Example: "host:song.wav" or "host:folder/song.wav"
*/
void load(const char* t_path);
void load(const std::string& t_path);
void play();
void stop();
const bool& isPlaying() const;
const bool& isLoaded() const;
const u8& getVolume() const;
/**
* Set song volume.
* @param t_vol Value 0-100
*/
void setVolume(const u8& t_vol);
/**
* If you want to synchronize some actions with
* background song, add audio listener.
* @returns Listener id.
*/
u32 addListener(AudioListener* t_listener);
/** Remove song listener. */
void removeListener(const u32& t_id);
std::size_t getListenersCount() const;
void work();
private:
bool songLoaded, songPlaying, songFinished;
u8 tyraVolume, audsrvVolume;
FILE* wav;
audsrv_fmt_t format;
std::vector<AudioListenerRef*> songListeners;
ee_sema_t sema;
s32 fillbufferSema;
static const u16 chunkSize;
char* chunk;
s32 chunkReadStatus;
void initSema();
void initAUDSRV();
void setSongFormat();
void unloadSong();
void rewindSongToStart();
};
} // namespace Tyra