|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @file dsp-protocol.c
|
|
Packit Service |
cd2a00 |
* @brief Protocol to communicate with DSP side.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Copyright (C) 2006 Nokia Corporation
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Contact: Eduardo Bezerra Valentin <eduardo.valentin@indt.org.br>
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* This library is free software; you can redistribute it and/or
|
|
Packit Service |
cd2a00 |
* modify it under the terms of the GNU Library General Public
|
|
Packit Service |
cd2a00 |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
cd2a00 |
* version 2 of the License, or (at your option) any later version.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* This library is distributed in the hope that it will be useful,
|
|
Packit Service |
cd2a00 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
cd2a00 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
cd2a00 |
* Library General Public License for more details.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* You should have received a copy of the GNU Library General Public License
|
|
Packit Service |
cd2a00 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
cd2a00 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit Service |
cd2a00 |
* */
|
|
Packit Service |
cd2a00 |
#include <stdio.h>
|
|
Packit Service |
cd2a00 |
#include <string.h>
|
|
Packit Service |
cd2a00 |
#include <stdlib.h>
|
|
Packit Service |
cd2a00 |
#include <poll.h>
|
|
Packit Service |
cd2a00 |
#include <sys/errno.h>
|
|
Packit Service |
cd2a00 |
#include <sys/types.h>
|
|
Packit Service |
cd2a00 |
#include <sys/uio.h>
|
|
Packit Service |
cd2a00 |
#include <unistd.h>
|
|
Packit Service |
cd2a00 |
#include <fcntl.h>
|
|
Packit Service |
cd2a00 |
#include <sys/mman.h>
|
|
Packit Service |
cd2a00 |
#include <math.h>
|
|
Packit Service |
cd2a00 |
#include <sys/ioctl.h>
|
|
Packit Service |
cd2a00 |
#include <sys/sem.h>
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
#include "dsp-protocol.h"
|
|
Packit Service |
cd2a00 |
#include "constants.h"
|
|
Packit Service |
cd2a00 |
#include "debug.h"
|
|
Packit Service |
cd2a00 |
#include "types.h"
|
|
Packit Service |
cd2a00 |
#include "reporting.h"
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
cd2a00 |
#include <config.h>
|
|
Packit Service |
cd2a00 |
#endif
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
#ifdef USE_RESOURCE_MANAGER
|
|
Packit Service |
cd2a00 |
#define DBUS_API_SUBJECT_TO_CHANGE
|
|
Packit Service |
cd2a00 |
#include <dbus/dbus.h>
|
|
Packit Service |
cd2a00 |
#define AUDIO_PM_SERVICE "com.nokia.osso_audio_pm"
|
|
Packit Service |
cd2a00 |
#define AUDIO_PM_PLAYBACK_RESOURCE "/com/nokia/osso/pm/audio/playback"
|
|
Packit Service |
cd2a00 |
#define AUDIO_PM_RECORD_RESOURCE "/com/nokia/osso/pm/audio/record"
|
|
Packit Service |
cd2a00 |
#define RESOURCE_INTERFACE "com.nokia.osso_resource_manager"
|
|
Packit Service |
cd2a00 |
#define RESOURCE_TIMEOUT 200
|
|
Packit Service |
cd2a00 |
#endif /* USE_RESOURCE_MANAGER */
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
#define MAGIC_NUMBER 0x00A3D70A
|
|
Packit Service |
cd2a00 |
#define PANNING_STEP 0x06
|
|
Packit Service |
cd2a00 |
#define TASK_IOCTL_LOCK 0x10002
|
|
Packit Service |
cd2a00 |
#define TASK_IOCTL_UNLOCK 0x10003
|
|
Packit Service |
cd2a00 |
/* internal datatypes declarations */
|
|
Packit Service |
cd2a00 |
union semun {
|
|
Packit Service |
cd2a00 |
int val; /* value for SETVAL */
|
|
Packit Service |
cd2a00 |
struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
|
|
Packit Service |
cd2a00 |
u_short *array; /* array for GETALL & SETALL */
|
|
Packit Service |
cd2a00 |
};
|
|
Packit Service |
cd2a00 |
/* internal features declarations */
|
|
Packit Service |
cd2a00 |
static int dsp_protocol_flush(dsp_protocol_t * dsp_protocol);
|
|
Packit Service |
cd2a00 |
static int dsp_protocol_send_command(dsp_protocol_t * dsp_protocol,
|
|
Packit Service |
cd2a00 |
const short int command);
|
|
Packit Service |
cd2a00 |
static void dsp_protocol_linear2Q15(const unsigned short int input,
|
|
Packit Service |
cd2a00 |
unsigned short int *scale,
|
|
Packit Service |
cd2a00 |
unsigned short int *power2);
|
|
Packit Service |
cd2a00 |
static void dsp_protocol_Q152linear(const unsigned short int scale,
|
|
Packit Service |
cd2a00 |
const unsigned short int power2,
|
|
Packit Service |
cd2a00 |
unsigned short int *output);
|
|
Packit Service |
cd2a00 |
static int dsp_protocol_update_state(dsp_protocol_t * dsp_protocol);
|
|
Packit Service |
cd2a00 |
static inline int dsp_protocol_get_sem(dsp_protocol_t * dsp_protocol);
|
|
Packit Service |
cd2a00 |
static inline int dsp_protocol_lock_dev(dsp_protocol_t * dsp_protocol);
|
|
Packit Service |
cd2a00 |
static inline int dsp_protocol_unlock_dev(dsp_protocol_t * dsp_protocol);
|
|
Packit Service |
cd2a00 |
/* Initialisation phase features definitions */
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol DSP protocol reference pointer to be instanciated.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Creates new dsp_protocol object instance and initializes it
|
|
Packit Service |
cd2a00 |
* with default parameters. After this the device must be
|
|
Packit Service |
cd2a00 |
* separately opened with gst_dspaudio_open_node() method.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code
|
|
Packit Service |
cd2a00 |
* (-ENOMEM - fail when requesting memory for data structures).
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_create(dsp_protocol_t ** dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
|
|
Packit Service |
cd2a00 |
int ret = 0;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
*dsp_protocol = (dsp_protocol_t *) calloc(1, sizeof(dsp_protocol_t));
|
|
Packit Service |
cd2a00 |
if ((*dsp_protocol) == NULL) {
|
|
Packit Service |
cd2a00 |
DERROR("Could not allocate dsp_protocol instance\n");
|
|
Packit Service |
cd2a00 |
ret = -ENOMEM;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->fd = -1;
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->device = NULL;
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->state = STATE_UNINITIALISED;
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->mute = 0;
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->stream_id = 0;
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->bridge_buffer_size = 0;
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->mmap_buffer_size = 0;
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->mmap_buffer = NULL;
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->mutex = mutex;
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->sem_set_id = -1;
|
|
Packit Service |
cd2a00 |
#ifdef USE_RESOURCE_MANAGER
|
|
Packit Service |
cd2a00 |
(*dsp_protocol)->dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
|
|
Packit Service |
cd2a00 |
#endif
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol DSP protocol reference pointer to be initialized.
|
|
Packit Service |
cd2a00 |
* @param device dsp device node name.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Opens pcm dsp device file and initializes dsp_protocol
|
|
Packit Service |
cd2a00 |
* with information about stream, state and mmapbuffer.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_open_node(dsp_protocol_t * dsp_protocol, const char *device)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
short int tmp;
|
|
Packit Service |
cd2a00 |
audio_status_info_t audio_status_info;
|
|
Packit Service |
cd2a00 |
audio_init_status_t audio_init_status;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state != STATE_UNINITIALISED) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol
|
|
Packit Service |
cd2a00 |
("Trying to send open node from a non-valid state",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
dsp_protocol->fd = open(device, O_RDWR);
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->fd < 0) {
|
|
Packit Service |
cd2a00 |
DERROR("Could not open pcm device file %s\n", device);
|
|
Packit Service |
cd2a00 |
ret = errno;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
dsp_protocol->device = strdup(device);
|
|
Packit Service |
cd2a00 |
dsp_protocol_get_sem(dsp_protocol);
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_flush(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
tmp = DSP_CMD_STATE;
|
|
Packit Service |
cd2a00 |
if (write(dsp_protocol->fd, &tmp, sizeof(short int)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = read(dsp_protocol->fd, &audio_status_info,
|
|
Packit Service |
cd2a00 |
sizeof(audio_status_info_t))) < 0) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not read audio_status_info",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
report_audio_status_info("Received:", audio_status_info);
|
|
Packit Service |
cd2a00 |
if (audio_status_info.status == STATE_UNINITIALISED) {
|
|
Packit Service |
cd2a00 |
tmp = DSP_CMD_INIT;
|
|
Packit Service |
cd2a00 |
if (write(dsp_protocol->fd, &tmp, sizeof(short int)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = read(dsp_protocol->fd, &audio_init_status,
|
|
Packit Service |
cd2a00 |
sizeof(audio_init_status_t))) < 0) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Error reading INIT status",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
report_audio_init_status("Received:", audio_init_status);
|
|
Packit Service |
cd2a00 |
/* receive info from audio_init_status */
|
|
Packit Service |
cd2a00 |
dsp_protocol->stream_id = audio_init_status.stream_id;
|
|
Packit Service |
cd2a00 |
dsp_protocol->bridge_buffer_size =
|
|
Packit Service |
cd2a00 |
audio_init_status.bridge_buffer_size;
|
|
Packit Service |
cd2a00 |
dsp_protocol->mmap_buffer_size =
|
|
Packit Service |
cd2a00 |
audio_init_status.mmap_buffer_size;
|
|
Packit Service |
cd2a00 |
} else {
|
|
Packit Service |
cd2a00 |
/* This pcm task node is busy. Try to use another one. */
|
|
Packit Service |
cd2a00 |
ret = -EBUSY;
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
dsp_protocol->mmap_buffer = (short int *)
|
|
Packit Service |
cd2a00 |
mmap((void *)0, dsp_protocol->mmap_buffer_size,
|
|
Packit Service |
cd2a00 |
PROT_READ | PROT_WRITE, MAP_SHARED, dsp_protocol->fd, 0);
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->mmap_buffer == MAP_FAILED) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Cannot mmap data buffer", dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = -ENOMEM;
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
dsp_protocol->state = STATE_INITIALISED;
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("connection stablished:", dsp_protocol);
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
unlock:
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol DSP protocol reference pointer.
|
|
Packit Service |
cd2a00 |
* @param audio_params_data audio params to be sent to the dsp.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Send audio params to pcm task node and checks if
|
|
Packit Service |
cd2a00 |
* it was sent properly.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_send_audio_params(dsp_protocol_t * dsp_protocol,
|
|
Packit Service |
cd2a00 |
audio_params_data_t * audio_params_data)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
dsp_cmd_status_t audio_cmd_status;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state != STATE_INITIALISED) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol
|
|
Packit Service |
cd2a00 |
("Trying to send audio parameters from a non-valid state",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
audio_params_data->ds_stream_id = dsp_protocol->stream_id;
|
|
Packit Service |
cd2a00 |
if (write(dsp_protocol->fd, audio_params_data,
|
|
Packit Service |
cd2a00 |
sizeof(audio_params_data_t)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -1;
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not send audio_params_data",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if (read(dsp_protocol->fd, &audio_cmd_status,
|
|
Packit Service |
cd2a00 |
sizeof(dsp_cmd_status_t)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -1;
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not receive DSP_CMD_STATUS",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if (audio_cmd_status.status != DSP_OK) {
|
|
Packit Service |
cd2a00 |
ret = -1;
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("DSP returned a diferent Status of DSP_OK",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
report_return_value("DSP returned", audio_cmd_status.status);
|
|
Packit Service |
cd2a00 |
report_audio_params("Audio params sent", (*audio_params_data));
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
report_audio_params("Audio params sent", (*audio_params_data));
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
unlock:
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol DSP protocol reference pointer.
|
|
Packit Service |
cd2a00 |
* @param speech_params_data audio params to be sent to the dsp.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Send audio params to pcm_rec task node and checks if
|
|
Packit Service |
cd2a00 |
* it was sent properly.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_send_speech_params(dsp_protocol_t * dsp_protocol,
|
|
Packit Service |
cd2a00 |
speech_params_data_t * speech_params_data)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
dsp_cmd_status_t audio_cmd_status;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state != STATE_INITIALISED) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol
|
|
Packit Service |
cd2a00 |
("Trying to send speech parameters from a non-valid state",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
speech_params_data->ds_stream_id = dsp_protocol->stream_id;
|
|
Packit Service |
cd2a00 |
if (write(dsp_protocol->fd, speech_params_data,
|
|
Packit Service |
cd2a00 |
sizeof(speech_params_data_t)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -1;
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not send speech_params_data",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if (read(dsp_protocol->fd, &audio_cmd_status,
|
|
Packit Service |
cd2a00 |
sizeof(dsp_cmd_status_t)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -1;
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not receive DSP_CMD_STATUS",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if (audio_cmd_status.status != DSP_OK) {
|
|
Packit Service |
cd2a00 |
ret = -1;
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("DSP returned a diferent Status of DSP_OK",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
report_return_value("DSP returned", audio_cmd_status.status);
|
|
Packit Service |
cd2a00 |
report_speech_params("Speech params sent",
|
|
Packit Service |
cd2a00 |
(*speech_params_data));
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
report_speech_params("Speech params sent", (*speech_params_data));
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
unlock:
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/* Execution phase features definitions */
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It starts a playback section sending a DSP_CMD_PLAY. It flushes
|
|
Packit Service |
cd2a00 |
* all pending message comming from DSP side after DSP_CMD_PLAY.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code
|
|
Packit Service |
cd2a00 |
* (-EIO - sending play from a non-valid state).
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_send_play(dsp_protocol_t * dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state == STATE_UNINITIALISED) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol
|
|
Packit Service |
cd2a00 |
("Trying to send play from a non-valid state",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state == STATE_PLAYING)
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
else {
|
|
Packit Service |
cd2a00 |
if ((ret =
|
|
Packit Service |
cd2a00 |
dsp_protocol_send_command(dsp_protocol,
|
|
Packit Service |
cd2a00 |
DSP_CMD_PLAY)) == 0)
|
|
Packit Service |
cd2a00 |
dsp_protocol->state = STATE_PLAYING;
|
|
Packit Service |
cd2a00 |
dsp_protocol_flush(dsp_protocol);
|
|
Packit Service |
cd2a00 |
//Both, read and write remain data on the mbx system
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
* @param data audio data buffer.
|
|
Packit Service |
cd2a00 |
* @param count amount of data to be copied (in TUint16).
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It copies audio data to the mmap area in the right moment.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return if success, it returns the amount of data was sent.
|
|
Packit Service |
cd2a00 |
* If called in a wrong moment, it returns 0. Otherwise, a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_send_audio_data(dsp_protocol_t * dsp_protocol,
|
|
Packit Service |
cd2a00 |
void *data,
|
|
Packit Service |
cd2a00 |
unsigned short int count /* TUint16 */ )
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
write_status_t write_status;
|
|
Packit Service |
cd2a00 |
data_write_t data_write;
|
|
Packit Service |
cd2a00 |
int ret = 0;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
DPRINT("count %d\n", count);
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state != STATE_PLAYING) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Not in the STATE_PLAYING\n", dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
memcpy(dsp_protocol->mmap_buffer, data, count * 2);
|
|
Packit Service |
cd2a00 |
data_write.dsp_cmd = DSP_CMD_DATA_WRITE;
|
|
Packit Service |
cd2a00 |
data_write.data_size = count;
|
|
Packit Service |
cd2a00 |
if ((ret = write(dsp_protocol->fd, &data_write,
|
|
Packit Service |
cd2a00 |
sizeof(data_write_t))) < 0)
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
if ((ret = read(dsp_protocol->fd, &write_status,
|
|
Packit Service |
cd2a00 |
sizeof(write_status_t))) < 0)
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
if (write_status.dsp_cmd == DSP_CMD_DATA_WRITE) {
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
if (write_status.status == DSP_OK) {
|
|
Packit Service |
cd2a00 |
ret = count;
|
|
Packit Service |
cd2a00 |
DPRINT("%d words sent\n", ret);
|
|
Packit Service |
cd2a00 |
} else {
|
|
Packit Service |
cd2a00 |
DPRINT("Received a response different of DSP_OK\n");
|
|
Packit Service |
cd2a00 |
report_return_value("Returned value:",
|
|
Packit Service |
cd2a00 |
write_status.status);
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Current dsp_protocol",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
} else {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not send audio data", dsp_protocol);
|
|
Packit Service |
cd2a00 |
report_command("Returned cmd", write_status.dsp_cmd);
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
unlock:
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
* @param data audio data buffer.
|
|
Packit Service |
cd2a00 |
* @param count amount of data to be copied (in TUint16).
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It copies the audio data from the mmap area in the right moment.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return if success, it returns the amount of data was received.
|
|
Packit Service |
cd2a00 |
* If called in a wrong moment, it returns 0. Otherwise, a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_receive_audio_data(dsp_protocol_t * dsp_protocol,
|
|
Packit Service |
cd2a00 |
void *data, int count /* TU16int */ )
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
read_status_t read_status;
|
|
Packit Service |
cd2a00 |
dsp_cmd_status_t audio_cmd_status;
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
int ret = 0;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
DPRINT("count %d\n", count);
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state != STATE_PLAYING) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Not in the STATE_PLAYING\n", dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
memcpy(data, dsp_protocol->mmap_buffer, count * 2);
|
|
Packit Service |
cd2a00 |
audio_cmd_status.dsp_cmd = DSP_CMD_DATA_READ;
|
|
Packit Service |
cd2a00 |
audio_cmd_status.status = DSP_OK;
|
|
Packit Service |
cd2a00 |
if ((ret = write(dsp_protocol->fd, &audio_cmd_status,
|
|
Packit Service |
cd2a00 |
sizeof(dsp_cmd_status_t))) < 0)
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
if ((ret = read(dsp_protocol->fd, &read_status,
|
|
Packit Service |
cd2a00 |
sizeof(read_status_t))) < 0)
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
if (read_status.dsp_cmd == DSP_CMD_DATA_READ) {
|
|
Packit Service |
cd2a00 |
if (read_status.status == DSP_OK) {
|
|
Packit Service |
cd2a00 |
DPRINT("---------> DSP: ### %d ###\n",
|
|
Packit Service |
cd2a00 |
read_status.frame_size);
|
|
Packit Service |
cd2a00 |
ret = count;
|
|
Packit Service |
cd2a00 |
DPRINT("%d words sent\n", ret);
|
|
Packit Service |
cd2a00 |
} else {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Receive a status "
|
|
Packit Service |
cd2a00 |
"different from DSP_OK (skiping block)",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
report_return_value("Returned: ", read_status.status);
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
} else {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not receive audio data",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
DPRINT("Returned cmd %d expected %d\n", read_status.dsp_cmd,
|
|
Packit Service |
cd2a00 |
DSP_CMD_DATA_READ);
|
|
Packit Service |
cd2a00 |
report_return_value("Returned: ", read_status.status);
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
unlock:
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It pauses a playback section sending a DSP_CMD_PAUSE.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code
|
|
Packit Service |
cd2a00 |
* (-EIO - sending play from a non-valid state).
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_send_pause(dsp_protocol_t * dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state != STATE_PLAYING) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Not in the STATE_PLAYING\n", dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state == STATE_PAUSED)
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
else {
|
|
Packit Service |
cd2a00 |
if ((ret =
|
|
Packit Service |
cd2a00 |
dsp_protocol_send_command(dsp_protocol,
|
|
Packit Service |
cd2a00 |
DSP_CMD_PAUSE)) == 0)
|
|
Packit Service |
cd2a00 |
dsp_protocol->state = STATE_PAUSED;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It stops a playback section sending a DSP_CMD_STOP.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code
|
|
Packit Service |
cd2a00 |
* (-EIO - sending play from a non-valid state).
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_send_stop(dsp_protocol_t * dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state != STATE_PLAYING) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Not in the STATE_PLAYING\n", dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state == STATE_STOPPED)
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
else {
|
|
Packit Service |
cd2a00 |
if ((ret =
|
|
Packit Service |
cd2a00 |
dsp_protocol_send_command(dsp_protocol,
|
|
Packit Service |
cd2a00 |
DSP_CMD_STOP)) == 0)
|
|
Packit Service |
cd2a00 |
dsp_protocol->state = STATE_STOPPED;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/* Deletion phase features definitions */
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol DSP protocol reference pointer to be uninitialized.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It closes the connection with pcm dsp task node. It flushes all
|
|
Packit Service |
cd2a00 |
* pending data before that. Closes the mmap area. Initialize the
|
|
Packit Service |
cd2a00 |
* dsp_protocol structure with unused values.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_close_node(dsp_protocol_t * dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state != STATE_UNINITIALISED) {
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_flush(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_send_command(dsp_protocol,
|
|
Packit Service |
cd2a00 |
DSP_CMD_CLOSE)) < 0)
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->mmap_buffer)
|
|
Packit Service |
cd2a00 |
munmap(dsp_protocol->mmap_buffer,
|
|
Packit Service |
cd2a00 |
dsp_protocol->mmap_buffer_size);
|
|
Packit Service |
cd2a00 |
close(dsp_protocol->fd);
|
|
Packit Service |
cd2a00 |
dsp_protocol->fd = -1;
|
|
Packit Service |
cd2a00 |
free(dsp_protocol->device);
|
|
Packit Service |
cd2a00 |
dsp_protocol->device = NULL;
|
|
Packit Service |
cd2a00 |
dsp_protocol->state = STATE_UNINITIALISED;
|
|
Packit Service |
cd2a00 |
dsp_protocol->mute = 0;
|
|
Packit Service |
cd2a00 |
dsp_protocol->stream_id = 0;
|
|
Packit Service |
cd2a00 |
dsp_protocol->bridge_buffer_size = 0;
|
|
Packit Service |
cd2a00 |
dsp_protocol->mmap_buffer_size = 0;
|
|
Packit Service |
cd2a00 |
dsp_protocol->mmap_buffer = NULL;
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
unlock:
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol DSP protocol reference pointer.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It frees all the allocated memory. It sets NULL to the pointer.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_destroy(dsp_protocol_t ** dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret = 0;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
#ifdef USE_RESOURCE_MANAGER
|
|
Packit Service |
cd2a00 |
if ((*dsp_protocol)->dbus_connection)
|
|
Packit Service |
cd2a00 |
dbus_connection_unref((*dsp_protocol)->dbus_connection);
|
|
Packit Service |
cd2a00 |
#endif /* USE_RESOURCE_MANAGER */
|
|
Packit Service |
cd2a00 |
if (*dsp_protocol) {
|
|
Packit Service |
cd2a00 |
if ((*dsp_protocol)->device)
|
|
Packit Service |
cd2a00 |
free((*dsp_protocol)->device);
|
|
Packit Service |
cd2a00 |
free((*dsp_protocol));
|
|
Packit Service |
cd2a00 |
*dsp_protocol = NULL;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/* controls features definitions */
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* dsp_protocol_set_volume:
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
* @param left left channel volume value (0 - 100).
|
|
Packit Service |
cd2a00 |
* @param right right channel volume value (0 - 100).
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It changes volume data for both left and right channels.
|
|
Packit Service |
cd2a00 |
* It receives both values in a 0 - 100 scale.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_set_volume(dsp_protocol_t * dsp_protocol,
|
|
Packit Service |
cd2a00 |
unsigned char left, unsigned char right)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
dsp_cmd_status_t audio_cmd_status;
|
|
Packit Service |
cd2a00 |
volume_data_t volume_data;
|
|
Packit Service |
cd2a00 |
panning_data_t panning_data;
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
dsp_protocol_linear2Q15(left > right ? left : right, &volume_data.scale,
|
|
Packit Service |
cd2a00 |
&volume_data.power2);
|
|
Packit Service |
cd2a00 |
volume_data.dsp_cmd = DSP_CMD_SET_VOLUME;
|
|
Packit Service |
cd2a00 |
if ((ret =
|
|
Packit Service |
cd2a00 |
write(dsp_protocol->fd, &volume_data, sizeof(volume_data_t))) < 0)
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
if (read(dsp_protocol->fd, &audio_cmd_status,
|
|
Packit Service |
cd2a00 |
sizeof(dsp_cmd_status_t)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -EINVAL;
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not receive DSP_CMD_STATUS",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
report_return_value("Received", audio_cmd_status.status);
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
if (audio_cmd_status.status != DSP_OK)
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
if (ret == 0) { /*if sucess till here, update panning info */
|
|
Packit Service |
cd2a00 |
panning_data.dsp_cmd = DSP_CMD_SET_PANNING;
|
|
Packit Service |
cd2a00 |
panning_data.steps = PANNING_STEP;
|
|
Packit Service |
cd2a00 |
if (left != right) {
|
|
Packit Service |
cd2a00 |
panning_data.left_gain =
|
|
Packit Service |
cd2a00 |
left >
|
|
Packit Service |
cd2a00 |
right ? 0x4000 : (1.0 * left) / right * 0x4000;
|
|
Packit Service |
cd2a00 |
panning_data.right_gain =
|
|
Packit Service |
cd2a00 |
right >
|
|
Packit Service |
cd2a00 |
left ? 0x4000 : (1.0 * right) / left * 0x4000;
|
|
Packit Service |
cd2a00 |
} else {
|
|
Packit Service |
cd2a00 |
panning_data.left_gain = 0x4000;
|
|
Packit Service |
cd2a00 |
panning_data.right_gain = 0x4000;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
DPRINT("left gain %x right gain %x\n", panning_data.left_gain,
|
|
Packit Service |
cd2a00 |
panning_data.right_gain);
|
|
Packit Service |
cd2a00 |
if ((ret =
|
|
Packit Service |
cd2a00 |
write(dsp_protocol->fd, &panning_data,
|
|
Packit Service |
cd2a00 |
sizeof(panning_data_t))) < 0)
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
if (read(dsp_protocol->fd, &audio_cmd_status,
|
|
Packit Service |
cd2a00 |
sizeof(dsp_cmd_status_t)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -EINVAL;
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not receive DSP_CMD_STATUS",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
if (audio_cmd_status.status != DSP_OK)
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
unlock:
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
* @param left left channel volume value output (0 - 100).
|
|
Packit Service |
cd2a00 |
* @param right right channel volume value output (0 - 100).
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It returns volume data for both left and right channels.
|
|
Packit Service |
cd2a00 |
* It provides both values in a 0 - 100 scale.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_get_volume(dsp_protocol_t * dsp_protocol,
|
|
Packit Service |
cd2a00 |
unsigned char *left, unsigned char *right)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
unsigned short int tmp;
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
audio_status_info_t audio_status_info;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
tmp = DSP_CMD_STATE;
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
if (write(dsp_protocol->fd, &tmp, sizeof(short int)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = read(dsp_protocol->fd, &audio_status_info,
|
|
Packit Service |
cd2a00 |
sizeof(audio_status_info_t))) < 0) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not read audio_status_info",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto unlock;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
dsp_protocol->state = audio_status_info.status;
|
|
Packit Service |
cd2a00 |
report_audio_status_info("Received:", audio_status_info);
|
|
Packit Service |
cd2a00 |
dsp_protocol_Q152linear(audio_status_info.vol_scale,
|
|
Packit Service |
cd2a00 |
audio_status_info.vol_power2, &tmp);
|
|
Packit Service |
cd2a00 |
*left = tmp;
|
|
Packit Service |
cd2a00 |
*right = tmp;
|
|
Packit Service |
cd2a00 |
if (audio_status_info.number_channels == CHANNELS_2) {
|
|
Packit Service |
cd2a00 |
if (audio_status_info.left_gain > audio_status_info.right_gain){
|
|
Packit Service |
cd2a00 |
float result =
|
|
Packit Service |
cd2a00 |
*right * audio_status_info.right_gain / (0x4000 *
|
|
Packit Service |
cd2a00 |
1.0);
|
|
Packit Service |
cd2a00 |
*right = result;
|
|
Packit Service |
cd2a00 |
if ((result - *right) > 0.5)
|
|
Packit Service |
cd2a00 |
(*right)++;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if (audio_status_info.left_gain < audio_status_info.right_gain){
|
|
Packit Service |
cd2a00 |
float result =
|
|
Packit Service |
cd2a00 |
*left * audio_status_info.left_gain / (0x4000 *
|
|
Packit Service |
cd2a00 |
1.0);
|
|
Packit Service |
cd2a00 |
*left = result;
|
|
Packit Service |
cd2a00 |
if ((result - *left) > 0.5)
|
|
Packit Service |
cd2a00 |
(*left)++;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
unlock:
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
* @param mute mute value (0 unmuted - 1 muted).
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It changes mute state of DSP task node sending DSP_CMD_[UN]MUTE.
|
|
Packit Service |
cd2a00 |
* Provide 0 in mute to unmute, and 1 in mute to mute.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_set_mute(dsp_protocol_t * dsp_protocol, unsigned char mute)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret = 0;
|
|
Packit Service |
cd2a00 |
int command;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
if (mute == 1)
|
|
Packit Service |
cd2a00 |
command = DSP_CMD_MUTE;
|
|
Packit Service |
cd2a00 |
else
|
|
Packit Service |
cd2a00 |
command = DSP_CMD_UNMUTE;
|
|
Packit Service |
cd2a00 |
ret = dsp_protocol_send_command(dsp_protocol, command);
|
|
Packit Service |
cd2a00 |
dsp_protocol->mute = mute;
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It returns mute state of DSP task node.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, it returns current state of mute.
|
|
Packit Service |
cd2a00 |
* 0 means not muted. 1 means muted. otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_get_mute(dsp_protocol_t * dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret = 0;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
ret = dsp_protocol_update_state(dsp_protocol);
|
|
Packit Service |
cd2a00 |
if (ret >= 0)
|
|
Packit Service |
cd2a00 |
ret = dsp_protocol->mute;
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/*miscelaneos features definitions */
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
* @param enable enabled state of mic. 0 disable. 1 enabled.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It modifies enabled state of mic.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
#ifdef USE_RESOURCE_MANAGER
|
|
Packit Service |
cd2a00 |
int dsp_protocol_set_mic_enabled(dsp_protocol_t * dsp_protocol, int enabled)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret = 0;
|
|
Packit Service |
cd2a00 |
DBusMessage *message;
|
|
Packit Service |
cd2a00 |
DBusMessage *reply = NULL;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->dbus_connection &&
|
|
Packit Service |
cd2a00 |
(message = dbus_message_new_method_call(AUDIO_PM_SERVICE,
|
|
Packit Service |
cd2a00 |
AUDIO_PM_RECORD_RESOURCE, RESOURCE_INTERFACE,
|
|
Packit Service |
cd2a00 |
enabled ? "request" : "release"))) {
|
|
Packit Service |
cd2a00 |
if (!enabled) {
|
|
Packit Service |
cd2a00 |
dbus_int32_t handle = 0;
|
|
Packit Service |
cd2a00 |
/* assuming handle is always 0 for this resource */
|
|
Packit Service |
cd2a00 |
dbus_message_append_args(message,
|
|
Packit Service |
cd2a00 |
DBUS_TYPE_INT32, &handle,
|
|
Packit Service |
cd2a00 |
DBUS_TYPE_INVALID);
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
reply = dbus_connection_send_with_reply_and_block(
|
|
Packit Service |
cd2a00 |
dsp_protocol->dbus_connection,
|
|
Packit Service |
cd2a00 |
message, RESOURCE_TIMEOUT, NULL);
|
|
Packit Service |
cd2a00 |
/* TODO: check return value(s), append args for request()
|
|
Packit Service |
cd2a00 |
* These parts of the RM spec may still change so not done yet
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
dbus_message_unref(message);
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if (reply) {
|
|
Packit Service |
cd2a00 |
dbus_message_unref(reply);
|
|
Packit Service |
cd2a00 |
} else {
|
|
Packit Service |
cd2a00 |
DPRINT("Error acquiring PM resource for recording\n");
|
|
Packit Service |
cd2a00 |
#ifdef ERROR_ON_PM_FAILURE
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
#endif
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
#else /* !USE_RESOURCE_MANAGER */
|
|
Packit Service |
cd2a00 |
int dsp_protocol_set_mic_enabled(dsp_protocol_t * dsp_protocol, int enabled)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int mic_fd;
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
char mic_control_name[] = "/sys/devices/platform/audio-i2c/mic_enable";
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if ((mic_fd = open(mic_control_name, O_WRONLY)) < 0) {
|
|
Packit Service |
cd2a00 |
DPRINT("Error opening: %s\n", mic_control_name);
|
|
Packit Service |
cd2a00 |
#ifdef ERROR_ON_PM_FAILURE
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
#else
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
#endif
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
write(mic_fd, (enabled ? "1" : "0"), sizeof(char));
|
|
Packit Service |
cd2a00 |
close(mic_fd);
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
#endif /* USE_RESOURCE_MANAGER */
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
* @param device dsp task node file name.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It opens a dsp task node and queries for its states.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return if success, it returns number of channels whose dsp task is
|
|
Packit Service |
cd2a00 |
* currently using (1 - mono. 2 stero). otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int dsp_protocol_probe_node(dsp_protocol_t * dsp_protocol, const char *device)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->state != STATE_UNINITIALISED) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol
|
|
Packit Service |
cd2a00 |
("Trying to send open node from a non-valid state",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
dsp_protocol->fd = open(device, O_RDWR);
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->fd < 0) {
|
|
Packit Service |
cd2a00 |
DERROR("Could not open pcm device file %s\n", device);
|
|
Packit Service |
cd2a00 |
ret = errno;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
dsp_protocol->device = strdup(device);
|
|
Packit Service |
cd2a00 |
dsp_protocol_get_sem(dsp_protocol);
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_lock_dev(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
dsp_protocol->device = strdup(device);
|
|
Packit Service |
cd2a00 |
ret = dsp_protocol_update_state(dsp_protocol);
|
|
Packit Service |
cd2a00 |
if (ret != CHANNELS_1 && ret != CHANNELS_2)
|
|
Packit Service |
cd2a00 |
ret = CHANNELS_1;
|
|
Packit Service |
cd2a00 |
dsp_protocol_unlock_dev(dsp_protocol);
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param str string with a number.
|
|
Packit Service |
cd2a00 |
* @param val holder for the conversion result.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It converts a string to a number (long).
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
int safe_strtol(const char *str, long *val)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
char *end;
|
|
Packit Service |
cd2a00 |
long v;
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (!*str) {
|
|
Packit Service |
cd2a00 |
ret = -EINVAL;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
errno = 0;
|
|
Packit Service |
cd2a00 |
v = strtol(str, &end, 0);
|
|
Packit Service |
cd2a00 |
if (errno) {
|
|
Packit Service |
cd2a00 |
ret = -errno;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if (*end) {
|
|
Packit Service |
cd2a00 |
ret = -EINVAL;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
*val = v;
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
/* internal features definitions */
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Tries to read all the pending data.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero. success
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
static int dsp_protocol_flush(dsp_protocol_t * dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
struct pollfd pollf;
|
|
Packit Service |
cd2a00 |
int ret = 0;
|
|
Packit Service |
cd2a00 |
int tmp;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
pollf.fd = dsp_protocol->fd;
|
|
Packit Service |
cd2a00 |
pollf.events = POLLIN;
|
|
Packit Service |
cd2a00 |
while (poll(&pollf, 1, 0) > 0) {
|
|
Packit Service |
cd2a00 |
if (read(dsp_protocol->fd, &tmp, sizeof(short int)) == 0)
|
|
Packit Service |
cd2a00 |
/* Test end of file */
|
|
Packit Service |
cd2a00 |
break;
|
|
Packit Service |
cd2a00 |
#ifdef DEBUG
|
|
Packit Service |
cd2a00 |
fprintf(DEBUG_OUTPUT, ".");
|
|
Packit Service |
cd2a00 |
#endif
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
#ifdef DEBUG
|
|
Packit Service |
cd2a00 |
fprintf(DEBUG_OUTPUT, "\n");
|
|
Packit Service |
cd2a00 |
#endif
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
* @param command command value to be sent to the pcm task node.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Send the command to pcm task node and checks if
|
|
Packit Service |
cd2a00 |
* it was sent properly.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
static int dsp_protocol_send_command(dsp_protocol_t * dsp_protocol,
|
|
Packit Service |
cd2a00 |
const short int command)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
dsp_cmd_status_t audio_cmd_status;
|
|
Packit Service |
cd2a00 |
int ret = 0;
|
|
Packit Service |
cd2a00 |
short int tmp;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
report_command("Sending", command);
|
|
Packit Service |
cd2a00 |
tmp = command;
|
|
Packit Service |
cd2a00 |
if (write(dsp_protocol->fd, &tmp, sizeof(short int)) < 0) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not send", dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
if (read(dsp_protocol->fd, &audio_cmd_status,
|
|
Packit Service |
cd2a00 |
sizeof(dsp_cmd_status_t)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -1;
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not receive DSP_CMD_STATUS",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
/* report_command("Received", audio_cmd_status.dsp_cmd);
|
|
Packit Service |
cd2a00 |
report_return_value("Received", audio_cmd_status.status);*/
|
|
Packit Service |
cd2a00 |
DPRINT("audio_cmd_status.dsp_cmd: 0x%x\n", audio_cmd_status.dsp_cmd);
|
|
Packit Service |
cd2a00 |
DPRINT("audio_cmd_status.status: 0x%x\n", audio_cmd_status.status);
|
|
Packit Service |
cd2a00 |
if (audio_cmd_status.status != DSP_OK)
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param input 0 - 100 value to be converted to Q15.
|
|
Packit Service |
cd2a00 |
* @param scale scale value of Q15 format.
|
|
Packit Service |
cd2a00 |
* @param power2 power of 2 value of Q15 format.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Converts a 0 - 100 value to a Q15 format value.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
static void dsp_protocol_linear2Q15(const unsigned short int input,
|
|
Packit Service |
cd2a00 |
unsigned short int *scale,
|
|
Packit Service |
cd2a00 |
unsigned short int *power2)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
unsigned long int val = MAGIC_NUMBER * input;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
if (input == 0) {
|
|
Packit Service |
cd2a00 |
*scale = 0;
|
|
Packit Service |
cd2a00 |
*power2 = 0;
|
|
Packit Service |
cd2a00 |
} else {
|
|
Packit Service |
cd2a00 |
*power2 = 1;
|
|
Packit Service |
cd2a00 |
while (val < 0x40000000) {
|
|
Packit Service |
cd2a00 |
(*power2)--;
|
|
Packit Service |
cd2a00 |
val <<= 1;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
*scale = val >> 16;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
DPRINT("Resulted scale %d and power2 %d from input %d\n", *scale,
|
|
Packit Service |
cd2a00 |
*power2, input);
|
|
Packit Service |
cd2a00 |
DLEAVE(0);
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param scale scale value of Q15 format.
|
|
Packit Service |
cd2a00 |
* @param power2 power of 2 value of Q15 format.
|
|
Packit Service |
cd2a00 |
* @param output 0 - 100 resulted value.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Converts a Q15 format value to a 0 - 100 value.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
static void dsp_protocol_Q152linear(const unsigned short int scale,
|
|
Packit Service |
cd2a00 |
const unsigned short int power2, unsigned short int *output)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
float result = scale * 1.0 / 0x8000 * (1 << power2) * 100.0;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
*output = (short int)(result);
|
|
Packit Service |
cd2a00 |
if ((result - *output) > 0.5)
|
|
Packit Service |
cd2a00 |
(*output)++;
|
|
Packit Service |
cd2a00 |
DPRINT("Resulted linear: %d from scale %d and power2 %d\n", *output,
|
|
Packit Service |
cd2a00 |
scale, power2);
|
|
Packit Service |
cd2a00 |
DLEAVE(0);
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* Update dsp_protocol_t structure info. Queries dsp task
|
|
Packit Service |
cd2a00 |
* for a audio_status_info structure.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return if success, it returns number of channels whose dsp task is
|
|
Packit Service |
cd2a00 |
* currently using. otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
static int dsp_protocol_update_state(dsp_protocol_t * dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
short int tmp;
|
|
Packit Service |
cd2a00 |
audio_status_info_t audio_status_info;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
if ((ret = dsp_protocol_flush(dsp_protocol)) < 0)
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
tmp = DSP_CMD_STATE;
|
|
Packit Service |
cd2a00 |
if (write(dsp_protocol->fd, &tmp, sizeof(short int)) < 0) {
|
|
Packit Service |
cd2a00 |
ret = -EIO;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
if ((ret = read(dsp_protocol->fd, &audio_status_info,
|
|
Packit Service |
cd2a00 |
sizeof(audio_status_info_t))) < 0) {
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("Could not read audio_status_info",
|
|
Packit Service |
cd2a00 |
dsp_protocol);
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
report_audio_status_info("Received:", audio_status_info);
|
|
Packit Service |
cd2a00 |
dsp_protocol->stream_id = audio_status_info.stream_id;
|
|
Packit Service |
cd2a00 |
dsp_protocol->bridge_buffer_size = audio_status_info.bridge_buffer_size;
|
|
Packit Service |
cd2a00 |
dsp_protocol->mmap_buffer_size = audio_status_info.mmap_buffer_size;
|
|
Packit Service |
cd2a00 |
dsp_protocol->state = audio_status_info.status;
|
|
Packit Service |
cd2a00 |
#ifndef NORMAL_DSP_TASK
|
|
Packit Service |
cd2a00 |
dsp_protocol->mute = audio_status_info.mute;
|
|
Packit Service |
cd2a00 |
#endif
|
|
Packit Service |
cd2a00 |
report_dsp_protocol("connection stablished:", dsp_protocol);
|
|
Packit Service |
cd2a00 |
ret = audio_status_info.number_channels;
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It produces the semaphore ID and connects to it.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
static inline int dsp_protocol_get_sem(dsp_protocol_t * dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
union semun sem_val; /* semaphore value, for semctl(). */
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
int rc;
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
/* identifier returned by ftok() */
|
|
Packit Service |
cd2a00 |
key_t set_key;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
/* generate a "unique" key for our set, using the */
|
|
Packit Service |
cd2a00 |
/* directory "/dev/dsptask/xxxx". */
|
|
Packit Service |
cd2a00 |
set_key = ftok(dsp_protocol->device, 0);
|
|
Packit Service |
cd2a00 |
if (set_key == -1) {
|
|
Packit Service |
cd2a00 |
DPRINT("ftok: %d\n", errno);
|
|
Packit Service |
cd2a00 |
ret = -ENODEV;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
DPRINT("key %d\n", set_key);
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/* now we can use 'set_key' to generate a set id, for example. */
|
|
Packit Service |
cd2a00 |
dsp_protocol->sem_set_id = semget(set_key, 1, 0666);
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->sem_set_id == -1) {
|
|
Packit Service |
cd2a00 |
DPRINT("semget %d\n", errno);
|
|
Packit Service |
cd2a00 |
dsp_protocol->sem_set_id = semget(set_key, 1, IPC_CREAT | 0666);
|
|
Packit Service |
cd2a00 |
if (dsp_protocol->sem_set_id == -1) {
|
|
Packit Service |
cd2a00 |
DPRINT("semget: IPC_CREAT: %d\n", errno);
|
|
Packit Service |
cd2a00 |
ret = -ENODEV;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
DPRINT("Initialising the semaphore\n");
|
|
Packit Service |
cd2a00 |
sem_val.val = 1;
|
|
Packit Service |
cd2a00 |
rc = semctl(dsp_protocol->sem_set_id, 0, SETVAL, sem_val);
|
|
Packit Service |
cd2a00 |
if (rc == -1) {
|
|
Packit Service |
cd2a00 |
DPRINT("semctl %d\n", errno);
|
|
Packit Service |
cd2a00 |
ret = -ENODEV;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It waits until be able to hold the semaphore to access the dsp task node.
|
|
Packit Service |
cd2a00 |
* If the current process already has the semaphore, returns success.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
static inline int dsp_protocol_lock_dev(dsp_protocol_t * dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
int ret;
|
|
Packit Service |
cd2a00 |
struct sembuf sem_op;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
ret = pthread_mutex_trylock(&(dsp_protocol->mutex));
|
|
Packit Service |
cd2a00 |
if (ret != 0) {
|
|
Packit Service |
cd2a00 |
DPRINT("No lock %d\n", ret);
|
|
Packit Service |
cd2a00 |
if (errno == EBUSY)
|
|
Packit Service |
cd2a00 |
ret = 0;
|
|
Packit Service |
cd2a00 |
goto out;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
sem_op.sem_num = 0;
|
|
Packit Service |
cd2a00 |
sem_op.sem_op = -1;
|
|
Packit Service |
cd2a00 |
sem_op.sem_flg = 0;
|
|
Packit Service |
cd2a00 |
DPRINT("requesting semaphore (dev)\n");
|
|
Packit Service |
cd2a00 |
if (semop(dsp_protocol->sem_set_id, &sem_op, 1) == -1) {
|
|
Packit Service |
cd2a00 |
DPRINT("semop %d\n", errno);
|
|
Packit Service |
cd2a00 |
pthread_mutex_unlock(&(dsp_protocol->mutex));
|
|
Packit Service |
cd2a00 |
ret = -errno;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
out:
|
|
Packit Service |
cd2a00 |
DLEAVE(ret);
|
|
Packit Service |
cd2a00 |
return ret;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
/**
|
|
Packit Service |
cd2a00 |
* @param dsp_protocol dsp_protocol_t structure.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* It releases the semaphore.
|
|
Packit Service |
cd2a00 |
*
|
|
Packit Service |
cd2a00 |
* @return zero if success, otherwise a negative error code.
|
|
Packit Service |
cd2a00 |
*/
|
|
Packit Service |
cd2a00 |
static inline int dsp_protocol_unlock_dev(dsp_protocol_t * dsp_protocol)
|
|
Packit Service |
cd2a00 |
{
|
|
Packit Service |
cd2a00 |
struct sembuf sem_op;
|
|
Packit Service |
cd2a00 |
DENTER();
|
|
Packit Service |
cd2a00 |
sem_op.sem_num = 0;
|
|
Packit Service |
cd2a00 |
sem_op.sem_op = 1;
|
|
Packit Service |
cd2a00 |
sem_op.sem_flg = 0;
|
|
Packit Service |
cd2a00 |
DPRINT("Releasing\n");
|
|
Packit Service |
cd2a00 |
semop(dsp_protocol->sem_set_id, &sem_op, 1);
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
pthread_mutex_unlock(&(dsp_protocol->mutex));
|
|
Packit Service |
cd2a00 |
DLEAVE(0);
|
|
Packit Service |
cd2a00 |
return 0;
|
|
Packit Service |
cd2a00 |
}
|
|
Packit Service |
cd2a00 |
|
|
Packit Service |
cd2a00 |
|