Skip to content

Commit

Permalink
add Oboe for realtime sound
Browse files Browse the repository at this point in the history
# Conflicts:
#	yabause/src/android/jni/yui.cpp
  • Loading branch information
devmiyax committed Apr 9, 2022
1 parent b00655a commit 5f98b55
Show file tree
Hide file tree
Showing 6 changed files with 339 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "ext/eigen"]
path = yabause/src/retro_arena/nanogui-sdl/ext/eigen
url = https://github.com/libigl/eigen.git
[submodule "yabause/src/android/oboe"]
path = yabause/src/android/oboe
url = https://github.com/google/oboe
8 changes: 8 additions & 0 deletions yabause/src/android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ include( ${CMAKE_SOURCE_DIR}/CMake/Packages/external_libpng.cmake )
#include( ${CMAKE_SOURCE_DIR}/CMake/Packages/external_zlib.cmake )

set( SOURCES
jni/SndOboe.h
jni/SndOboe.cpp
jni/yui.cpp
#jni/sndaudiotrack.c
jni/sndopensl.c
Expand All @@ -45,6 +47,11 @@ set( SOURCES
jni/ChdFileInfo.h
)

set (OBOE_DIR ./oboe)
add_subdirectory (${OBOE_DIR} ./oboe)
include_directories (${OBOE_DIR}/include)


if( YAB_WANT_VULKAN )
set( SOURCES ${SOURCES} ../vulkan/Window_android.cpp )
endif()
Expand Down Expand Up @@ -84,6 +91,7 @@ target_link_libraries(${LIBRARY_NAME} yabause ${YABAUSE_LIBRARIES}
png16
${ZLIB_LIBRARY_RELEASE}
${VULKAN_LIBRARIES}
oboe
#${zlib_STATIC_LIBRARIES}
# ${PROJECT_SOURCE_DIR}/debuglib/libNvidia_gfx_debugger_stub.a
)
Expand Down
4 changes: 4 additions & 0 deletions yabause/src/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@
android:name="android.hardware.opengles.aep"
android:required="false" />

<uses-feature android:name="android.hardware.audio.low_latency"/>
<uses-feature android:name="android.hardware.audio.pro"/>


<application
android:name="org.uoyabause.android.YabauseApplication"
android:icon="@mipmap/ic_launcher"
Expand Down
272 changes: 272 additions & 0 deletions yabause/src/android/jni/SndOboe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
#include "SndOboe.h"

#include <oboe/Oboe.h>
#include <math.h>


using namespace oboe;

class SndOboeEngine: public oboe::AudioStreamDataCallback {
private:
std::mutex mLock;
std::shared_ptr<oboe::AudioStream> mStream;

const int NUMSOUNDBLOCKS =4;
const int blockSize = 2940;

u16 *stereodata16;
u32 soundoffset;
volatile u32 soundpos;
u32 soundlen;
u32 soundbufsize;
u8 soundvolume;
int muted = 0;

// Stream params
static int constexpr kChannelCount = 2;
static int constexpr kSampleRate = 44100;

public:


static SndOboeEngine * instance_;
static SndOboeEngine * getInstance(){
if( instance_==NULL ) instance_ = new SndOboeEngine();
return instance_;
}


virtual ~SndOboeEngine() = default;

int32_t startAudio() {
std::lock_guard<std::mutex> lock(mLock);

soundbufsize = blockSize * NUMSOUNDBLOCKS * 2 * 2;
stereodata16 = new u16[soundbufsize];
memset( stereodata16, 0, sizeof(s16) * soundbufsize );
soundpos = 0;

oboe::AudioStreamBuilder builder;
// The builder set methods can be chained for convenience.
Result result = builder.setSharingMode(oboe::SharingMode::Exclusive)
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
->setChannelCount(kChannelCount)
->setSampleRate(kSampleRate)
->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::Medium)
->setFormat(oboe::AudioFormat::I16)
->setDataCallback(this)
->openStream(mStream);

if (result != Result::OK) return (int32_t) result;

mStream->requestStart();

return (int32_t) result;
}

// Call this from Activity onPause()
void stopAudio() {
// Stop, close and delete in case not already closed.
std::lock_guard<std::mutex> lock(mLock);

delete [] stereodata16;

if (mStream) {
mStream->stop();
mStream->close();
mStream.reset();
}
}

oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override {

std::lock_guard<std::mutex> lock(mLock);

int i;
u8* soundbuf = (u8*)stereodata16;
u8 *stream = (u8 *)audioData;
int len = numFrames * 2 * 2;

// original code
for (i = 0; i < len; i++)
{
if (soundpos >= soundbufsize)
soundpos = 0;
stream[i] = muted ? 0 : soundbuf[soundpos];
soundpos++;
}

return oboe::DataCallbackResult::Continue;
}


void convert32uto16s(s32 *srcL, s32 *srcR, s16 *dst, u32 len) {
u32 i;

for (i = 0; i < len; i++)
{
// Left Channel
if (*srcL > 0x7FFF) *dst = 0x7FFF;
else if (*srcL < -0x8000) *dst = -0x8000;
else *dst = *srcL;
srcL++;
dst++;

// Right Channel
if (*srcR > 0x7FFF) *dst = 0x7FFF;
else if (*srcR < -0x8000) *dst = -0x8000;
else *dst = *srcR;
srcR++;
dst++;
}

}

public:
void onUpdateAudio(u32 *leftchanbuffer, u32 *rightchanbuffer, u32 num_samples) {
u32 copy1size=0, copy2size=0;
int nextpos;

std::lock_guard<std::mutex> lock(mLock);


if ((soundbufsize - soundoffset) < (num_samples * sizeof(s16) * 2))
{
copy1size = (soundbufsize - soundoffset);
copy2size = (num_samples * sizeof(s16) * 2) - copy1size;
}
else
{
copy1size = (num_samples * sizeof(s16) * 2);
copy2size = 0;
}

convert32uto16s((s32 *)leftchanbuffer, (s32 *)rightchanbuffer,
(s16 *)(((u8 *)stereodata16)+soundoffset), copy1size / sizeof(s16) / 2);

if (copy2size)
convert32uto16s((s32 *)leftchanbuffer + (copy1size / sizeof(s16) / 2),
(s32 *)rightchanbuffer + (copy1size / sizeof(s16) / 2), (s16 *)stereodata16,
copy2size / sizeof(s16) / 2);

soundoffset += copy1size + copy2size;
soundoffset %= soundbufsize;


}

int getAudioSpace(){

u32 freespace=0;

if (soundoffset > soundpos)
freespace = soundbufsize - soundoffset + soundpos;
else
freespace = soundpos - soundoffset;

return (freespace / sizeof(s16) / 2);
}

void mute(){
muted = 1;
}

void unmute(){
muted = 0;
}

void setVolume( int vol ){
if( vol == 0 ){
muted = 1;
}else{
muted = 0;
}
}

};

