forked from enlightenment/efl
ecore_audio: Add rudimentary ALSA support
By rudimentary I mean I barely got it to work. For my particular test case. It will not work for you and needs lots of love until it can be used. Signed-off-by: Daniel Willmann <d.willmann@samsung.com> SVN revision: 80999
This commit is contained in:
parent
d49fe90b18
commit
eb15fa9e9c
|
@ -76,6 +76,11 @@ ecore_audio_init(void)
|
|||
ECORE_AUDIO_OUTPUT_INPUT_ADDED = ecore_event_type_new();
|
||||
ECORE_AUDIO_OUTPUT_INPUT_REMOVED = ecore_event_type_new();
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
mod = ecore_audio_alsa_init();
|
||||
if (mod)
|
||||
ecore_audio_modules = eina_list_append(ecore_audio_modules, mod);
|
||||
#endif
|
||||
#ifdef HAVE_PULSE
|
||||
mod = ecore_audio_pulse_init();
|
||||
if (mod)
|
||||
|
@ -107,6 +112,9 @@ ecore_audio_shutdown(void)
|
|||
|
||||
/* FIXME: Shutdown all the inputs and outputs first */
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
ecore_audio_alsa_shutdown();
|
||||
#endif
|
||||
#ifdef HAVE_PULSE
|
||||
ecore_audio_pulse_shutdown();
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_FEATURES_H
|
||||
#include <features.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
#include "ecore_audio_private.h"
|
||||
|
||||
static Ecore_Audio_Module *alsa_module = NULL;
|
||||
|
||||
static Ecore_Audio_Object *
|
||||
_alsa_output_new(Ecore_Audio_Object *output)
|
||||
{
|
||||
int ret;
|
||||
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||
struct _Ecore_Audio_Alsa *alsa;
|
||||
|
||||
alsa = calloc(1, sizeof(struct _Ecore_Audio_Alsa));
|
||||
if (!alsa)
|
||||
{
|
||||
ERR("Could not allocate memory for private structure.");
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->module_data = alsa;
|
||||
|
||||
ret = snd_pcm_open(&alsa->handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERR("Could not open playback: %s", snd_strerror(ret));
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* XXX: Make configurable */
|
||||
ret = snd_pcm_set_params(alsa->handle, SND_PCM_FORMAT_FLOAT, SND_PCM_ACCESS_RW_INTERLEAVED, 2, 44100, 1, 500000);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERR("Could not set parameters: %s", snd_strerror(ret));
|
||||
goto err;
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
err:
|
||||
free(out->module_data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_alsa_output_del(Ecore_Audio_Object *output)
|
||||
{
|
||||
free(output->module_data);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_alsa_output_async_cb(Ecore_Audio_Object *output)
|
||||
{
|
||||
unsigned char *data;
|
||||
int size, ret;
|
||||
snd_pcm_sframes_t avail;
|
||||
Ecore_Audio_Output *out = output;
|
||||
Ecore_Audio_Input *in = eina_list_data_get(out->inputs);
|
||||
struct _Ecore_Audio_Alsa *alsa = (struct _Ecore_Audio_Alsa *)output->module_data;
|
||||
|
||||
/* XXX: Error handling! */
|
||||
avail = snd_pcm_avail_update(alsa->handle);
|
||||
ERR("Aval: %i", avail);
|
||||
if (!avail)
|
||||
return EINA_TRUE;
|
||||
if (avail < 0)
|
||||
goto recover;
|
||||
|
||||
data = calloc(1, sizeof(float) * avail * 8);
|
||||
|
||||
size = in->module->in_ops->input_read((Ecore_Audio_Object *)in, data, avail*8);
|
||||
ERR("Read: %i", size);
|
||||
|
||||
ret = snd_pcm_writei(alsa->handle, data, size/8);
|
||||
ERR("Written: %i", ret);
|
||||
if (ret < 0) {
|
||||
recover:
|
||||
ERR(snd_strerror(ret));
|
||||
snd_pcm_recover(alsa->handle, ret, 0);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_alsa_output_add_input(Ecore_Audio_Object *output, Ecore_Audio_Object *input)
|
||||
{
|
||||
Ecore_Audio_Module *outmod = output->module;
|
||||
Ecore_Audio_Module *inmod = input->module;
|
||||
struct _Ecore_Audio_Alsa *alsa = (struct _Ecore_Audio_Alsa *)output->module_data;
|
||||
|
||||
ecore_timer_add(0.3, _alsa_output_async_cb, output);
|
||||
}
|
||||
|
||||
static struct input_api inops = {
|
||||
};
|
||||
|
||||
static struct output_api outops = {
|
||||
.output_new = _alsa_output_new,
|
||||
.output_del = _alsa_output_del,
|
||||
// .output_volume_set = _alsa_output_volume_set,
|
||||
.output_add_input = _alsa_output_add_input,
|
||||
// .output_del_input = _alsa_output_del_input,
|
||||
// .output_update_input_format = _alsa_output_update_input_format,
|
||||
};
|
||||
|
||||
/* externally accessible functions */
|
||||
|
||||
/**
|
||||
* @addtogroup Ecore_Audio_Group Ecore_Audio_alsa - Ecore internal ALSA audio functions
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the Ecore_Audio ALSA module.
|
||||
*
|
||||
* @return the initialized module success, NULL on error.
|
||||
*
|
||||
*/
|
||||
Ecore_Audio_Module *
|
||||
ecore_audio_alsa_init(void)
|
||||
{
|
||||
alsa_module = calloc(1, sizeof(Ecore_Audio_Module));
|
||||
if (!alsa_module)
|
||||
{
|
||||
ERR("Could not allocate memory for the module.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ECORE_MAGIC_SET(alsa_module, ECORE_MAGIC_AUDIO_MODULE);
|
||||
alsa_module->type = ECORE_AUDIO_TYPE_ALSA;
|
||||
alsa_module->name = "alsa";
|
||||
alsa_module->inputs = NULL;
|
||||
alsa_module->outputs = NULL;
|
||||
alsa_module->in_ops = &inops;
|
||||
alsa_module->out_ops = &outops;
|
||||
|
||||
return alsa_module;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shut down the Ecore_Audio ALSA module
|
||||
*/
|
||||
void
|
||||
ecore_audio_alsa_shutdown(void)
|
||||
{
|
||||
free(alsa_module);
|
||||
alsa_module = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAVE_ALSA */
|
|
@ -9,6 +9,10 @@
|
|||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
#include <alsa/asoundlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PULSE
|
||||
#include <pulse/pulseaudio.h>
|
||||
#endif
|
||||
|
@ -297,6 +301,20 @@ struct _Ecore_Audio_Callback {
|
|||
|
||||
extern Eina_List *ecore_audio_modules;
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
/* ecore_audio_alsa */
|
||||
struct _Ecore_Audio_Alsa
|
||||
{
|
||||
ECORE_MAGIC;
|
||||
snd_pcm_t *handle;
|
||||
unsigned int channels;
|
||||
unsigned int samplerate;
|
||||
};
|
||||
|
||||
Ecore_Audio_Module *ecore_audio_alsa_init(void);
|
||||
void ecore_audio_alsa_shutdown(void);
|
||||
#endif /* HAVE_ALSA */
|
||||
|
||||
#ifdef HAVE_PULSE
|
||||
/* PA mainloop integration */
|
||||
struct _Ecore_Audio_Pa_Private
|
||||
|
|
Loading…
Reference in New Issue