add basic audio playing on linux
This commit is contained in:
parent
569b191389
commit
d41a83a7c6
@ -16,7 +16,7 @@ LOCAL_STATIC_LIBRARIES := etk libfreetype tinyxml libzip libpng agg
|
||||
LOCAL_C_INCLUDES := -I$(LOCAL_PATH)
|
||||
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
||||
LOCAL_EXPORT_LDLIBS := -lGL -lGLU -lz -lX11
|
||||
LOCAL_EXPORT_LDLIBS := -lGL -lGLU -lz -lX11 -lasound
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
LOCAL_CFLAGS := -D__PLATFORM__Linux \
|
||||
@ -46,10 +46,11 @@ include $(LOCAL_PATH)/file.mk
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
ewol/base/guiX11.cpp \
|
||||
ewol/Audio/audioAlsa.cpp \
|
||||
$(FILE_LIST)
|
||||
|
||||
# Ewol Test Software :
|
||||
LOCAL_LDLIBS := -lGL -lGLU -lz -lX11
|
||||
LOCAL_LDLIBS := -lGL -lGLU -lz -lX11 -lasound
|
||||
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
@ -23,7 +23,9 @@
|
||||
*/
|
||||
|
||||
#include <etk/Types.h>
|
||||
#include <ewol/Audo/audio.h>
|
||||
#include <ewol/Audio/audio.h>
|
||||
#include <ewol/Debug.h>
|
||||
#include <math.h>
|
||||
|
||||
static bool musicMute = true;
|
||||
static float musicVolume = -5000;
|
||||
@ -34,6 +36,9 @@ static float effectsVolume = -5000;
|
||||
|
||||
static bool isInit = false;
|
||||
|
||||
#ifdef __PLATFORM__Linux
|
||||
# include <ewol/Audio/audioAlsa.h>
|
||||
#endif
|
||||
|
||||
void ewol::audio::Init(void)
|
||||
{
|
||||
@ -46,6 +51,9 @@ void ewol::audio::Init(void)
|
||||
effectsVolume = 0;
|
||||
musicFadingTime = 100;
|
||||
isInit = true;
|
||||
#ifdef __PLATFORM__Linux
|
||||
ewol::audioAlsa::Init();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -53,7 +61,11 @@ void ewol::audio::UnInit(void)
|
||||
{
|
||||
if (false == isInit) {
|
||||
EWOL_ERROR("multiple un-init requested ... at the audio system ...");
|
||||
return;
|
||||
}
|
||||
#ifdef __PLATFORM__Linux
|
||||
ewol::audioAlsa::UnInit();
|
||||
#endif
|
||||
musicMute = true;
|
||||
musicVolume = -5000;
|
||||
effectsMute = true;
|
||||
@ -61,6 +73,24 @@ void ewol::audio::UnInit(void)
|
||||
musicFadingTime = 0;
|
||||
}
|
||||
|
||||
static float angle = 0;
|
||||
|
||||
void ewol::audio::GetData(int16_t * bufferInterlace, int32_t nbSample, int32_t nbChannels)
|
||||
{
|
||||
if (nbChannels != 2) {
|
||||
EWOL_ERROR("TODO : Support the signal mono or more tha stereo ...");
|
||||
return;
|
||||
}
|
||||
for (int iii = 0; iii<nbSample ; iii++) {
|
||||
bufferInterlace[iii*2] = 32000.0 * sin(angle/180.0 * M_PI);
|
||||
bufferInterlace[iii*2+1] = bufferInterlace[iii*2];
|
||||
angle+=0.9;
|
||||
if (angle>=360) {
|
||||
angle -= 360.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ewol::audio::music::Fading(int32_t timeMs)
|
||||
{
|
||||
@ -112,11 +142,6 @@ erreurCode_te ewol::audio::music::ListLast(void)
|
||||
}
|
||||
|
||||
|
||||
erreurCode_te ewol::audio::music::ListLast(void)
|
||||
{
|
||||
return ERR_FAIL;
|
||||
}
|
||||
|
||||
|
||||
erreurCode_te ewol::audio::music::ListPlay(void)
|
||||
{
|
||||
@ -151,7 +176,7 @@ float ewol::audio::music::VolumeGet(void)
|
||||
}
|
||||
|
||||
|
||||
void ewol::audio::music::(float newVolume)
|
||||
void ewol::audio::music::VolumeSet(float newVolume)
|
||||
{
|
||||
musicVolume = newVolume;
|
||||
musicVolume = etk_avg(-100, musicVolume, 20);
|
||||
@ -201,7 +226,7 @@ float ewol::audio::effects::VolumeGet(void)
|
||||
|
||||
void ewol::audio::effects::VolumeSet(float newVolume)
|
||||
{
|
||||
effectsVolume = effectsVolume;
|
||||
effectsVolume = newVolume;
|
||||
effectsVolume = etk_avg(-100, effectsVolume, 20);
|
||||
EWOL_INFO("Set music Volume at " << newVolume << "dB ==> " << effectsVolume << "dB");
|
||||
}
|
||||
|
@ -26,11 +26,13 @@
|
||||
#define __EWOL_AUDIO_H__
|
||||
|
||||
#include <etk/Types.h>
|
||||
#include <etk/UString.h>
|
||||
|
||||
namespace ewol {
|
||||
namespace audio {
|
||||
void Init(void);
|
||||
void UnInit(void);
|
||||
void GetData(int16_t * bufferInterlace, int32_t nbSample, int32_t nbChannels);
|
||||
|
||||
namespace music {
|
||||
void Fading(int32_t timeMs);
|
||||
@ -42,7 +44,6 @@ namespace ewol {
|
||||
erreurCode_te ListNext(void);
|
||||
erreurCode_te ListFirst(void);
|
||||
erreurCode_te ListLast(void);
|
||||
erreurCode_te ListLast(void);
|
||||
erreurCode_te ListPlay(void); // List playing
|
||||
erreurCode_te ListStop(void); // List stopping
|
||||
|
||||
|
157
Sources/libewol/ewol/Audio/audioAlsa.cpp
Normal file
157
Sources/libewol/ewol/Audio/audioAlsa.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file ewol/Audio/audioAlsa.cpp
|
||||
* @brief Alsa ewol Audio interface (Sources)
|
||||
* @author Edouard DUPIN
|
||||
* @date 26/06/2012
|
||||
* @par Project
|
||||
* ewol
|
||||
*
|
||||
* @par Copyright
|
||||
* Copyright 2011 Edouard DUPIN, all right reserved
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY.
|
||||
*
|
||||
* Licence summary :
|
||||
* You can modify and redistribute the sources code and binaries.
|
||||
* You can send me the bug-fix
|
||||
*
|
||||
* Term of the licence in in the file licence.txt.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#include <etk/Types.h>
|
||||
#include <etk/UString.h>
|
||||
#include <ewol/Debug.h>
|
||||
#include <ewol/Audio/audioAlsa.h>
|
||||
#include <ewol/Audio/audio.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <math.h>
|
||||
/* Use the newer ALSA API */
|
||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
|
||||
static pthread_t audioHandleThread;
|
||||
static pthread_attr_t audioHandleThreadAttr;
|
||||
static bool g_stopRequested=false;
|
||||
|
||||
|
||||
static void* audioThread(void* param)
|
||||
{
|
||||
EWOL_DEBUG("==> Init audioAlsa Thread (START)");
|
||||
int rc;
|
||||
int size;
|
||||
snd_pcm_t *handle;
|
||||
snd_pcm_hw_params_t *params;
|
||||
unsigned int val;
|
||||
int dir;
|
||||
snd_pcm_uframes_t frames;
|
||||
char *buffer;
|
||||
|
||||
int32_t frequency = 48000;
|
||||
int32_t nbChan = 2;
|
||||
int32_t frameSize = 1024;
|
||||
|
||||
// Open PCM device name "default" to play audio on it ...
|
||||
rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
|
||||
if (rc < 0) {
|
||||
EWOL_ERROR("AUDIO : unable to open pcm device: " << (char*)snd_strerror(rc));
|
||||
// stop the thread ...
|
||||
pthread_exit(NULL);
|
||||
return;
|
||||
}
|
||||
// Allocate a hardware parameters object.
|
||||
snd_pcm_hw_params_alloca(¶ms);
|
||||
// Fill it in with default values.
|
||||
snd_pcm_hw_params_any(handle, params);
|
||||
|
||||
// Set the desired hardware parameters.
|
||||
// Interleaved mode
|
||||
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
// Signed 16-bit little-endian format
|
||||
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
|
||||
// number of channel : 2 (stereo) ==> might never need more for simple game
|
||||
snd_pcm_hw_params_set_channels(handle, params, nbChan);
|
||||
// Frequency : 48000 Hz
|
||||
val = frequency;
|
||||
snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
|
||||
// Set pushing data frameRate : 32 frames. ==> might be a little small ???
|
||||
frames = frameSize;
|
||||
snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
|
||||
// Write the parameters to the driver ==> and hope it work corectly ...
|
||||
rc = snd_pcm_hw_params(handle, params);
|
||||
if (rc < 0) {
|
||||
EWOL_ERROR("AUDIO : unable to set hw parameters: " << (char*)snd_strerror(rc));
|
||||
// stop the thread ...
|
||||
pthread_exit(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
EWOL_DEBUG("AUDIO : Audio Properties : nbChan=" << nbChan << ", freg=" << frequency << "Hz, frameRate=" << frameSize);
|
||||
// Use a buffer large enough to hold one period
|
||||
snd_pcm_hw_params_get_period_size(params, &frames, &dir);
|
||||
size = frames * sizeof(int16_t) * nbChan;
|
||||
buffer = (char *) malloc(size);
|
||||
EWOL_DEBUG("AUDIO : Buffer size= " << size);
|
||||
|
||||
// request the period time to display it ...
|
||||
snd_pcm_hw_params_get_period_time(params, &val, &dir);
|
||||
EWOL_DEBUG("AUDIO : periode time = " << (float)((float)val/1000.0) << "ms" );
|
||||
|
||||
EWOL_DEBUG("==> Init audioAlsa Thread (END)");
|
||||
while (g_stopRequested==false) {
|
||||
//request data from the standard system generation ...
|
||||
ewol::audio::GetData((int16_t*)buffer, frames, nbChan);
|
||||
// write it to ALSA system
|
||||
rc = snd_pcm_writei(handle, buffer, frames);
|
||||
if (rc == -EPIPE) {
|
||||
EWOL_ERROR("underrun occurred");
|
||||
// restart the Audio system
|
||||
snd_pcm_prepare(handle);
|
||||
} else if (rc < 0) {
|
||||
EWOL_ERROR("error from writei: " << (char*)snd_strerror(rc));
|
||||
} else if (rc != (int)frames) {
|
||||
EWOL_ERROR("short write, write " << rc << " frames");
|
||||
}
|
||||
}
|
||||
EWOL_DEBUG("==> Un-Init audioAlsa Thread (START)");
|
||||
snd_pcm_drain(handle);
|
||||
snd_pcm_close(handle);
|
||||
free(buffer);
|
||||
EWOL_DEBUG("==> Un-Init audioAlsa Thread (END)");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void ewol::audioAlsa::Init(void)
|
||||
{
|
||||
EWOL_DEBUG("Create Audio Thread...");
|
||||
g_stopRequested=false;
|
||||
// create th thread ...
|
||||
pthread_setname_np(audioHandleThread, "ewol_audio_thread");
|
||||
pthread_create(&audioHandleThread, &audioHandleThreadAttr, audioThread, NULL);
|
||||
pthread_attr_init(&audioHandleThreadAttr);
|
||||
pthread_attr_setdetachstate(&audioHandleThreadAttr, PTHREAD_CREATE_JOINABLE);
|
||||
EWOL_DEBUG("Create Audio Thread ... might have start");
|
||||
}
|
||||
|
||||
void ewol::audioAlsa::UnInit(void)
|
||||
{
|
||||
g_stopRequested=true;
|
||||
// destroy the thread ...
|
||||
EWOL_DEBUG("Wait end of the thread ...");
|
||||
// Wait end of the thread
|
||||
pthread_join(audioHandleThread, NULL);
|
||||
|
||||
EWOL_DEBUG("Create Audio Thread ... might have stop");
|
||||
|
||||
}
|
||||
|
37
Sources/libewol/ewol/Audio/audioAlsa.h
Normal file
37
Sources/libewol/ewol/Audio/audioAlsa.h
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file ewol/Audio/audioAlsa.h
|
||||
* @brief Alsa ewol Audio interface (header)
|
||||
* @author Edouard DUPIN
|
||||
* @date 26/06/2012
|
||||
* @par Project
|
||||
* ewol
|
||||
*
|
||||
* @par Copyright
|
||||
* Copyright 2011 Edouard DUPIN, all right reserved
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY.
|
||||
*
|
||||
* Licence summary :
|
||||
* You can modify and redistribute the sources code and binaries.
|
||||
* You can send me the bug-fix
|
||||
*
|
||||
* Term of the licence in in the file licence.txt.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __EWOL_ALSA_AUDIO_H__
|
||||
#define __EWOL_ALSA_AUDIO_H__
|
||||
|
||||
#include <etk/Types.h>
|
||||
|
||||
namespace ewol {
|
||||
namespace audioAlsa {
|
||||
void Init(void);
|
||||
void UnInit(void);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
@ -52,6 +52,7 @@ FILE_LIST = ewol/ewol.cpp \
|
||||
ewol/widget/WidgetScrolled.cpp \
|
||||
ewol/widgetMeta/FileChooser.cpp \
|
||||
ewol/widgetMeta/ColorChooser.cpp \
|
||||
ewol/theme/Theme.cpp
|
||||
ewol/theme/Theme.cpp \
|
||||
ewol/Audio/audio.cpp
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user