SndOboeEngine * SndOboeEngine::instance_ = NULL;

extern "C" {

int SNDOboeInit(void);
void SNDOboeDeInit(void);
int SNDOboeReset(void);
int SNDOboeChangeVideoFormat(int vertfreq);
void SNDOboeUpdateAudio(u32 *leftchanbuffer, u32 *rightchanbuffer, u32 num_samples);
u32 SNDOboeGetAudioSpace(void);
void SNDOboeMuteAudio(void);
void SNDOboeUnMuteAudio(void);
void SNDOboeSetVolume(int volume);

SoundInterface_struct SNDOboe = {
SNDCORE_OBOE,
"Oboe Sound Interface",
SNDOboeInit,
SNDOboeDeInit,
SNDOboeReset,
SNDOboeChangeVideoFormat,
SNDOboeUpdateAudio,
SNDOboeGetAudioSpace,
SNDOboeMuteAudio,
SNDOboeUnMuteAudio,
SNDOboeSetVolume
};

int SNDOboeInit(void){

SndOboeEngine * i = SndOboeEngine::getInstance();
i->startAudio();

return 0;
}

void SNDOboeDeInit(void){

SndOboeEngine * i = SndOboeEngine::getInstance();
i->stopAudio();

return;
}

int SNDOboeReset(void){
return 0;
}

int SNDOboeChangeVideoFormat(int vertfreq){
return 0;
}

void SNDOboeUpdateAudio(u32 *leftchanbuffer, u32 *rightchanbuffer, u32 num_samples){

SndOboeEngine * i = SndOboeEngine::getInstance();
i->onUpdateAudio(leftchanbuffer,rightchanbuffer,num_samples);
return;

}

u32 SNDOboeGetAudioSpace(void){

SndOboeEngine * i = SndOboeEngine::getInstance();
return i->getAudioSpace();
}

void SNDOboeMuteAudio(void){
SndOboeEngine * i = SndOboeEngine::getInstance();
return i->mute();

}

void SNDOboeUnMuteAudio(void){
SndOboeEngine * i = SndOboeEngine::getInstance();
return i->unmute();

}

void SNDOboeSetVolume(int volume){
SndOboeEngine * i = SndOboeEngine::getInstance();
return i->setVolume(volume);
}


}
40 changes: 40 additions & 0 deletions yabause/src/android/jni/SndOboe.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* Copyright 2012 Guillaume Duhamel
This file is part of Yabause.
Yabause is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Yabause is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Yabause; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef SNDOBOE_H
#define SNDOBOE_H

#ifdef __cplusplus
extern "C" {
#endif


#define SNDCORE_OBOE 0x21

#include "scsp.h"

extern SoundInterface_struct SNDOboe;


#ifdef __cplusplus
}
#endif


#endif
13 changes: 12 additions & 1 deletion yabause/src/android/jni/yui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include "sndopensl.h"
#endif

#include "SndOboe.h"

#include "libpng16/png.h"

#include "PlayRecorder.h"
Expand Down Expand Up @@ -222,7 +224,9 @@ SoundInterface_struct *SNDCoreList[] = {
#ifdef HAVE_OPENSL
&SNDOpenSL,
#endif
NULL};
&SNDOboe,
NULL
};

VideoInterface_struct *VIDCoreList[] = {
&VIDDummy,
Expand Down Expand Up @@ -1484,7 +1488,14 @@ int YabauseInit()
#else
yinit.sndcoretype = SNDCORE_AUDIOTRACK;
#endif
<<<<<<< HEAD
yinit.cdcoretype = CDCORE_WEBAPI;
=======

yinit.sndcoretype = SNDCORE_OBOE;

yinit.cdcoretype = CDCORE_ISO;
>>>>>>> 732737167... add Oboe for realtime sound
yinit.carttype = GetCartridgeType();
yinit.regionid = 0;

Expand Down

0 comments on commit 5f98b55

Please sign in to comment.