forked from enlightenment/efl
efl: Introducing ecore_audio - the audio API for efl
This is still very much a work in progress, so expect some issues. The signalling is using ecore events for now - that will change to callbacks you can register callbacks for events on specific Ecore_Audio_Objects. EO wasn't there when Ecore_Audio started, but it will probably move to that in the future. Otherwise have fun, don't break it (too much) and please send bug reports and feedback to me. Signed-off-by: Daniel Willmann <d.willmann@samsung.com> SVN revision: 80994
This commit is contained in:
parent
b3d9fe9315
commit
318a88b61f
|
@ -0,0 +1,442 @@
|
||||||
|
#ifndef ECORE_AUDIO_H
|
||||||
|
#define ECORE_AUDIO_H
|
||||||
|
|
||||||
|
#include <Eina.h>
|
||||||
|
|
||||||
|
#ifdef EAPI
|
||||||
|
#undef EAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
#define EAPI __attribute__ ((visibility("default")))
|
||||||
|
#else
|
||||||
|
#define EAPI
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define EAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file Ecore_Audio.h
|
||||||
|
* @brief Audio utility functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Ecore_Audio_Group Ecore_Audio - Convenience audio API
|
||||||
|
*
|
||||||
|
* @ref Ecore_Audio_Module_API_Group
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum _Ecore_Audio_Type {
|
||||||
|
ECORE_AUDIO_TYPE_PULSE,
|
||||||
|
ECORE_AUDIO_TYPE_ALSA,
|
||||||
|
ECORE_AUDIO_TYPE_SNDFILE,
|
||||||
|
ECORE_AUDIO_TYPE_TONE,
|
||||||
|
ECORE_AUDIO_TYPE_CUSTOM,
|
||||||
|
ECORE_AUDIO_MODULE_LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum _Ecore_Audio_Type Ecore_Audio_Type;
|
||||||
|
|
||||||
|
typedef struct _Ecore_Audio_Module Ecore_Audio_Module;
|
||||||
|
/**< The audio module */
|
||||||
|
typedef struct _Ecore_Audio_Object Ecore_Audio_Object; /**< The audio object */
|
||||||
|
typedef struct _Ecore_Audio_Format Ecore_Audio_Format;
|
||||||
|
/**< The format of the audio data */
|
||||||
|
|
||||||
|
typedef int (*Ecore_Audio_Read_Callback)(void *user_data, void *data, int len);
|
||||||
|
|
||||||
|
struct _Ecore_Audio_Vio {
|
||||||
|
int (*get_length)(Ecore_Audio_Object *in);
|
||||||
|
int (*seek)(Ecore_Audio_Object *in, int offset, int whence);
|
||||||
|
int (*tell)(Ecore_Audio_Object *in);
|
||||||
|
int (*read)(Ecore_Audio_Object *in, void *buffer, int length);
|
||||||
|
int (*write)(Ecore_Audio_Object *out, const void *buffer, int length);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _Ecore_Audio_Vio Ecore_Audio_Vio; /** < Functions to implement IO virtually */
|
||||||
|
|
||||||
|
EAPI extern int ECORE_AUDIO_INPUT_STARTED; /**< Sound was started */
|
||||||
|
EAPI extern int ECORE_AUDIO_INPUT_STOPPED; /**< Sound was stopped */
|
||||||
|
EAPI extern int ECORE_AUDIO_INPUT_LOOPED; /**< Sound looped */
|
||||||
|
EAPI extern int ECORE_AUDIO_INPUT_ENDED; /**< Sound playback ended */
|
||||||
|
EAPI extern int ECORE_AUDIO_INPUT_PAUSED; /**< Sound paused */
|
||||||
|
EAPI extern int ECORE_AUDIO_OUTPUT_INPUT_ADDED; /**< Input added to output */
|
||||||
|
EAPI extern int ECORE_AUDIO_OUTPUT_INPUT_REMOVED; /**< Input removed from output */
|
||||||
|
|
||||||
|
/* Audio operations */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the Ecore_Audio library.
|
||||||
|
*
|
||||||
|
* @return 1 or greater on success, 0 on error.
|
||||||
|
*
|
||||||
|
* This function sets up Ecore_Audio and initializes the modules that
|
||||||
|
* provide the in- and outputs to use. It returns 0 on failure, otherwise
|
||||||
|
* it returns the number of times it has already been called.
|
||||||
|
*
|
||||||
|
* When Ecore_Audio is not used anymore, call ecore_audio_shutdown()
|
||||||
|
* to shut down the Ecore_Audio library.
|
||||||
|
*/
|
||||||
|
EAPI int ecore_audio_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shut down the Ecore_Audio library.
|
||||||
|
*
|
||||||
|
* @return 0 when the library is completely shut down, 1 or
|
||||||
|
* greater otherwise.
|
||||||
|
*
|
||||||
|
* This function shuts down the Ecore_Audio library. It returns 0 when it has
|
||||||
|
* been called the same number of times than ecore_audio_init(). In that case
|
||||||
|
* it shuts down all the services it uses.
|
||||||
|
*/
|
||||||
|
EAPI int ecore_audio_shutdown(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* Output operations*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a new Ecore_Audio_Output instance
|
||||||
|
*
|
||||||
|
* @param name the name of the output to create
|
||||||
|
* @return a new instance or NULL on error
|
||||||
|
*/
|
||||||
|
EAPI Ecore_Audio_Object *ecore_audio_output_add(Ecore_Audio_Type type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the name of an output
|
||||||
|
*
|
||||||
|
* @param output The output
|
||||||
|
* @param name The name
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_output_name_set(Ecore_Audio_Object *output, const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the name of an output
|
||||||
|
*
|
||||||
|
* @param output the output
|
||||||
|
*
|
||||||
|
* @return the name of the output
|
||||||
|
*/
|
||||||
|
EAPI const char *ecore_audio_output_name_get(Ecore_Audio_Object *output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free an @ref Ecore_Audio_Output instance
|
||||||
|
*
|
||||||
|
* @param out the output
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_output_del(Ecore_Audio_Object *output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the user data pointer
|
||||||
|
*
|
||||||
|
* @param output The output
|
||||||
|
* @param data The pointer to set
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_output_userdata_set(Ecore_Audio_Object *output, void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the user data pointer
|
||||||
|
*
|
||||||
|
* @param output The output
|
||||||
|
*
|
||||||
|
* @return The pointer to the user data
|
||||||
|
*/
|
||||||
|
EAPI void *ecore_audio_output_userdata_get(Ecore_Audio_Object *output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the volume of the output
|
||||||
|
*
|
||||||
|
* @param out the output
|
||||||
|
* @param volume the volume
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_output_volume_set(Ecore_Audio_Object *output, double volume);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the volume of the output
|
||||||
|
*
|
||||||
|
* @param out the output
|
||||||
|
*
|
||||||
|
* @return the volume
|
||||||
|
*/
|
||||||
|
EAPI double ecore_audio_output_volume_get(Ecore_Audio_Object *output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the paused state of an output
|
||||||
|
*
|
||||||
|
* @param out the output
|
||||||
|
* @param paused the paused state
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_output_paused_set(Ecore_Audio_Object *output, Eina_Bool paused);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the paused state of an output
|
||||||
|
*
|
||||||
|
* @param out the output
|
||||||
|
*
|
||||||
|
* @return the paused state
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool ecore_audio_output_paused_get(Ecore_Audio_Object *output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add an input to an output.
|
||||||
|
*
|
||||||
|
* @param out the output
|
||||||
|
* @param in the input
|
||||||
|
*
|
||||||
|
* @return True if connecting was successful, False otherwise
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool ecore_audio_output_input_add(Ecore_Audio_Object *output, Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disconnect an input from an output. This will stop playback of the
|
||||||
|
* input.
|
||||||
|
*
|
||||||
|
* @param out the output
|
||||||
|
* @param in the input
|
||||||
|
*
|
||||||
|
* @return True if disconnecting was successful, False otherwise
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool ecore_audio_output_input_del(Ecore_Audio_Object *output, Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the inputs connected to an output.
|
||||||
|
*
|
||||||
|
* @param out the output
|
||||||
|
*
|
||||||
|
* @return A list of Ecore_Audio_Input that are connected to the output
|
||||||
|
*/
|
||||||
|
EAPI Eina_List *ecore_audio_output_inputs_get(Ecore_Audio_Object *output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set up an input to play after another input.
|
||||||
|
*
|
||||||
|
* @param out the output
|
||||||
|
* @param after the input relative to which the other input will be chained
|
||||||
|
* @param in the input to chain
|
||||||
|
*
|
||||||
|
* @return True if chaining was successful, False otherwise
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool ecore_audio_output_input_chain_after(Ecore_Audio_Object *output, Ecore_Audio_Object *input, Ecore_Audio_Object *after);
|
||||||
|
|
||||||
|
|
||||||
|
/* Input operations*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a new Ecore_Audio_Input instance
|
||||||
|
*
|
||||||
|
* @param name the name of the input to create
|
||||||
|
* @return a new instance or NULL on error
|
||||||
|
*/
|
||||||
|
EAPI Ecore_Audio_Object *ecore_audio_input_add(Ecore_Audio_Type type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the name of an input
|
||||||
|
*
|
||||||
|
* @param input the input
|
||||||
|
*
|
||||||
|
* @return the name of the input
|
||||||
|
*/
|
||||||
|
EAPI const char *ecore_audio_input_name_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the name of an input
|
||||||
|
*
|
||||||
|
* @param input the input
|
||||||
|
* @param name The name to set
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_input_name_set(Ecore_Audio_Object *input, const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free an @ref Ecore_Audio_Input instance
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_input_del(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the user data pointer
|
||||||
|
*
|
||||||
|
* @param input The input
|
||||||
|
* @param data The pointer to set
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_input_userdata_set(Ecore_Audio_Object *input, void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the user data pointer
|
||||||
|
*
|
||||||
|
* @param input The input
|
||||||
|
*
|
||||||
|
* @return The pointer to the user data
|
||||||
|
*/
|
||||||
|
EAPI void *ecore_audio_input_userdata_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the sample rate of the input
|
||||||
|
*
|
||||||
|
* @param input The input
|
||||||
|
*
|
||||||
|
* @return The samplerate in Hz
|
||||||
|
*/
|
||||||
|
EAPI int ecore_audio_input_samplerate_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the sample rate of the input
|
||||||
|
*
|
||||||
|
* @param input The input
|
||||||
|
* @param samplerate The sample rate in Hz
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_input_samplerate_set(Ecore_Audio_Object *input, int samplerate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the channels of the input
|
||||||
|
*
|
||||||
|
* @param input The input
|
||||||
|
*
|
||||||
|
* @return The number of channels
|
||||||
|
*/
|
||||||
|
EAPI int ecore_audio_input_channels_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the amount of channels in the input
|
||||||
|
*
|
||||||
|
* @param input The input
|
||||||
|
* @param channels The number of channels to set
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_input_channels_set(Ecore_Audio_Object *input, int channels);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Seek within an input stream
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
* @offset the offset in seconds
|
||||||
|
* @mode seek mode (SEEK_SET, SEEK_END, or SEEK_CUR)
|
||||||
|
* @return the current offset
|
||||||
|
*/
|
||||||
|
EAPI double ecore_audio_input_seek(Ecore_Audio_Object *input, double offset, int mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read data from an input stream
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
* @param data the buffer to write the audio data into
|
||||||
|
* @param len the size of the buffer
|
||||||
|
*
|
||||||
|
* @return the number of bytes that were read
|
||||||
|
*/
|
||||||
|
EAPI int ecore_audio_input_read(Ecore_Audio_Object *input, void *data, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the paused state of an input
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
* @return EINA_TRUE if the input is paused, EINA_FALSE otherwise
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool ecore_audio_input_paused_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the paused state of an input
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
* @param paused the paused state to set
|
||||||
|
*
|
||||||
|
* If paused is EINA_TRUE if the input is paused, if it is EINA_FALSE the
|
||||||
|
* input plays normally.
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_input_paused_set(Ecore_Audio_Object *input, Eina_Bool paused);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the volume of the input
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
* @param volume the volume
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_input_volume_set(Ecore_Audio_Object *input, double volume);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the volume of the input
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
*
|
||||||
|
* @return the volume
|
||||||
|
*/
|
||||||
|
EAPI double ecore_audio_input_volume_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether the input loops
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
* @param looped if the input should loop
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_input_looped_set(Ecore_Audio_Object *input, Eina_Bool looped);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get whether the input loops
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
*
|
||||||
|
* @return if the input loops
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool ecore_audio_input_looped_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the length of the input in seconds
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
*
|
||||||
|
* @return the length in seconds
|
||||||
|
*/
|
||||||
|
EAPI double ecore_audio_input_length_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether the input is preloaded
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
* @param preloaded if the input is preloaded
|
||||||
|
*/
|
||||||
|
EAPI void ecore_audio_input_preloaded_set(Ecore_Audio_Object *input, Eina_Bool preloaded);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get whether the input is preloaded
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
*
|
||||||
|
* @return EINA_TRUE if the input is preloaded, otherwise EINA_FALSE
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool ecore_audio_input_preloaded_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the outputs this input is connected to
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
*
|
||||||
|
* @return A list of outputs
|
||||||
|
*/
|
||||||
|
EAPI Ecore_Audio_Object *ecore_audio_input_output_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the remaining time of the input
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
*
|
||||||
|
* @return The remaining time in seconds
|
||||||
|
*/
|
||||||
|
EAPI double ecore_audio_input_remaining_get(Ecore_Audio_Object *input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,557 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_FEATURES_H
|
||||||
|
#include <features.h>
|
||||||
|
#endif
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "ecore_audio_private.h"
|
||||||
|
|
||||||
|
int _ecore_audio_log_dom = -1;
|
||||||
|
static int _ecore_audio_init_count = 0;
|
||||||
|
Eina_List *ecore_audio_modules;
|
||||||
|
|
||||||
|
EAPI int ECORE_AUDIO_INPUT_STARTED;
|
||||||
|
EAPI int ECORE_AUDIO_INPUT_STOPPED;
|
||||||
|
EAPI int ECORE_AUDIO_INPUT_LOOPED;
|
||||||
|
EAPI int ECORE_AUDIO_INPUT_ENDED;
|
||||||
|
EAPI int ECORE_AUDIO_INPUT_PAUSED;
|
||||||
|
EAPI int ECORE_AUDIO_OUTPUT_INPUT_ADDED;
|
||||||
|
EAPI int ECORE_AUDIO_OUTPUT_INPUT_REMOVED;
|
||||||
|
|
||||||
|
static void _dummy_free(void *foo EINA_UNUSED, void *bar EINA_UNUSED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
module_cmp(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Module *mod = (Ecore_Audio_Module *)a;
|
||||||
|
Ecore_Audio_Type type = *(Ecore_Audio_Type *)b;
|
||||||
|
|
||||||
|
return !(mod->type == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Ecore_Audio_Module *
|
||||||
|
get_module_by_type(Ecore_Audio_Type type)
|
||||||
|
{
|
||||||
|
return eina_list_search_unsorted(ecore_audio_modules, module_cmp, &type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* externally accessible functions */
|
||||||
|
|
||||||
|
EAPI int
|
||||||
|
ecore_audio_init(void)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Module *mod;
|
||||||
|
|
||||||
|
if (++_ecore_audio_init_count != 1)
|
||||||
|
return _ecore_audio_init_count;
|
||||||
|
|
||||||
|
if (!ecore_init())
|
||||||
|
return --_ecore_audio_init_count;
|
||||||
|
|
||||||
|
_ecore_audio_log_dom = eina_log_domain_register("ecore_audio", ECORE_AUDIO_DEFAULT_LOG_COLOR);
|
||||||
|
if (_ecore_audio_log_dom < 0)
|
||||||
|
{
|
||||||
|
EINA_LOG_ERR("Impossible to create a log domain for the ecore audio module.");
|
||||||
|
return --_ecore_audio_init_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG("Ecore_Audio init");
|
||||||
|
ecore_audio_modules = NULL;
|
||||||
|
|
||||||
|
ECORE_AUDIO_INPUT_STARTED = ecore_event_type_new();
|
||||||
|
ECORE_AUDIO_INPUT_STOPPED = ecore_event_type_new();
|
||||||
|
ECORE_AUDIO_INPUT_LOOPED = ecore_event_type_new();
|
||||||
|
ECORE_AUDIO_INPUT_ENDED = ecore_event_type_new();
|
||||||
|
ECORE_AUDIO_INPUT_PAUSED = ecore_event_type_new();
|
||||||
|
ECORE_AUDIO_OUTPUT_INPUT_ADDED = ecore_event_type_new();
|
||||||
|
ECORE_AUDIO_OUTPUT_INPUT_REMOVED = ecore_event_type_new();
|
||||||
|
|
||||||
|
return _ecore_audio_init_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI int
|
||||||
|
ecore_audio_shutdown(void)
|
||||||
|
{
|
||||||
|
DBG("Ecore_Audio shutdown");
|
||||||
|
if (--_ecore_audio_init_count != 0)
|
||||||
|
return _ecore_audio_init_count;
|
||||||
|
|
||||||
|
/* FIXME: Shutdown all the inputs and outputs first */
|
||||||
|
|
||||||
|
eina_list_free(ecore_audio_modules);
|
||||||
|
|
||||||
|
eina_log_domain_unregister(_ecore_audio_log_dom);
|
||||||
|
_ecore_audio_log_dom = -1;
|
||||||
|
|
||||||
|
ecore_shutdown();
|
||||||
|
|
||||||
|
return _ecore_audio_init_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output operations */
|
||||||
|
|
||||||
|
EAPI Ecore_Audio_Object *
|
||||||
|
ecore_audio_output_add(Ecore_Audio_Type type)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Output *out;
|
||||||
|
Ecore_Audio_Module *module;
|
||||||
|
|
||||||
|
module = get_module_by_type(type);
|
||||||
|
|
||||||
|
if (!module)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
out = calloc(1, sizeof(Ecore_Audio_Output));
|
||||||
|
if (!out)
|
||||||
|
{
|
||||||
|
ERR("Could not allocate memory for output.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ECORE_MAGIC_SET(out, ECORE_MAGIC_AUDIO_OUTPUT);
|
||||||
|
out->module = module;
|
||||||
|
out->inputs = NULL;
|
||||||
|
|
||||||
|
return module->out_ops->output_new((Ecore_Audio_Object *)out);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
ecore_audio_output_del(Ecore_Audio_Object *output)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||||
|
Eina_Bool del;
|
||||||
|
Ecore_Audio_Object *in;
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(out);
|
||||||
|
|
||||||
|
/* Cleanup */
|
||||||
|
EINA_LIST_FREE (out->inputs, in)
|
||||||
|
{
|
||||||
|
del = ecore_audio_output_input_del(output, in);
|
||||||
|
if (!del)
|
||||||
|
WRN("Disconnecting in %p and out %p failed.", in, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
out->module->out_ops->output_del(output);
|
||||||
|
eina_stringshare_del(output->name);
|
||||||
|
free(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void ecore_audio_output_userdata_set(Ecore_Audio_Object *output, void *data)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||||
|
out->user_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void *ecore_audio_output_userdata_get(Ecore_Audio_Object *output)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||||
|
return out->user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI const char *ecore_audio_output_name_get(Ecore_Audio_Object *output)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
|
||||||
|
|
||||||
|
return out->name;
|
||||||
|
}
|
||||||
|
EAPI void ecore_audio_output_name_set(Ecore_Audio_Object *output, const char *name)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(out);
|
||||||
|
|
||||||
|
if (out->name)
|
||||||
|
eina_stringshare_del(out->name);
|
||||||
|
|
||||||
|
out->name = eina_stringshare_add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
ecore_audio_output_volume_set(Ecore_Audio_Object *output, double volume)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(output);
|
||||||
|
|
||||||
|
Ecore_Audio_Module *outmod = output->module;
|
||||||
|
|
||||||
|
outmod->out_ops->output_volume_set(output, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI double
|
||||||
|
ecore_audio_output_volume_get(Ecore_Audio_Object *output)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(output, 0);
|
||||||
|
Ecore_Audio_Module *outmod = output->module;
|
||||||
|
|
||||||
|
return outmod->out_ops->output_volume_get(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
ecore_audio_output_paused_set(Ecore_Audio_Object *output, Eina_Bool paused)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(output);
|
||||||
|
Ecore_Audio_Module *outmod = output->module;
|
||||||
|
|
||||||
|
outmod->out_ops->output_paused_set(output, paused);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
ecore_audio_output_paused_get(Ecore_Audio_Object *output)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_TRUE);
|
||||||
|
|
||||||
|
return output->paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
ecore_audio_output_input_add(Ecore_Audio_Object *output, Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
|
||||||
|
Ecore_Audio_Module *outmod = output->module;
|
||||||
|
Eina_Bool ret;
|
||||||
|
|
||||||
|
if (in->output != NULL)
|
||||||
|
ecore_audio_output_input_del((Ecore_Audio_Object *)in->output, input);
|
||||||
|
|
||||||
|
ret = outmod->out_ops->output_add_input(output, input);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
in->output = out;
|
||||||
|
out->inputs = eina_list_append(out->inputs, in);
|
||||||
|
ecore_event_add(ECORE_AUDIO_OUTPUT_INPUT_ADDED, in, _dummy_free, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
ecore_audio_output_input_del(Ecore_Audio_Object *output, Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
|
||||||
|
Ecore_Audio_Module *outmod = output->module;
|
||||||
|
Eina_Bool ret;
|
||||||
|
|
||||||
|
ret = outmod->out_ops->output_del_input(output, input);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
in->output = NULL;
|
||||||
|
out->inputs = eina_list_remove(out->inputs, in);
|
||||||
|
ecore_event_add(ECORE_AUDIO_OUTPUT_INPUT_REMOVED, in, _dummy_free, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_List *ecore_audio_output_inputs_get(Ecore_Audio_Object *output)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
|
||||||
|
return out->inputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool ecore_audio_output_input_chain_after(Ecore_Audio_Object *output, Ecore_Audio_Object *after, Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(after, EINA_FALSE);
|
||||||
|
|
||||||
|
if (!eina_list_data_find(out->inputs, after))
|
||||||
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
/* XXX: implement */
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Input operations */
|
||||||
|
|
||||||
|
EAPI Ecore_Audio_Object *
|
||||||
|
ecore_audio_input_add(Ecore_Audio_Type type)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in;
|
||||||
|
Ecore_Audio_Module *module;
|
||||||
|
|
||||||
|
module = get_module_by_type(type);
|
||||||
|
|
||||||
|
if (!module)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
in = calloc(1, sizeof(Ecore_Audio_Input));
|
||||||
|
if (!in)
|
||||||
|
{
|
||||||
|
ERR("Could not allocate memory for input.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ECORE_MAGIC_SET(in, ECORE_MAGIC_AUDIO_INPUT);
|
||||||
|
in->module = module;
|
||||||
|
in->output = NULL;
|
||||||
|
in->paused = EINA_FALSE;
|
||||||
|
|
||||||
|
return module->in_ops->input_new((Ecore_Audio_Object *)in);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
ecore_audio_input_del(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
Eina_Bool del;
|
||||||
|
Ecore_Audio_Module *module = input->module;
|
||||||
|
|
||||||
|
if (in->output) {
|
||||||
|
del = ecore_audio_output_input_del((Ecore_Audio_Object *)in->output, input);
|
||||||
|
if (!del)
|
||||||
|
WRN("Disconnecting in %p and out %p failed.", input, in->output);
|
||||||
|
in->output = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
module->in_ops->input_del(input);
|
||||||
|
eina_stringshare_del(in->name);
|
||||||
|
free(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void ecore_audio_input_userdata_set(Ecore_Audio_Object *input, void *data)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
in->user_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void *ecore_audio_input_userdata_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
return in->user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI const char *ecore_audio_input_name_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
|
||||||
|
return in->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void ecore_audio_input_name_set(Ecore_Audio_Object *input, const char *name)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(in);
|
||||||
|
|
||||||
|
if (in->name)
|
||||||
|
eina_stringshare_del(in->name);
|
||||||
|
|
||||||
|
in->name = eina_stringshare_add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI int ecore_audio_input_samplerate_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(in, -1);
|
||||||
|
|
||||||
|
return in->samplerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void ecore_audio_input_samplerate_set(Ecore_Audio_Object *input, int samplerate)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(input);
|
||||||
|
Ecore_Audio_Module *outmod;
|
||||||
|
|
||||||
|
if (in->samplerate == samplerate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
in->samplerate = samplerate;
|
||||||
|
|
||||||
|
if (in->output)
|
||||||
|
{
|
||||||
|
outmod = in->output->module;
|
||||||
|
outmod->out_ops->output_update_input_format((Ecore_Audio_Object *)in->output, input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI int ecore_audio_input_channels_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(in, -1);
|
||||||
|
|
||||||
|
return in->channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void ecore_audio_input_channels_set(Ecore_Audio_Object *input, int channels)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(in);
|
||||||
|
|
||||||
|
if (in->channels == channels)
|
||||||
|
return;
|
||||||
|
|
||||||
|
in->channels = channels;
|
||||||
|
|
||||||
|
/* XXX: Change channel number for connected streams?
|
||||||
|
if (in->output)
|
||||||
|
{
|
||||||
|
outmod = in->output->module;
|
||||||
|
outmod->out_ops->output_update_input_format(in->output, in);
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI int ecore_audio_input_read(Ecore_Audio_Object *input, void *data, int len)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(in, 0);
|
||||||
|
Ecore_Audio_Module *inmod = input->module;
|
||||||
|
|
||||||
|
if (in->paused)
|
||||||
|
{
|
||||||
|
memset(data, 0, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = inmod->in_ops->input_read(input, data, len);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
if (!in->looped)
|
||||||
|
{
|
||||||
|
ecore_event_add(ECORE_AUDIO_INPUT_ENDED, in, _dummy_free, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inmod->in_ops->input_seek(input, 0, SEEK_SET);
|
||||||
|
ret = inmod->in_ops->input_read(input, data, len);
|
||||||
|
ecore_event_add(ECORE_AUDIO_INPUT_LOOPED, input, _dummy_free, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI double
|
||||||
|
ecore_audio_input_seek(Ecore_Audio_Object *input, double offs, int mode)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input, -1);
|
||||||
|
Ecore_Audio_Module *inmod = input->module;
|
||||||
|
|
||||||
|
return inmod->in_ops->input_seek(input, offs, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
ecore_audio_input_paused_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
|
||||||
|
|
||||||
|
return input->paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
ecore_audio_input_paused_set(Ecore_Audio_Object *input, Eina_Bool paused)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(input);
|
||||||
|
|
||||||
|
if (paused == input->paused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
input->paused = paused;
|
||||||
|
ecore_event_add(ECORE_AUDIO_INPUT_PAUSED, input, _dummy_free, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
ecore_audio_input_volume_set(Ecore_Audio_Object *input, double volume)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(input);
|
||||||
|
Ecore_Audio_Module *inmod = input->module;
|
||||||
|
|
||||||
|
inmod->in_ops->input_volume_set(input, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI double
|
||||||
|
ecore_audio_input_volume_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input, -1);
|
||||||
|
Ecore_Audio_Module *inmod = input->module;
|
||||||
|
|
||||||
|
return inmod->in_ops->input_volume_get(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
ecore_audio_input_looped_set(Ecore_Audio_Object *input, Eina_Bool looped)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(input);
|
||||||
|
|
||||||
|
in->looped = looped;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
ecore_audio_input_looped_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
|
||||||
|
|
||||||
|
return in->looped;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI double
|
||||||
|
ecore_audio_input_length_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input, -1);
|
||||||
|
|
||||||
|
return in->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
ecore_audio_input_preloaded_set(Ecore_Audio_Object *input, Eina_Bool preloaded)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(input);
|
||||||
|
Ecore_Audio_Module *inmod = input->module;
|
||||||
|
|
||||||
|
inmod->in_ops->input_preloaded_set(input, preloaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
ecore_audio_input_preloaded_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
|
||||||
|
return in->preloaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Ecore_Audio_Object *
|
||||||
|
ecore_audio_input_output_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
|
||||||
|
return (Ecore_Audio_Object *)in->output;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI double
|
||||||
|
ecore_audio_input_remaining_get(Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Input *in = (Ecore_Audio_Input *)input;
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input, -1);
|
||||||
|
Ecore_Audio_Module *inmod = input->module;
|
||||||
|
|
||||||
|
return in->length - inmod->in_ops->input_seek(input, 0, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
|
@ -0,0 +1,295 @@
|
||||||
|
#ifndef ECORE_AUDIO_PRIVATE_H_
|
||||||
|
#define ECORE_AUDIO_PRIVATE_H_
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <features.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "Ecore.h"
|
||||||
|
#include "ecore_private.h"
|
||||||
|
|
||||||
|
#include "Ecore_Audio.h"
|
||||||
|
|
||||||
|
extern int _ecore_audio_log_dom;
|
||||||
|
|
||||||
|
#ifdef ECORE_AUDIO_DEFAULT_LOG_COLOR
|
||||||
|
#undef ECORE_AUDIO_DEFAULT_LOG_COLOR
|
||||||
|
#endif
|
||||||
|
#define ECORE_AUDIO_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
|
||||||
|
|
||||||
|
#ifdef ERR
|
||||||
|
#undef ERR
|
||||||
|
#endif
|
||||||
|
#define ERR(...) EINA_LOG_DOM_ERR(_ecore_audio_log_dom, __VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
#undef DBG
|
||||||
|
#endif
|
||||||
|
#define DBG(...) EINA_LOG_DOM_DBG(_ecore_audio_log_dom, __VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef INF
|
||||||
|
#undef INF
|
||||||
|
#endif
|
||||||
|
#define INF(...) EINA_LOG_DOM_INFO(_ecore_audio_log_dom, __VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef WRN
|
||||||
|
#undef WRN
|
||||||
|
#endif
|
||||||
|
#define WRN(...) EINA_LOG_DOM_WARN(_ecore_audio_log_dom, __VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef CRIT
|
||||||
|
#undef CRIT
|
||||||
|
#endif
|
||||||
|
#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_audio_log_dom, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define ECORE_MAGIC_AUDIO_MODULE 0xabba0001
|
||||||
|
#define ECORE_MAGIC_AUDIO_OUTPUT 0xabba0002
|
||||||
|
#define ECORE_MAGIC_AUDIO_INPUT 0xabba0003
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup Ecore_Audio_Module_API_Group Ecore_Audio_Module_API - API for modules
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _Ecore_Audio_Input Ecore_Audio_Input;
|
||||||
|
typedef struct _Ecore_Audio_Output Ecore_Audio_Output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Functions for inputs
|
||||||
|
*/
|
||||||
|
struct input_api
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Create a new input
|
||||||
|
*
|
||||||
|
* @param in The input already initialized from @ref ecore_audio_input_new()
|
||||||
|
*
|
||||||
|
* @return The input, NULL on error
|
||||||
|
*/
|
||||||
|
Ecore_Audio_Object *(*input_new)(Ecore_Audio_Object *in);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free an input
|
||||||
|
*
|
||||||
|
* @param in The input
|
||||||
|
*/
|
||||||
|
void (*input_del)(Ecore_Audio_Object *in);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read data from an input
|
||||||
|
*
|
||||||
|
* @param in The input to read from
|
||||||
|
* @param data A pointer to a buffer where the data is put
|
||||||
|
* @param len The amount of data to read in bytes
|
||||||
|
*/
|
||||||
|
int (*input_read)(Ecore_Audio_Object *in, void *data, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Seek within an input
|
||||||
|
*
|
||||||
|
* @param in The input
|
||||||
|
* @param count The amount to seek in seconds
|
||||||
|
* @param mode The mode
|
||||||
|
*
|
||||||
|
* @return The current position in seconds
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
double (*input_seek)(Ecore_Audio_Object *in, double count, int mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the volume
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
* @param volume the volume
|
||||||
|
*/
|
||||||
|
void (*input_volume_set)(Ecore_Audio_Object *in, double volume);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the volume
|
||||||
|
*
|
||||||
|
* @param in the input
|
||||||
|
*
|
||||||
|
* @return the volume
|
||||||
|
*/
|
||||||
|
double (*input_volume_get)(Ecore_Audio_Object *in);
|
||||||
|
|
||||||
|
void (*input_looped_set)(Ecore_Audio_Object *in, Eina_Bool looped);
|
||||||
|
Eina_Bool (*input_looped_get)(Ecore_Audio_Object *in);
|
||||||
|
|
||||||
|
void (*input_preloaded_set)(Ecore_Audio_Object *in, Eina_Bool preloaded);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Functions for outputs
|
||||||
|
*/
|
||||||
|
struct output_api
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Create a new output
|
||||||
|
*
|
||||||
|
* @param out The output already initialized from @ref ecore_audio_output_new()
|
||||||
|
*
|
||||||
|
* @return The output, NULL on error
|
||||||
|
*/
|
||||||
|
Ecore_Audio_Object *(*output_new)(Ecore_Audio_Object * out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free an output
|
||||||
|
*
|
||||||
|
* @param out the output
|
||||||
|
*/
|
||||||
|
void (*output_del)(Ecore_Audio_Object *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the volume of the output
|
||||||
|
*
|
||||||
|
* @param out The output
|
||||||
|
* @param vol The volume in the range of 0-255
|
||||||
|
*/
|
||||||
|
void (*output_volume_set)(Ecore_Audio_Object *out, double vol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the volume of the output
|
||||||
|
*
|
||||||
|
* @param out The output
|
||||||
|
*
|
||||||
|
* @return vol The volume
|
||||||
|
*/
|
||||||
|
double (*output_volume_get)(Ecore_Audio_Object *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the paused state of the output
|
||||||
|
*
|
||||||
|
* @param out The output
|
||||||
|
* @param paused The paused state
|
||||||
|
*/
|
||||||
|
void (*output_paused_set)(Ecore_Audio_Object *out, Eina_Bool paused);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add an input to an output
|
||||||
|
*
|
||||||
|
* @param out The output
|
||||||
|
* @param in The input
|
||||||
|
*
|
||||||
|
* @return EINA_TRUE if the operation was successful, EINA_FALSE otherwise
|
||||||
|
*/
|
||||||
|
Eina_Bool (*output_add_input)(Ecore_Audio_Object *out, Ecore_Audio_Object *in);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete an input from an output
|
||||||
|
*
|
||||||
|
* @param out The output
|
||||||
|
* @param in The input
|
||||||
|
*
|
||||||
|
* @return EINA_TRUE if the operation was successful, EINA_FALSE otherwise
|
||||||
|
*/
|
||||||
|
Eina_Bool (*output_del_input)(Ecore_Audio_Object *out, Ecore_Audio_Object *in);
|
||||||
|
|
||||||
|
void (*output_update_input_format)(Ecore_Audio_Object *out, Ecore_Audio_Object *in);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The structure representing an Ecore_Audio module
|
||||||
|
*/
|
||||||
|
struct _Ecore_Audio_Module
|
||||||
|
{
|
||||||
|
ECORE_MAGIC;
|
||||||
|
Ecore_Audio_Type type;
|
||||||
|
char *name;
|
||||||
|
Eina_List *inputs;
|
||||||
|
Eina_List *outputs;
|
||||||
|
|
||||||
|
void *priv;
|
||||||
|
|
||||||
|
struct input_api *in_ops;
|
||||||
|
struct output_api *out_ops;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A common structure, could be input or output
|
||||||
|
*/
|
||||||
|
struct _Ecore_Audio_Object
|
||||||
|
{
|
||||||
|
ECORE_MAGIC;
|
||||||
|
const char *name;
|
||||||
|
Ecore_Audio_Module *module;
|
||||||
|
|
||||||
|
Eina_Bool paused;
|
||||||
|
|
||||||
|
void *module_data;
|
||||||
|
void *obj_data;
|
||||||
|
void *user_data;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The structure representing an Ecore_Audio output
|
||||||
|
*/
|
||||||
|
struct _Ecore_Audio_Output
|
||||||
|
{
|
||||||
|
ECORE_MAGIC;
|
||||||
|
const char *name;
|
||||||
|
Ecore_Audio_Module *module;
|
||||||
|
|
||||||
|
Eina_Bool paused;
|
||||||
|
|
||||||
|
void *module_data;
|
||||||
|
void *obj_data;
|
||||||
|
void *user_data;
|
||||||
|
|
||||||
|
Eina_List *inputs; /**< The inputs that are connected to this output */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The structure representing an Ecore_Audio input
|
||||||
|
*/
|
||||||
|
struct _Ecore_Audio_Input
|
||||||
|
{
|
||||||
|
ECORE_MAGIC;
|
||||||
|
const char *name;
|
||||||
|
Ecore_Audio_Module *module;
|
||||||
|
|
||||||
|
Eina_Bool paused; /**< Is the input paused? */
|
||||||
|
|
||||||
|
void *module_data;
|
||||||
|
void *obj_data;
|
||||||
|
void *user_data;
|
||||||
|
|
||||||
|
Ecore_Audio_Output *output; /**< The output this input is connected to */
|
||||||
|
|
||||||
|
int samplerate;
|
||||||
|
int channels;
|
||||||
|
Eina_Bool looped; /**< Loop the sound */
|
||||||
|
double length; /**< Length of the sound */
|
||||||
|
Eina_Bool preloaded;
|
||||||
|
Eina_Bool ended;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The structure representing an Ecore_Audio format
|
||||||
|
*/
|
||||||
|
struct _Ecore_Audio_Format
|
||||||
|
{
|
||||||
|
unsigned int rate;
|
||||||
|
unsigned short channels;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _Ecore_Audio_Callback {
|
||||||
|
Ecore_Audio_Read_Callback read_cb;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Eina_List *ecore_audio_modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif
|
Loading…
Reference in New Issue