FreeCalypso > hg > freecalypso-sw
view gsm-fw/services/etm/etm_audio.c @ 178:7ab6b29e76bb
rvinterf: forwarding of Rx packets to clients implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sat, 23 Nov 2013 22:15:16 +0000 |
parents | d78219c43fbf |
children |
line wrap: on
line source
/******************************************************************************** * Enhanced TestMode (ETM) * @file etm_audio.c (Support for AUDIO commands) * * @author Kim T. Peteren (ktp@ti.com) * @version 0.8 * * * History: * * Date Modification * ------------------------------------ * 16/06/2003 Creation * 30/06/2003 Small cleanup in func. etm_audio_write, etm_audio_saveload and * etm_aud_wait_for_aud_event is updated and renamed * 12/08/2003 The func. etm_audio_write has been updated regarding the AEC struct. * 14/08/2003 The func. etm_audio_read has been updated regarding the AEC struct. * 17/03/2004 Modified the event handling, events revceived from the Audio SWE. * Integrated event callback function, etm_audio_callback(). * * (C) Copyright 2003 by Texas Instruments Incorporated, All Rights Reserved *********************************************************************************/ #include "etm/etm.h" #include "etm/etm_api.h" #include "etm/etm_trace.h" #include "etm/etm_env.h" // Need because use of T_ETM_ENV_CTRL_BLK #include "etm/etm_audio_err.h" // Privat Audio error codes for PC and Target #include "etm/etm_trace.h" #include "audio/audio_api.h" #include "rv/rv_general.h" #include "spi/spi_drv.h" // used for codec read/write #include "memif/mem.h" #include <string.h> /****************************************************************************** * Globals *****************************************************************************/ // Version of the ETM AUDIO module //const uint16 etm_audio_revision = (1<<12) | (0x1); extern T_ETM_ENV_CTRL_BLK *etm_env_ctrl_blk; static int etm_audio_event_status = 0; /****************************************************************************** * Internal prototypes *****************************************************************************/ int etm_audio(uint8 *indata, int insize); T_RV_HDR *etm_audio_wait_for_event(UINT16 msg_id_expected); T_ETM_PKT *etm_audio_setup(uint8 fid, uint8 cfg_data); void etm_audio_callback(void *event_from_audio); /****************************************************************************** * Register the Audio Module to the ETM database *****************************************************************************/ int etm_audio_init(void) { int result; result = etm_register("AUDIO", ETM_AUDIO, 0, 0, etm_audio); return result; } /****************************************************************************** * Audio Full Access Read Function *****************************************************************************/ int etm_audio_read(T_ETM_PKT *pkt, uint8 *buf) { int result, size = 0, size_tmp, i; uint8 param; T_AUDIO_FULL_ACCESS_READ audio; T_AUDIO_AEC_CFG *aec_parameter = NULL; void *parameter = NULL; param = *buf; if ((result = etm_pkt_put8(pkt, param)) < 0) return result; tr_etm(TgTrAudio, "ETM AUDIO: _audio_read: param(%d)", param); audio.variable_indentifier = param; audio.data = (T_AUDIO_FULL_ACCESS_READ *) &pkt->data[2]; //data[0] = fid //data[1] = parameter/identifier if ((result = audio_full_access_read(&audio)) != AUDIO_OK){ tr_etm(TgTrAudio, "ETM AUDIO: _audio_read: ERROR(%d)", result); if (result == AUDIO_ERROR) return ETM_INVAL; // Invalid audio parameter else return ETM_AUDIO_FATAL; } switch (param) { case AUDIO_PATH_USED: size = sizeof(T_AUDIO_VOICE_PATH_SETTING); break; case AUDIO_MICROPHONE_MODE: case AUDIO_MICROPHONE_GAIN: case AUDIO_MICROPHONE_EXTRA_GAIN: case AUDIO_MICROPHONE_OUTPUT_BIAS: case AUDIO_MICROPHONE_SPEAKER_LOOP_SIDETONE: size = sizeof(INT8); break; case AUDIO_MICROPHONE_SPEAKER_LOOP_AEC: size = sizeof(T_AUDIO_AEC_CFG); aec_parameter = (T_AUDIO_AEC_CFG *) &pkt->data[2]; etm_pkt_put16(pkt, aec_parameter->aec_enable); // 1 #if (L1_NEW_AEC) etm_pkt_put16(pkt, aec_parameter->continuous_filtering); // 2 etm_pkt_put16(pkt, aec_parameter->granularity_attenuation); // 3 etm_pkt_put16(pkt, aec_parameter->smoothing_coefficient); // 4 etm_pkt_put16(pkt, aec_parameter->max_echo_suppression_level); // 5 etm_pkt_put16(pkt, aec_parameter->vad_factor); // 6 etm_pkt_put16(pkt, aec_parameter->absolute_threshold); // 7 etm_pkt_put16(pkt, aec_parameter->factor_asd_filtering); // 8 etm_pkt_put16(pkt, aec_parameter->factor_asd_muting); // 9 etm_pkt_put16(pkt, aec_parameter->aec_visibility); //10 #else etm_pkt_put16(pkt, aec_parameter->aec_mode); // 2 etm_pkt_put16(pkt, aec_parameter->echo_suppression_level); // 3 #endif // end of (L1_NEW_AEC) etm_pkt_put16(pkt, aec_parameter->noise_suppression_enable); // 4 or 11 etm_pkt_put16(pkt, aec_parameter->noise_suppression_level); // 5 or 12 break; case AUDIO_MICROPHONE_FIR: case AUDIO_SPEAKER_FIR: size = sizeof(T_AUDIO_FIR_COEF); break; case AUDIO_SPEAKER_MODE: case AUDIO_SPEAKER_GAIN: case AUDIO_SPEAKER_FILTER: case AUDIO_SPEAKER_BUZZER_STATE: size = sizeof(INT8); break; case AUDIO_SPEAKER_VOLUME_LEVEL: size = sizeof(T_AUDIO_SPEAKER_LEVEL); break; default: size = ETM_INVAL; } pkt->size += size; return ETM_OK; } /****************************************************************************** * Audio Full Access Write Function *****************************************************************************/ int etm_audio_write(T_ETM_PKT *pkt, uint8 *buf) { T_RV_HDR *msg = NULL; T_RV_RETURN return_path; T_AUDIO_FULL_ACCESS_WRITE audio; T_AUDIO_AEC_CFG *aec_parameter = NULL; void *parameter = NULL; int result = ETM_OK, i; uint8 param; param = *buf++; if ((result = etm_pkt_put8(pkt, param)) < ETM_OK) { return result; } tr_etm(TgTrAudio, "ETM AUDIO: _audio_write: param(%d)", param); return_path.addr_id = NULL; //etm_env_ctrl_blk->addr_id; return_path.callback_func = etm_audio_callback; audio.variable_indentifier = param; audio.data = buf; switch (param) { case AUDIO_MICROPHONE_SPEAKER_LOOP_AEC: tr_etm(TgTrAudio, "ETM AUDIO: _audio_write: AUDIO_MICROPHONE_SPEAKER_LOOP_AEC"); // RemoveMe aec_parameter = etm_malloc (sizeof(T_AUDIO_AEC_CFG)); aec_parameter->aec_enable = etm_get16(buf); buf += 2;// 1 #if (L1_NEW_AEC) if (etm_get16(buf)) // 2 aec_parameter->continuous_filtering = TRUE; else aec_parameter->continuous_filtering = FALSE; buf += 2; aec_parameter->granularity_attenuation = etm_get16(buf); buf += 2;// 3 aec_parameter->smoothing_coefficient = etm_get16(buf); buf += 2;// 4 aec_parameter->max_echo_suppression_level = etm_get16(buf); buf += 2;// 5 aec_parameter->vad_factor = etm_get16(buf); buf += 2;// 6 aec_parameter->absolute_threshold = etm_get16(buf); buf += 2;// 7 aec_parameter->factor_asd_filtering = etm_get16(buf); buf += 2;// 8 aec_parameter->factor_asd_muting = etm_get16(buf); buf += 2;// 9 aec_parameter->aec_visibility = etm_get16(buf); buf += 2;// 10 #else aec_parameter->aec_mode = etm_get16(buf); buf += 2;// 2 aec_parameter->echo_suppression_level = etm_get16(buf); buf += 2;// 3 #endif // end of (L1_NEW_AEC) #if (L1_ANR == 0) aec_parameter->noise_suppression_enable = etm_get16(buf); buf += 2;// 4 or 11 aec_parameter->noise_suppression_level = etm_get16(buf); // 5 or 12 #endif // end of (L1_ANR) audio.data = aec_parameter; break; case AUDIO_MICROPHONE_FIR: case AUDIO_SPEAKER_FIR: tr_etm(TgTrAudio, "ETM AUDIO: _audio_write: AUDIO_MICROPHONE/SPEAKER_FIR [%d]", sizeof(T_AUDIO_FIR_COEF)/2); // RemoveMe parameter = etm_malloc (sizeof(T_AUDIO_FIR_COEF)); // Write coeffient values for (i=0; i <= (sizeof(T_AUDIO_FIR_COEF)/2); i++) { ((T_AUDIO_FIR_COEF *) parameter)->coefficient[i] = etm_get16(buf); buf += 2; } audio.data = parameter; break; } if ((result = audio_full_access_write(&audio, return_path)) != AUDIO_OK) { tr_etm(TgTrAudio, "ETM AUDIO: _audio_write: ERROR(%d)", result); if (result == AUDIO_ERROR) result = ETM_INVAL; // Invalid audio parameter else result = ETM_AUDIO_FATAL; } // Wait for recv. of event: AUDIO_FULL_ACCESS_WRITE_DONE rvf_wait(0xffff, 100); // Timeout 100 ticks tr_etm(TgTrAudio, "ETM AUDIO: _audio_write: STATUS(%d)", etm_audio_event_status); if (parameter != NULL) { etm_free(parameter); parameter = NULL; } if (aec_parameter != NULL) { etm_free(aec_parameter); aec_parameter = NULL; } if (etm_audio_event_status != 0) { etm_audio_event_status = 0; result = ETM_AUDIO_FATAL; } return result; } /****************************************************************************** * Audio Save and Load cfg file Function *****************************************************************************/ int etm_audio_saveload(T_ETM_PKT *pkt, uint8 saveload, void *buf, int size) { T_RV_HDR *msg; T_AUDIO_MODE_SAVE audio_s; T_AUDIO_MODE_LOAD audio_l; T_RV_RETURN return_path; int result = ETM_OK; int error, event; return_path.addr_id = etm_env_ctrl_blk->addr_id; return_path.callback_func = NULL; switch(saveload) { case 'S': memcpy(audio_s.audio_mode_filename, buf, size); result = audio_mode_save(&audio_s, return_path); break; case 'L': memcpy(audio_l.audio_mode_filename, buf, size); result = audio_mode_load(&audio_l, return_path); break; default: tr_etm(TgTrAudio, "ETM AUDIO: _audio_saveload: FAILED"); break; } rvf_wait(0xffff, 100); // Timeout 100 ticks tr_etm(TgTrAudio, "ETM AUDIO: _audio_saveload: STATUS(%d)", etm_audio_event_status); if (etm_audio_event_status != 0) { etm_audio_event_status = 0; return ETM_AUDIO_FATAL; } if (result != AUDIO_OK) return ETM_AUDIO_FATAL; return result; } /****************************************************************************** * ETM AUDIO callback functio *****************************************************************************/ void etm_audio_callback(void *event_from_audio) { tr_etm(TgTrEtmLow,"ETM: AUDIO: _audio_callback: recv. event (0x%x)", ((T_RV_HDR *) event_from_audio)->msg_id); switch (((T_RV_HDR *) event_from_audio)->msg_id) { case AUDIO_FULL_ACCESS_WRITE_DONE: tr_etm(TgTrAudio, "ETM AUDIO: _audio_callback: recv. event AUDIO_FULL_ACCESS_WRITE_DONE"); etm_audio_event_status = ((T_AUDIO_FULL_ACCESS_WRITE_DONE *) event_from_audio)->status; break; case AUDIO_MODE_SAVE_DONE: tr_etm(TgTrAudio, "ETM AUDIO: _audio_callback: recv. event AUDIO_MODE_SAVE_DONE"); etm_audio_event_status = ((T_AUDIO_SAVE_DONE *) event_from_audio)->status; break; case AUDIO_MODE_LOAD_DONE: tr_etm(TgTrAudio, "ETM AUDIO: _audio_callback: recv. event AUDIO_MODE_LOAD_DONE"); etm_audio_event_status = ((T_AUDIO_LOAD_DONE *) event_from_audio)->status; break; } if (event_from_audio != NULL) { // etm_free(event_from_audio); event_from_audio = NULL; } } /****************************************************************************** * ETM AUDIO Moudle - Main Task *****************************************************************************/ // AUDIO packet structure for audio read/write and codec read/write: // |fid(8)|param(8)|--data(W)--| and for audio save/load |fid|--data(W)--| int etm_audio(uint8 *indata, int insize) { int error = ETM_OK; uint8 fid; T_ETM_PKT *pkt = NULL; fid = *indata++; tr_etm(TgTrAudio, "ETM AUDIO: _audio: fid(%c) param(%d) recv. size(%d)", fid, *indata, insize); /* Create TestMode return Packet */ if ((pkt = (T_ETM_PKT *) etm_malloc(sizeof(T_ETM_PKT))) == NULL) { return ETM_NOMEM; } // Init. of return packet pkt->mid = ETM_AUDIO; pkt->status = ETM_OK; pkt->size = 0; pkt->index = 0; etm_pkt_put8(pkt, fid); if (error == ETM_OK) { switch (fid) { case 'R': error = etm_audio_read(pkt, indata); break; case 'W': error = etm_audio_write(pkt, indata); break; case 'S': case 'L': error = etm_audio_saveload(pkt, fid, indata, insize); break; default: tr_etm(TgTrAudio, "ETM AUDIO: _audio: fid(%c) - ERROR ", fid); error = ETM_NOSYS; break; } } if (error < 0) { tr_etm(TgTrAudio,"ETM AUDIO: _audio: ERROR(%d)", error); pkt->status = -error; } etm_pkt_send(pkt); etm_free(pkt); return ETM_OK; }