[DEV] add basic AIRTAUDIO interface for android sound

This commit is contained in:
Edouard DUPIN 2014-03-20 10:27:58 +01:00
parent 9f4bd697e8
commit 4be5c84b9c
16 changed files with 333 additions and 940 deletions

2
build

@ -1 +1 @@
Subproject commit 2ab328a164b3c4b39df2f9b93fa0da64faf98783
Subproject commit b48a5672b6c3a981160bb5ec61df46cde8d823a9

2
external/airtaudio vendored

@ -1 +1 @@
Subproject commit 56836c78767759c202ca8cf79e13e05fb0a7ae7a
Subproject commit a1f0b0f81c895b946a6db763d9845acdd2d05525

2
external/eaudiofx vendored

@ -1 +1 @@
Subproject commit baf70033f33a1fc3c78159162c5d6f5193cb3840
Subproject commit 5f94203fff63da9a37122f550e749d3d41e88ea4

2
external/ejson vendored

@ -1 +1 @@
Subproject commit 74f13fd91904cf52b4545440bfc13f5aaa827355
Subproject commit 989ced9c90865dda4b0d6d65a4cf7eef99d9a8c1

View File

@ -56,10 +56,13 @@ import org.ewol.Ewol;
public abstract class EwolActivity extends Activity implements EwolCallback, EwolConstants {
private static Context mContext;
private EwolSurfaceViewGL mGLView;
private EwolAudioTask mStreams;
private Thread mAudioThread;
private Ewol EWOL;
// clipboard section
private String tmpClipBoard; // TODO : Remove this ==> clipboard acces does not work
// Audio section :
private EwolAudioTask mStreams;
private Thread mAudioThread;
private boolean mAudioStarted;
static {
try {
System.loadLibrary("ewol");
@ -99,7 +102,8 @@ public abstract class EwolActivity extends Activity implements EwolCallback, Ewo
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setListnerToRootView();
mAudioStarted = false;
mAudioThread = null;
EwolActivity.mContext = getApplicationContext();
// Load the application directory
@ -147,28 +151,35 @@ public abstract class EwolActivity extends Activity implements EwolCallback, Ewo
@Override protected void onResume() {
super.onResume();
mGLView.onResume();
/*
mAudioThread = new Thread(mStreams);
if (mAudioThread != null) {
mAudioThread.start();
if (mAudioStarted == true) {
Log.e("EwolActivity", "Start audio interface");
if (mAudioThread == null) {
Log.e("EwolActivity", "create thread with stream");
mAudioThread = new Thread(mStreams);
if (mAudioThread != null) {
Log.e("EwolActivity", "start audio");
mAudioThread.start();
}
}
}
*/
EWOL.onResume();
}
@Override protected void onPause() {
super.onPause();
mGLView.onPause();
/*
if (mAudioThread != null) {
// request audio stop
mStreams.AutoStop();
// wait the thread ended ...
try {
mAudioThread.join();
} catch(InterruptedException e) { }
if (mAudioStarted == true) {
Log.e("EwolActivity", "Pause audio interface");
if (mAudioThread != null) {
// request audio stop
mStreams.AutoStop();
// wait the thread ended ...
try {
mAudioThread.join();
} catch(InterruptedException e) { }
mAudioThread = null;
}
}
*/
EWOL.onPause();
}
@ -314,6 +325,52 @@ public abstract class EwolActivity extends Activity implements EwolCallback, Ewo
*/
}
public int audioGetDeviceCount() {
//Log.e("EwolActivity", "Get device List");
return 1;
}
public String audioGetDeviceProperty(int idDevice) {
if (idDevice == 0) {
return "speaker:out:8000,16000,24000,32000,48000,96000:2:s16";
} else {
return "::::";
}
}
public boolean audioOpenDevice(int idDevice, int freq, int nbChannel, int format) {
if (idDevice == 0) {
mAudioStarted = true;
mAudioThread = new Thread(mStreams);
if (mAudioThread != null) {
mAudioThread.start();
return true;
}
return false;
} else {
Log.e("EwolActivity", "can not open : error unknow device ...");
return false;
}
}
public boolean audioCloseDevice(int idDevice) {
if (idDevice == 0) {
if (mAudioThread != null) {
// request audio stop
mStreams.AutoStop();
// wait the thread ended ...
try {
mAudioThread.join();
} catch(InterruptedException e) { }
mAudioThread = null;
}
mAudioStarted = false;
return true;
} else {
Log.e("EwolActivity", "can not close : error unknow device ...");
return false;
}
}
}

View File

@ -12,6 +12,7 @@ import android.media.AudioTrack;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.util.Log;
// import the ewol package :
/* no need in same package... */
@ -30,10 +31,13 @@ public class EwolAudioTask implements Runnable, EwolConstants
// constructor :
public EwolAudioTask(Ewol ewolInstance) {
EWOL = ewolInstance;
m_stopAudioThreads = false;
}
public void run() {
Log.e("audioEWOL", "RUN (start)");
if(m_musicTrack != null) {
Log.e("audioEWOL", " ==> rejected");
return;
}
@ -52,18 +56,28 @@ public class EwolAudioTask implements Runnable, EwolConstants
bufferSize,
AudioTrack.MODE_STREAM);
m_musicTrack.play();
m_stopAudioThreads = false;
//m_musicTrack.setPositionNotificationPeriod(2048);
while (!m_stopAudioThreads) {
// Fill buffer with PCM data from C++
EWOL.audioPlayback(streamBuffer, NATIVE_AUDIO_BUFFER_SIZE, nbChannels);
int xxx = NATIVE_AUDIO_BUFFER_SIZE;
/*
while (xxx>0) {
Log.e("audioEWOL", (NATIVE_AUDIO_BUFFER_SIZE-xxx) + " data : " + streamBuffer[NATIVE_AUDIO_BUFFER_SIZE-xxx]);
xxx--;
}
*/
// Stream PCM data into the music AudioTrack
m_musicTrack.write(streamBuffer, 0, NATIVE_AUDIO_BUFFER_SIZE);
}
m_musicTrack.flush();
m_musicTrack.stop();
m_musicTrack = null;
streamBuffer = null;
Log.e("audioEWOL", "RUN (stop)");
}
public void Pause() {
if(m_musicTrack == null) {

View File

@ -15,6 +15,8 @@ public interface EwolCallback {
public void orientationUpdate(int screenMode);
public void titleSet(String value);
public void stop();
public String getClipBoardString();
public void setClipBoardString(String data);
public int audioGetDeviceCount();
public String audioGetDeviceProperty(int idDevice);
public boolean audioOpenDevice(int idDevice, int freq, int nbChannel, int format);
public boolean audioCloseDevice(int idDevice);
}

View File

@ -188,4 +188,24 @@ public abstract class EwolWallpaper extends WallpaperService implements EwolCall
public void stop() {
Log.d("EwolCallback", "STOP is not implemented ...");
}
public int audioGetDeviceCount() {
Log.e("EwolActivity", "Get device List");
return 0;
}
public String audioGetDeviceProperty(int idDevice) {
Log.e("EwolActivity", "Get device property");
return "";
}
public boolean audioOpenDevice(int idDevice, int freq, int nbChannel, int format) {
Log.e("EwolActivity", "Open device");
return false;
}
public boolean audioCloseDevice(int idDevice) {
Log.e("EwolActivity", "Close device");
return false;
}
}

View File

@ -33,6 +33,7 @@ int64_t ewol::getTime(void) {
static JavaVM* g_JavaVM=NULL; // global acces on the unique JVM !!!
etk::Mutex g_interfaceMutex;
etk::Mutex g_interfaceAudioMutex;
void java_check_exception(JNIEnv* _env) {
@ -64,6 +65,11 @@ class AndroidContext : public ewol::Context {
jmethodID m_javaMethodEwolActivitySetTitle;
jmethodID m_javaMethodEwolActivitySetClipBoardString;
jmethodID m_javaMethodEwolActivityGetClipBoardString;
// List of all Audio interface :
jmethodID m_javaMethodEwolActivityAudioGetDeviceCount;
jmethodID m_javaMethodEwolActivityAudioGetDeviceProperty;
jmethodID m_javaMethodEwolActivityAudioOpenDevice;
jmethodID m_javaMethodEwolActivityAudioCloseDevice;
jclass m_javaDefaultClassString; //!< default string class
int32_t m_currentHeight;
ewol::key::Special m_guiKeyBoardSpecialKeyMode;//!< special key of the android system :
@ -93,9 +99,15 @@ class AndroidContext : public ewol::Context {
m_javaMethodEwolActivitySetTitle(0),
m_javaMethodEwolActivitySetClipBoardString(0),
m_javaMethodEwolActivityGetClipBoardString(0),
m_javaMethodEwolActivityAudioGetDeviceCount(0),
m_javaMethodEwolActivityAudioGetDeviceProperty(0),
m_javaMethodEwolActivityAudioOpenDevice(0),
m_javaMethodEwolActivityAudioCloseDevice(0),
m_javaDefaultClassString(0),
m_currentHeight(0),
m_clipBoardOwnerStd(false) {
m_clipBoardOwnerStd(false),
m_audioCallBack(NULL),
m_audioCallBackUserData(NULL) {
EWOL_DEBUG("*******************************************");
if (m_javaApplicationType == appl_application) {
EWOL_DEBUG("** set JVM Pointer (application) **");
@ -122,6 +134,7 @@ class AndroidContext : public ewol::Context {
m_JavaVirtualMachinePointer = NULL;
return;
}
bool functionCallbackIsMissing = false;
bool ret= false;
ret = safeInitMethodID(m_javaMethodEwolActivitySetTitle,
m_javaClassEwolCallback,
@ -129,7 +142,8 @@ class AndroidContext : public ewol::Context {
"(Ljava/lang/String;)V");
if (ret == false) {
java_check_exception(_env);
return;
EWOL_ERROR("system can not start without function : titleSet");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodEwolCallbackStop,
@ -138,7 +152,8 @@ class AndroidContext : public ewol::Context {
"()V");
if (ret == false) {
java_check_exception(_env);
return;
EWOL_ERROR("system can not start without function : stop");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodEwolCallbackEventNotifier,
@ -147,7 +162,8 @@ class AndroidContext : public ewol::Context {
"([Ljava/lang/String;)V");
if (ret == false) {
java_check_exception(_env);
return;
EWOL_ERROR("system can not start without function : eventNotifier");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodEwolCallbackKeyboardUpdate,
@ -156,7 +172,8 @@ class AndroidContext : public ewol::Context {
"(Z)V");
if (ret == false) {
java_check_exception(_env);
return;
EWOL_ERROR("system can not start without function : keyboardUpdate");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodEwolCallbackOrientationUpdate,
@ -165,7 +182,8 @@ class AndroidContext : public ewol::Context {
"(I)V");
if (ret == false) {
java_check_exception(_env);
return;
EWOL_ERROR("system can not start without function : orientationUpdate");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodEwolActivitySetClipBoardString,
@ -174,7 +192,8 @@ class AndroidContext : public ewol::Context {
"(Ljava/lang/String;)V");
if (ret == false) {
java_check_exception(_env);
return;
EWOL_ERROR("system can not start without function : setClipBoardString");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodEwolActivityGetClipBoardString,
@ -183,18 +202,64 @@ class AndroidContext : public ewol::Context {
"()Ljava/lang/String;");
if (ret == false) {
java_check_exception(_env);
return;
EWOL_ERROR("system can not start without function : getClipBoardString");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodEwolActivityAudioGetDeviceCount,
m_javaClassEwolCallback,
"audioGetDeviceCount",
"()I");
if (ret == false) {
java_check_exception(_env);
EWOL_ERROR("system can not start without function : audioGetDeviceCount");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodEwolActivityAudioGetDeviceProperty,
m_javaClassEwolCallback,
"audioGetDeviceProperty",
"(I)Ljava/lang/String;");
if (ret == false) {
java_check_exception(_env);
EWOL_ERROR("system can not start without function : audioGetDeviceProperty");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodEwolActivityAudioOpenDevice,
m_javaClassEwolCallback,
"audioOpenDevice",
"(IIII)Z");
if (ret == false) {
java_check_exception(_env);
EWOL_ERROR("system can not start without function : audioOpenDevice");
functionCallbackIsMissing = true;
}
ret = safeInitMethodID(m_javaMethodEwolActivityAudioCloseDevice,
m_javaClassEwolCallback,
"audioCloseDevice",
"(I)Z");
if (ret == false) {
java_check_exception(_env);
EWOL_ERROR("system can not start without function : audioCloseDevice");
functionCallbackIsMissing = true;
}
m_javaObjectEwolCallback = _env->NewGlobalRef(_objCallback);
//javaObjectEwolCallbackAndActivity = objCallback;
if (m_javaObjectEwolCallback == NULL) {
functionCallbackIsMissing = true;
}
m_javaDefaultClassString = m_JavaVirtualMachinePointer->FindClass("java/lang/String" );
if (m_javaDefaultClassString == 0) {
EWOL_ERROR("C->java : Can't find java/lang/String" );
// remove access on the virtual machine :
m_JavaVirtualMachinePointer = NULL;
return;
functionCallbackIsMissing = true;
}
if (functionCallbackIsMissing == true) {
EWOL_CRITICAL(" mission one function ==> system can not work withut it...");
}
}
}
@ -281,6 +346,110 @@ class AndroidContext : public ewol::Context {
break;
}
}
int32_t audioGetDeviceCount(void) {
// Request the clipBoard :
EWOL_DEBUG("C->java : audio get device count");
if (m_javaApplicationType == appl_application) {
int status;
if(!java_attach_current_thread(&status)) {
return 0;
}
EWOL_DEBUG("Call CallIntMethod ...");
//Call java ...
jint ret = m_JavaVirtualMachinePointer->CallIntMethod(m_javaObjectEwolCallback, m_javaMethodEwolActivityAudioGetDeviceCount);
// manage execption :
java_check_exception(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
return (int32_t)ret;
} else {
EWOL_ERROR("C->java : can not get audio device count");
}
return 0;
}
std::string audioGetDeviceProperty(int32_t _idDevice) {
// Request the clipBoard :
EWOL_DEBUG("C->java : audio get device count");
if (m_javaApplicationType == appl_application) {
int status;
if(!java_attach_current_thread(&status)) {
return "";
}
//Call java ...
jstring returnString = (jstring) m_JavaVirtualMachinePointer->CallObjectMethod(m_javaObjectEwolCallback, m_javaMethodEwolActivityAudioGetDeviceProperty, _idDevice);
const char *js = m_JavaVirtualMachinePointer->GetStringUTFChars(returnString, NULL);
std::string retString(js);
m_JavaVirtualMachinePointer->ReleaseStringUTFChars(returnString, js);
//m_JavaVirtualMachinePointer->DeleteLocalRef(returnString);
// manage execption :
java_check_exception(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
return retString;
} else {
EWOL_ERROR("C->java : can not get audio device count");
}
return "";
}
private:
AndroidAudioCallback m_audioCallBack;
void* m_audioCallBackUserData;
public:
bool audioOpenDevice(int32_t _idDevice,
int32_t _freq,
int32_t _nbChannel,
int32_t _format,
AndroidAudioCallback _callback,
void* _userData) {
if (m_audioCallBack != NULL) {
EWOL_ERROR("AudioCallback already started ...");
return false;
}
// Request the clipBoard :
EWOL_DEBUG("C->java : audio get device count");
if (m_javaApplicationType == appl_application) {
int status;
if(!java_attach_current_thread(&status)) {
return false;
}
//Call java ...
jboolean ret = m_JavaVirtualMachinePointer->CallBooleanMethod(m_javaObjectEwolCallback, m_javaMethodEwolActivityAudioOpenDevice, _idDevice, _freq, _nbChannel, _format);
// manage execption :
java_check_exception(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
if (ret == true) {
m_audioCallBack = _callback;
m_audioCallBackUserData = _userData;
}
return (bool)ret;
} else {
EWOL_ERROR("C->java : can not get audio device count");
}
return false;
}
bool audioCloseDevice(int32_t _idDevice) {
if (m_audioCallBack == NULL) {
EWOL_ERROR("AudioCallback Not started ...");
return false;
}
// Request the clipBoard :
EWOL_DEBUG("C->java : audio get device count");
if (m_javaApplicationType == appl_application) {
int status;
if(!java_attach_current_thread(&status)) {
return false;
}
//Call java ...
jboolean ret = m_JavaVirtualMachinePointer->CallBooleanMethod(m_javaObjectEwolCallback, m_javaMethodEwolActivityAudioCloseDevice, _idDevice);
// manage execption :
java_check_exception(m_JavaVirtualMachinePointer);
java_detach_current_thread(status);
m_audioCallBack = NULL;
m_audioCallBackUserData = NULL;
return (bool)ret;
} else {
EWOL_ERROR("C->java : can not get audio device count");
}
return false;
}
private:
bool java_attach_current_thread(int *_rstatus) {
EWOL_DEBUG("C->java : call java");
@ -431,6 +600,13 @@ class AndroidContext : public ewol::Context {
m_currentHeight = _size.y();
ewol::Context::OS_Resize(_size);
}
void audioPlayback(void* _dataOutput, int32_t _frameRate) {
if (m_audioCallBack != NULL) {
//EWOL_DEBUG("IO Audio event request: Frames=" << _frameRate);
m_audioCallBack(_dataOutput, _frameRate, m_audioCallBackUserData);
}
}
};
static std::vector<AndroidContext*> s_listInstance;
@ -440,6 +616,7 @@ extern "C" {
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* _jvm, void* _reserved) {
// get the java virtual machine handle ...
etk::AutoLockMutex myLock(g_interfaceMutex);
etk::AutoLockMutex myLock2(g_interfaceAudioMutex);
g_JavaVM = _jvm;
EWOL_DEBUG("JNI-> load the jvm ..." );
return JNI_VERSION_1_6;
@ -447,6 +624,7 @@ extern "C" {
// JNI onUnLoad
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* _vm, void *_reserved) {
etk::AutoLockMutex myLock(g_interfaceMutex);
etk::AutoLockMutex myLock2(g_interfaceAudioMutex);
g_JavaVM = NULL;
EWOL_DEBUG("JNI-> Un-load the jvm ..." );
}
@ -849,7 +1027,7 @@ extern "C" {
s_listInstance[_id]->OS_Resize(vec2(_w, _h));
}
// TODO : Return tur or foalse to not redraw when the under draw has not be done (processing gain of time)
// TODO : Return true or false to not redraw when the under draw has not be done (processing gain of time)
void Java_org_ewol_Ewol_EWrenderDraw(JNIEnv* _env,
jobject _thiz,
jint _id) {
@ -870,7 +1048,7 @@ extern "C" {
jshortArray _location,
jint _frameRate,
jint _nbChannels) {
etk::AutoLockMutex myLock(g_interfaceMutex);
etk::AutoLockMutex myLock(g_interfaceAudioMutex);
if( _id >= s_listInstance.size()
|| _id<0
|| NULL == s_listInstance[_id] ) {
@ -882,9 +1060,10 @@ extern "C" {
jboolean isCopy;
jshort* dst = _env->GetShortArrayElements(_location, &isCopy);
if (NULL != dst) {
//ewol::audio::getData(dst, _frameRate, _nbChannels);
memset(dst, sizeof(jshort), _frameRate*_nbChannels);
//EWOL_DEBUG("IO Audio event request: Frames=" << _frameRate << " channels=" << _nbChannels);
s_listInstance[_id]->audioPlayback(dst, _frameRate);
}
//APPL_DEBUG("IO Audio event request: Frames=" << frameRate << " channels=" << nbChannels);
// TODO : Understand why it did not work corectly ...
//if (isCopy == JNI_TRUE) {
// release the short* pointer

View File

@ -287,6 +287,30 @@ namespace ewol {
* @return The curent time of the process
*/
static int64_t getTime(void);
#if defined(__TARGET_OS__Android)
public:
typedef void (*AndroidAudioCallback)(void* _data,
int32_t _size,
void* _userData);
// Android specific audio interface :
virtual int32_t audioGetDeviceCount(void) {
return 0;
}
virtual std::string audioGetDeviceProperty(int32_t _idDevice) {
return "";
}
virtual bool audioOpenDevice(int32_t _idDevice,
int32_t _freq,
int32_t _nbChannel,
int32_t _format,
AndroidAudioCallback _callback,
void* _userData) {
return false;
}
virtual bool audioCloseDevice(int32_t _idDevice) {
return false;
}
#endif
private:
// TODO : set user argument here ....

View File

@ -1,392 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <etk/types.h>
#include <ewol/renderer/audio/audio.h>
#include <ewol/renderer/audio/decWav.h>
#include <ewol/debug.h>
#include <math.h>
static int64_t currentTimePlaying = 0;
static bool musicMute = false;
static float musicVolume = 0;
static int32_t musicVolumeApply = 1<<16;
static int32_t musicFadingTime = 0;
static bool effectsMute = false;
static float effectsVolume = 0;
static int32_t effectsVolumeApply = 1<<16;
static bool isInit = false;
#ifdef BUILD_PORTAUDIO
# include <ewol/renderer/audio/interfacePortAudio.h>
#endif
void ewol::audio::init(void) {
if (isInit == true) {
EWOL_ERROR("multiple init requested ... at the audio system ...");
}
ewol::audio::effects::volumeSet(0);
ewol::audio::effects::muteSet(false);
ewol::audio::music::volumeSet(0);
ewol::audio::music::muteSet(false);
musicFadingTime = 100;
isInit = true;
#ifdef BUILD_PORTAUDIO
ewol::portAudio::init();
#endif
}
void ewol::audio::unInit(void) {
if (false == isInit) {
EWOL_ERROR("multiple un-init requested ... at the audio system ...");
return;
}
#ifdef BUILD_PORTAUDIO
ewol::portAudio::unInit();
#endif
musicMute = true;
musicVolume = -5000;
effectsMute = true;
effectsVolume = -5000;
musicFadingTime = 0;
}
static ewol::audio::AudioCallback userLocalCallback = NULL;
void ewol::audio::getData(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels) {
// TODO : set the real playing time ...
currentTimePlaying += 10;
if (_nbChannels != 2) {
EWOL_ERROR("TODO : Support the signal mono or more tha stereo ...");
return;
}
// reset the current buffer
memset(_bufferInterlace, 0, _nbSample*sizeof(int16_t)*_nbChannels);
// get user data ...
if (NULL != userLocalCallback) {
(*userLocalCallback)(_bufferInterlace, _nbSample, _nbChannels);
}
// get background music :
ewol::audio::music::getData(_bufferInterlace, _nbSample, _nbChannels);
// add effects :
ewol::audio::effects::getData(_bufferInterlace, _nbSample, _nbChannels);
static FILE * plop = fopen("/home/edupin/testFile48khzstereo.raw", "w");
if (plop!=NULL) {
fwrite(_bufferInterlace, sizeof(int16_t), _nbSample*_nbChannels, plop);
}
}
void ewol::audio::addCallbackOutput(ewol::audio::AudioCallback _userCallback) {
userLocalCallback = _userCallback;
}
void ewol::audio::music::fading(int32_t _timeMs) {
musicFadingTime = _timeMs;
musicFadingTime = etk_avg(-100, musicFadingTime, 20);
EWOL_INFO("Set music fading time at " << _timeMs << "ms == > " << musicFadingTime << "ms");
}
bool ewol::audio::music::listAdd(std::string _file) {
return false;
}
bool ewol::audio::music::listRm(std::string _file) {
return false;
}
bool ewol::audio::music::listClean(void) {
return false;
}
bool ewol::audio::music::listPrevious(void) {
return false;
}
bool ewol::audio::music::listNext(void) {
return false;
}
bool ewol::audio::music::listFirst(void) {
return false;
}
bool ewol::audio::music::listLast(void) {
return false;
}
bool ewol::audio::music::listPlay(void) {
return false;
}
bool ewol::audio::music::listStop(void) {
return false;
}
bool ewol::audio::music::play(std::string _file) {
return false;
}
bool ewol::audio::music::stop(void) {
return false;
}
float ewol::audio::music::volumeGet(void) {
return musicVolume;
}
static void uptateMusicVolume(void) {
if (musicMute == true) {
musicVolumeApply = 0;
} else {
// convert in an fixpoint value
// V2 = V1*10^(db/20)
double coef = pow(10, (musicVolume/20) );
musicVolumeApply = (int32_t)(coef * (double)(1<<16));
}
}
void ewol::audio::music::volumeSet(float _newVolume) {
musicVolume = _newVolume;
musicVolume = etk_avg(-1000, musicVolume, 40);
EWOL_INFO("Set music Volume at " << _newVolume << "dB == > " << musicVolume << "dB");
uptateMusicVolume();
}
bool ewol::audio::music::muteGet(void) {
return musicMute;
}
void ewol::audio::music::muteSet(bool _newMute) {
musicMute = _newMute;
EWOL_INFO("Set music Mute at " << _newMute);
uptateMusicVolume();
}
void ewol::audio::music::getData(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels) {
/*static int32_t maxValue = 0;
static float angle = 0;
maxValue +=10;
if (maxValue > 16000) {
maxValue = 0;
}
for (int iii = 0; iii<nbSample ; iii++) {
bufferInterlace[iii*2] = (float)maxValue * sin(angle/180.0 * M_PI);
bufferInterlace[iii*2+1] = bufferInterlace[iii*2];
angle+=0.9;
if (angle >= 360) {
angle -= 360.0;
}
}*/
}
//----------------------------------------------------------------------------------------------------------
// Effects ...
//----------------------------------------------------------------------------------------------------------
//liste d'effet
class EffectsLoaded {
public :
EffectsLoaded(std::string _file)
{
m_file = _file;
m_requestedTime = 1;
m_data = ewol::audio::wav::loadData(_file, 1, 48000, m_nbSamples);
if (m_data == NULL) {
// write an error ...
}
}
std::string m_file;
int32_t m_nbSamples;
int32_t m_requestedTime;
int16_t* m_data;
};
class RequestPlay {
private:
bool m_freeSlot;
EffectsLoaded* m_effect; // reference to the effects
int32_t m_playTime; // position in sample playing in the audio effects
public :
RequestPlay(EffectsLoaded * _effect) : m_freeSlot(false), m_effect(_effect), m_playTime(0) { };
void reset(EffectsLoaded * _effect) { m_effect=_effect; m_playTime=0; m_freeSlot=false; };
bool isFree(void) { return m_freeSlot; };
void play(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels)
{
if (true == m_freeSlot) {
return;
}
if (m_effect->m_data == NULL) {
m_freeSlot = true;
return;
}
int32_t processTimeMax = etk_min(_nbSample, m_effect->m_nbSamples - m_playTime);
processTimeMax = etk_max(0, processTimeMax);
int16_t * pointer = _bufferInterlace;
int16_t * newData = &m_effect->m_data[m_playTime];
//EWOL_DEBUG("AUDIO : Play slot... nb sample : " << processTimeMax << " playTime=" <<m_playTime << " nbCannels=" << nbChannels);
for (int32_t iii=0; iii<processTimeMax; iii++) {
// TODO : set volume and spacialisation ...
for (int32_t jjj=0; jjj<_nbChannels; jjj++) {
int32_t tmppp = *pointer + ((((int32_t)*newData)*effectsVolumeApply)>>16);
*pointer = etk_avg(-32767, tmppp, 32766);
//EWOL_DEBUG("AUDIO : element : " << *pointer);
pointer++;
}
newData++;
}
m_playTime += processTimeMax;
// check end of playing ...
if (m_effect->m_nbSamples <= m_playTime) {
m_freeSlot=true;
}
}
};
#include <vector>
std::vector<EffectsLoaded*> ListEffects;
std::vector<RequestPlay*> ListEffectsPlaying;
int32_t ewol::audio::effects::add(std::string _file) {
for (size_t iii=0; iii<ListEffects.size(); iii++) {
if (NULL != ListEffects[iii]) {
if (ListEffects[iii]->m_file == _file) {
ListEffects[iii]->m_requestedTime++;
return iii;
}
}
}
// effect does not exist ... create a new one ...
EffectsLoaded * tmpEffect = new EffectsLoaded(_file);
if (NULL == tmpEffect) {
EWOL_ERROR("Error to load the effects : \"" << _file << "\"");
return -1;
}
ListEffects.push_back(tmpEffect);
return ListEffects.size()-1;
}
void ewol::audio::effects::rm(int32_t _effectId) {
// find element ...
if (_effectId <0 || _effectId >= (int64_t)ListEffects.size()) {
EWOL_ERROR("Wrong effect ID : " << _effectId << " != [0.." << ListEffects.size()-1 << "] == > can not remove it ...");
return;
}
if (ListEffects[_effectId] == NULL) {
EWOL_ERROR("effect ID : " << _effectId << " == > has already been removed");
return;
}
// check number of requested
if (ListEffects[_effectId]->m_requestedTime <= 0) {
EWOL_ERROR("effect ID : " << _effectId << " == > request more than predicted a removed of an effects");
return;
}
ListEffects[_effectId]->m_requestedTime--;
// mark to be removed ... TODO : Really removed it when no other element readed it ...
// TODO : ...
}
void ewol::audio::effects::play(int32_t _effectId, float _xxx, float _yyy) {
if (_effectId <0 || _effectId >= (int64_t)ListEffects.size()) {
EWOL_ERROR("Wrong effect ID : " << _effectId << " != [0.." << ListEffects.size()-1 << "] == > can not play it ...");
return;
}
if (ListEffects[_effectId] == NULL) {
EWOL_ERROR("effect ID : " << _effectId << " == > has been removed");
return;
}
EWOL_VERBOSE("effect play : " << _effectId );
// try to find an empty slot :
for (size_t iii=0; iii<ListEffectsPlaying.size(); iii++) {
if (ListEffectsPlaying[iii]->isFree()) {
ListEffectsPlaying[iii]->reset(ListEffects[_effectId]);
return;
}
}
RequestPlay* newPlay = new RequestPlay(ListEffects[_effectId]);
if (NULL == newPlay) {
EWOL_CRITICAL("Allocation error of a playing element : " << _effectId);
return;
}
ListEffectsPlaying.push_back(newPlay);
}
float ewol::audio::effects::volumeGet(void) {
return effectsVolume;
}
static void uptateEffectVolume(void) {
if (effectsMute == true) {
effectsVolumeApply = 0;
} else {
// convert in an fixpoint value
// V2 = V1*10^(db/20)
double coef = pow(10, (effectsVolume/20) );
effectsVolumeApply = (int32_t)(coef * (double)(1<<16));
}
}
void ewol::audio::effects::volumeSet(float _newVolume) {
effectsVolume = _newVolume;
effectsVolume = etk_avg(-100, effectsVolume, 20);
EWOL_INFO("Set music Volume at " << _newVolume << "dB == > " << effectsVolume << "dB");
uptateEffectVolume();
}
bool ewol::audio::effects::muteGet(void) {
return effectsMute;
}
void ewol::audio::effects::muteSet(bool _newMute) {
effectsMute = _newMute;
EWOL_INFO("Set effects Mute at " << _newMute);
}
void ewol::audio::effects::getData(int16_t* _bufferInterlace, int32_t _nbSample, int32_t _nbChannels) {
for (size_t iii = 0; iii < ListEffectsPlaying.size(); ++iii) {
if (ListEffectsPlaying[iii]!= NULL) {
ListEffectsPlaying[iii]->play(_bufferInterlace, _nbSample, _nbChannels);
}
}
}

View File

@ -1,69 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __EWOL_AUDIO_H__
#define __EWOL_AUDIO_H__
#include <etk/types.h>
#include <etk/types.h>
namespace ewol {
namespace audio {
void init(void);
void unInit(void);
typedef void (*AudioCallback)(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels);
void addCallbackOutput(AudioCallback _userCallback);
void getData(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels);
namespace music {
void fading(int32_t _timeMs);
// list playing system : is cyclic ...
bool listAdd(std::string _file);
bool listRm(std::string _file);
bool listClean(void);
bool listPrevious(void);
bool listNext(void);
bool listFirst(void);
bool listLast(void);
bool listPlay(void); // List playing
bool listStop(void); // List stopping
bool play(std::string _file); // play specific file ... pause the list element;
bool stop(void);
// in db
float volumeGet(void);
void volumeSet(float _newVolume);
bool muteGet(void);
void muteSet(bool _newMute);
void getData(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels);
};
// note effect is loaded in memory (then don't create long effect) and unload only when requested
namespace effects {
// note : support file (Mono, 16bit, 48kHz) : .raw or .wav (no encodage) or .ogg (decoded with tremor lib)
int32_t add(std::string _file);
void rm(int32_t _effectId);
void play(int32_t _effectId, float _xxx, float _yyy);
// in db
float volumeGet(void);
void volumeSet(float _newVolume);
bool muteGet(void);
void muteSet(bool _newMute);
void getData(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels);
};
};
};
#endif

View File

@ -1,294 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <etk/types.h>
#include <etk/types.h>
#include <etk/os/FSNode.h>
#include <ewol/debug.h>
#include <ewol/renderer/audio/decWav.h>
typedef struct {
char riffTag[4]; //!< 00-03
uint32_t size; //!< 04-07
char waveTag[4]; //!< 08-0b
char fmtTag[4]; //!< 0c-0f
uint32_t waveFormatSize; //!< 10-13
struct {
uint16_t type; //!< 00-01
uint16_t channelCount; //!< 02-03
uint32_t samplesPerSec; //!< 04-07
uint32_t bytesPerSec; //!< 08-0b
uint16_t bytesPerFrame; //!< 0c-0d
uint16_t bitsPerSample; //!< 0e-0f
}waveFormat; //!< 14-23
char dataTag[4]; //!< 24-27
uint32_t dataSize; //!< 28-2b
}waveHeader;
#define CONVERT_UINT32(littleEndien,data) (littleEndien)?(((uint32_t)((uint8_t*)data)[0] | (uint32_t)((uint8_t*)data)[1] << 8 | (uint32_t)((uint8_t*)data)[2] << 16 | (uint32_t)((uint8_t*)data)[3] << 24)): \
(((uint32_t)((uint8_t*)data)[3] | (uint32_t)((uint8_t*)data)[2] << 8 | (uint32_t)((uint8_t*)data)[1] << 16 | (uint32_t)((uint8_t*)data)[0] << 24))
#define CONVERT_INT32(littleEndien,data) (littleEndien)?(((int32_t)((uint8_t*)data)[0] | (int32_t)((uint8_t*)data)[1] << 8 | (int32_t)((uint8_t*)data)[2] << 16 | (int32_t)((int8_t*)data)[3] << 24)): \
(((int32_t)((uint8_t*)data)[3] | (int32_t)((uint8_t*)data)[2] << 8 | (int32_t)((uint8_t*)data)[1] << 16 | (int32_t)((int8_t*)data)[0] << 24))
#define CONVERT_UINT24(littleEndien,data) (littleEndien)?(((uint32_t)((uint8_t*)data)[0]<<8 | (uint32_t)((uint8_t*)data)[1] << 16 | (uint32_t)((uint8_t*)data)[2] << 24)): \
(((uint32_t)((uint8_t*)data)[2]<<8 | (uint32_t)((uint8_t*)data)[1] << 16 | (uint32_t)((uint8_t*)data)[0] << 24))
#define CONVERT_INT24(littleEndien,data) (littleEndien)?(((int32_t)((uint8_t*)data)[0]<<8 | (int32_t)((uint8_t*)data)[1] << 16 | (int32_t)((int8_t*)data)[2] << 24)): \
(((int32_t)((uint8_t*)data)[2]<<8 | (int32_t)((uint8_t*)data)[1] << 16 | (int32_t)((int8_t*)data)[0] << 24))
#define CONVERT_UINT16(littleEndien,data) (littleEndien)?(((uint16_t)((uint8_t*)data)[0] | (uint16_t)((uint8_t*)data)[1] << 8)): \
(((uint16_t)((uint8_t*)data)[1] | (uint16_t)((uint8_t*)data)[0] << 8))
#define CONVERT_INT16(littleEndien,data) (littleEndien)?(((int16_t)((uint8_t*)data)[0] | (int16_t)((int8_t*)data)[1] << 8)): \
(((int16_t)((uint8_t*)data)[1] | (int16_t)((int8_t*)data)[0] << 8))
#define COMPR_PCM (1)
#define COMPR_MADPCM (2)
#define COMPR_ALAW (6)
#define COMPR_MULAW (7)
#define COMPR_ADPCM (17)
#define COMPR_YADPCM (20)
#define COMPR_GSM (49)
#define COMPR_G721 (64)
#define COMPR_MPEG (80)
int16_t * ewol::audio::wav::loadData(std::string filename, int8_t nbChan, int32_t frequency, int32_t & nbSampleOut) {
nbSampleOut = 0;
waveHeader myHeader;
memset(&myHeader, 0, sizeof(waveHeader));
etk::FSNode fileAccess(std::string("DATA:") + filename);
// Start loading the XML :
EWOL_DEBUG("open file (WAV) \"" << fileAccess << "\"");
if (false == fileAccess.exist()) {
EWOL_ERROR("File Does not exist : \"" << fileAccess << "\"");
return NULL;
}
int32_t fileSize = fileAccess.fileSize();
if (0 == fileSize) {
EWOL_ERROR("This file is empty : \"" << fileAccess << "\"");
return NULL;
}
if (false == fileAccess.fileOpenRead()) {
EWOL_ERROR("Can not open the file : \"" << fileAccess << "\"");
return NULL;
}
// try to find endienness :
if (fileSize < (int64_t)sizeof(waveHeader)) {
EWOL_ERROR("File : \"" << fileAccess << "\" == > has not enouth data inside might be minumum of " << (int32_t)(sizeof(waveHeader)));
return NULL;
}
// ----------------------------------------------
// read the header :
// ----------------------------------------------
if (fileAccess.fileRead(&myHeader.riffTag, 1, 4)!=4) {
EWOL_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return NULL;
}
bool littleEndien = false;
if( myHeader.riffTag[0] == 'R'
&& myHeader.riffTag[1] == 'I'
&& myHeader.riffTag[2] == 'F'
&& (myHeader.riffTag[3] == 'F' || myHeader.riffTag[3] == 'X') ) {
if (myHeader.riffTag[3] == 'F' ) {
littleEndien = true;
}
} else {
EWOL_ERROR("file: \"" << fileAccess << "\" Does not start with \"RIF\" " );
return NULL;
}
// get the data size :
unsigned char tmpData[32];
if (fileAccess.fileRead(tmpData, 1, 4)!=4) {
EWOL_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return NULL;
}
myHeader.size = CONVERT_UINT32(littleEndien, tmpData);
// get the data size :
if (fileAccess.fileRead(&myHeader.waveTag, 1, 4)!=4) {
EWOL_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return NULL;
}
if( myHeader.waveTag[0] != 'W'
|| myHeader.waveTag[1] != 'A'
|| myHeader.waveTag[2] != 'V'
|| myHeader.waveTag[3] != 'E' ) {
EWOL_ERROR("file: \"" << fileAccess << "\" This is not a wave file " << myHeader.waveTag[0] << myHeader.waveTag[1] << myHeader.waveTag[2] << myHeader.waveTag[3] );
return NULL;
}
// get the data size :
if (fileAccess.fileRead(&myHeader.fmtTag, 1, 4)!=4) {
EWOL_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return NULL;
}
if( myHeader.fmtTag[0] != 'f'
|| myHeader.fmtTag[1] != 'm'
|| myHeader.fmtTag[2] != 't'
|| myHeader.fmtTag[3] != ' ' ) {
EWOL_ERROR("file: \"" << fileAccess << "\" header error ..." << myHeader.fmtTag[0] << myHeader.fmtTag[1] << myHeader.fmtTag[2] << myHeader.fmtTag[3]);
return NULL;
}
// get the data size :
if (fileAccess.fileRead(tmpData, 1, 4)!=4) {
EWOL_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return NULL;
}
myHeader.waveFormatSize = CONVERT_UINT32(littleEndien, tmpData);
if (myHeader.waveFormatSize != 16) {
EWOL_ERROR("file : \"" << fileAccess << "\" == > header error ...");
return NULL;
}
if (fileAccess.fileRead(tmpData, 1, 16)!=16) {
EWOL_ERROR("Can not 16 element in the file : \"" << fileAccess << "\"");
return NULL;
}
unsigned char * tmppp = tmpData;
myHeader.waveFormat.type = CONVERT_UINT16(littleEndien, tmppp);
tmppp += 2;
myHeader.waveFormat.channelCount = CONVERT_UINT16(littleEndien, tmppp);
tmppp += 2;
myHeader.waveFormat.samplesPerSec = CONVERT_UINT32(littleEndien, tmppp);
tmppp += 4;
myHeader.waveFormat.bytesPerSec = CONVERT_UINT32(littleEndien, tmppp);
tmppp += 4;
myHeader.waveFormat.bytesPerFrame = CONVERT_UINT16(littleEndien, tmppp);
tmppp += 2;
myHeader.waveFormat.bitsPerSample = CONVERT_UINT16(littleEndien, tmppp);
EWOL_DEBUG("audio properties : ");
EWOL_DEBUG(" type : " << myHeader.waveFormat.type);
EWOL_DEBUG(" channelCount : " << myHeader.waveFormat.channelCount);
EWOL_DEBUG(" samplesPerSec : " << myHeader.waveFormat.samplesPerSec);
EWOL_DEBUG(" bytesPerSec : " << myHeader.waveFormat.bytesPerSec);
EWOL_DEBUG(" bytesPerFrame : " << myHeader.waveFormat.bytesPerFrame);
EWOL_DEBUG(" bitsPerSample : " << myHeader.waveFormat.bitsPerSample);
// get the data size :
if (fileAccess.fileRead(&myHeader.dataTag, 1, 4)!=4) {
EWOL_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return NULL;
}
if( myHeader.dataTag[0] != 'd'
|| myHeader.dataTag[1] != 'a'
|| myHeader.dataTag[2] != 't'
|| myHeader.dataTag[3] != 'a' ) {
EWOL_ERROR("file: \"" << fileAccess << "\" header error ..." << myHeader.dataTag[0] << myHeader.dataTag[1] << myHeader.dataTag[2] << myHeader.dataTag[3]);
return NULL;
}
// get the data size :
if (fileAccess.fileRead(tmpData, 1, 4)!=4) {
EWOL_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return NULL;
}
myHeader.dataSize = CONVERT_UINT32(littleEndien, tmpData);
// ----------------------------------------------
// end of the header reading done ...
// ----------------------------------------------
//Parse the data and transform it if needed ...
if (COMPR_PCM != myHeader.waveFormat.type) {
EWOL_ERROR("File : \"" << fileAccess << "\" == > support only PCM compression ...");
return NULL;
}
if (myHeader.waveFormat.channelCount == 0 || myHeader.waveFormat.channelCount>2) {
EWOL_ERROR("File : \"" << fileAccess << "\" == > support only mono or stereo ..." << myHeader.waveFormat.channelCount);
return NULL;
}
if ( ! ( myHeader.waveFormat.bitsPerSample == 16
|| myHeader.waveFormat.bitsPerSample == 24
|| myHeader.waveFormat.bitsPerSample == 32 ) ) {
EWOL_ERROR("File : \"" << fileAccess << "\" == > not supported bit/sample ..." << myHeader.waveFormat.bitsPerSample);
return NULL;
}
if( ! ( 44100 == myHeader.waveFormat.samplesPerSec
|| 48000 == myHeader.waveFormat.samplesPerSec) ) {
EWOL_ERROR("File : \"" << fileAccess << "\" == > not supported frequency " << myHeader.waveFormat.samplesPerSec << " != 48000");
return NULL;
}
EWOL_DEBUG(" dataSize : " << myHeader.dataSize);
//int32_t globalDataSize = myHeader.dataSize;
int32_t nbSample = (myHeader.dataSize/((myHeader.waveFormat.bitsPerSample/8)*myHeader.waveFormat.channelCount));
int32_t outputSize = nbChan*nbSample;
int16_t * outputData = (int16_t*)malloc(outputSize*sizeof(int16_t));
if (NULL == outputData) {
EWOL_ERROR("Allocation ERROR try to allocate " << (int32_t)(outputSize*sizeof(int16_t) ) << "bytes");
return NULL;
}
int16_t * tmpOut = outputData;
for( int32_t iii=0; iii<nbSample; iii++) {
int32_t left;
int32_t right;
char audioSample[8];
if (myHeader.waveFormat.bitsPerSample == 16) {
if (myHeader.waveFormat.channelCount == 1) {
if (fileAccess.fileRead(audioSample, 1, 2)!=2) {
EWOL_ERROR("Read Error at position : " << iii);
return NULL;
}
left = ((int32_t)((int16_t)CONVERT_INT16(littleEndien, audioSample))) << 16;
right = left;
} else {
if (fileAccess.fileRead(audioSample, 1, 4)!=4) {
EWOL_ERROR("Read Error at position : " << iii);
return NULL;
}
left = (int32_t)((int16_t)CONVERT_INT16(littleEndien, audioSample)) << 16;
right = (int32_t)((int16_t)CONVERT_INT16(littleEndien, audioSample+2)) << 16;
}
} else if (myHeader.waveFormat.bitsPerSample == 24) {
if (myHeader.waveFormat.channelCount == 1) {
if (fileAccess.fileRead(audioSample, 1, 3)!=3) {
EWOL_ERROR("Read Error at position : " << iii);
return NULL;
}
left = CONVERT_INT24(littleEndien, audioSample);
right = left;
} else {
if (fileAccess.fileRead(audioSample, 1, 6)!=6) {
EWOL_ERROR("Read Error at position : " << iii);
return NULL;
}
left = CONVERT_INT24(littleEndien, audioSample);
right = CONVERT_INT24(littleEndien, audioSample+3);
}
} else if (myHeader.waveFormat.bitsPerSample == 32) {
if (myHeader.waveFormat.channelCount == 1) {
if (fileAccess.fileRead(audioSample, 1, 4)!=4) {
EWOL_ERROR("Read Error at position : " << iii);
return NULL;
}
left = CONVERT_INT32(littleEndien, audioSample);
right = left;
} else {
if (fileAccess.fileRead(audioSample, 1, 8)!=8) {
EWOL_ERROR("Read Error at position : " << iii);
return NULL;
}
left = CONVERT_INT32(littleEndien, audioSample);
right = CONVERT_INT32(littleEndien, audioSample+4);
}
}
if (nbChan == 1) {
*tmpOut++ = (int16_t)(((left>>1) + (right>>1))>>16);
} else {
*tmpOut++ = (int16_t)(left>>16);
*tmpOut++ = (int16_t)(left>>16);
}
}
// close the file:
fileAccess.fileClose();
nbSampleOut = nbSample;
return outputData;
}

View File

@ -1,24 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __EWOL_AUDIO_DEC_WAV_H__
#define __EWOL_AUDIO_DEC_WAV_H__
#include <etk/types.h>
#include <etk/types.h>
namespace ewol {
namespace audio {
namespace wav {
int16_t * loadData(std::string filename, int8_t nbChan, int32_t frequency, int32_t & nbSampleOut);
};
};
};
#endif

View File

@ -1,103 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <etk/types.h>
#include <etk/types.h>
#include <ewol/debug.h>
#include <ewol/renderer/audio/interfacePortAudio.h>
#include <ewol/renderer/audio/audio.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <poll.h>
#include <math.h>
extern "C" {
#include <portaudio/portaudio.h>
}
typedef struct {
int32_t sampleRate;
int32_t nbChanelsInput;
int32_t nbChanelsOutput;
int32_t frameSize;
} userOutputData;
userOutputData data;
PaStream *stream;
/* This routine will be called by the PortAudio engine when audio is needed.
It may called at interrupt level on some machines so don't do anything
that could mess up the system like calling malloc() or free().
*/
static int patestCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData ) {
/* Cast data passed through stream to our structure. */
userOutputData *data = (userOutputData*)userData;
// no use of the input buffer ... (mightt be NULL)
(void) inputBuffer;
ewol::audio::getData((int16_t*)outputBuffer, framesPerBuffer, data->nbChanelsOutput);
return 0;
}
#define SAMPLE_RATE (44100)
void ewol::portAudio::init(void) {
PaError err;
EWOL_DEBUG("Create Audio Thread...");
err = Pa_Initialize();
if( err != paNoError ) {
EWOL_ERROR("PortAudio error: " << (char*)Pa_GetErrorText(err) );
return;
}
data.sampleRate = 48000;
data.nbChanelsInput = 0;
data.nbChanelsOutput = 2;
data.frameSize = 256;
/* open an audio I/O stream. */
err = Pa_OpenDefaultStream( &stream, data.nbChanelsInput, data.nbChanelsOutput,
paInt16, data.sampleRate, data.frameSize,
patestCallback, &data );
if( err != paNoError ) {
EWOL_ERROR("PortAudio error: " << (char*)Pa_GetErrorText(err) );
return;
}
err = Pa_StartStream( stream );
if( err != paNoError ) {
EWOL_ERROR("PortAudio error: " << (char*)Pa_GetErrorText(err) );
return;
}
EWOL_DEBUG("Create Audio Thread ... might have start");
}
void ewol::portAudio::unInit(void) {
PaError err;
// destroy the thread ...
EWOL_DEBUG("Wait end of the thread ...");
err = Pa_StopStream( stream );
if( err != paNoError ) {
EWOL_ERROR("PortAudio error: " << (char*)Pa_GetErrorText(err) );
return;
}
err = Pa_CloseStream( stream );
if( err != paNoError ) {
EWOL_ERROR("PortAudio error: " << (char*)Pa_GetErrorText(err) );
return;
}
err = Pa_Terminate();
if( err != paNoError ) {
EWOL_ERROR("PortAudio error: " << (char*)Pa_GetErrorText(err) );
return;
}
EWOL_DEBUG("Create Audio Thread ... might have stop");
}

View File

@ -1,21 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __EWOL_PORT_AUDIO_H__
#define __EWOL_PORT_AUDIO_H__
#include <etk/types.h>
namespace ewol {
namespace portAudio {
void init(void);
void unInit(void);
};
};
#endif