Amr_record

hi,
I must record a vocal message through GSM_RX in format AMR, i have tried to modify relative example to the PCM in this way:

/***************************************************************************/
/*  File       : AMR_Record.c                                        	   */
/*-------------------------------------------------------------------------*/
/***************************************************************************/

#include "adl_global.h"

/***************************************************************************/
/*  Mandatory variables                                                    */
/*-------------------------------------------------------------------------*/
/*  wm_apmCustomStackSize                                                  */
/*-------------------------------------------------------------------------*/
/***************************************************************************/
const u16 wm_apmCustomStackSize = 1024;
const u32 wm_apmIRQLowLevelStackSize =  1024;
const u32 wm_apmIRQHighLevelStackSize = 1024;

/* Global variables */
s32	appAudioMicrophone_Handle =0;
s32 appAudioVoice_RX_Handle  = 0;
s32 appAudioSpeaker_Handle   = 0;
s32 appAudioVoice_TX_Handle  = 0;

s32	appListenLowIrqHandle	= 0;
s32	appListenHighIrqHandle	= 0;
s32 record_resource_Handle	= 0;
s32 play_resource_Handle	= 0;

static ascii *    AUDIO_RECORD_CMD  = "at+RECORD";

#define MICROPHONE 0
#define SPEAKER 0
#define GSM_RX 1
#define GSM_TX 1

adl_atPort_e port_context = 0;
void * StreamBufferListen = NULL;

// Recorded sound duration in seconds
#define DURATION 5
#define BUFFER_SIZE DURATION * 2 * 8000

s32 BufferSizeListen;

/*********************************************************/
/*  Function   : app_RECORD_CmdHandler                   */
/*-------------------------------------------------------*/
/*  Objet      : AT+RECORD = 1  - listen from GSM RX	 */
/*-------------------------------------------------------*/
/*********************************************************/
void app_RECORD_CmdHandler( adl_atCmdPreParser_t * paras )
{
	u8 source = 0;
	s32 RetVal = 0;
	StreamBufferListen = NULL;

	source = wm_atoi ( ADL_GET_PARAM ( paras, 0 ) );
	port_context = paras->Port;

	// Choose Source and destination media

	if (source == GSM_RX){
		TRACE (( 1, "RECORD: GSM_RX" ));
		record_resource_Handle = appAudioVoice_RX_Handle;
	}
	else
	{
		TRACE (( 1, "RECORD: Bad option selected: #%d", source ));
		adl_atSendResponsePort(ADL_AT_RSP, port_context, "\r\nERROR:Bad source selected:USAGE :<param1>: 0 - MICROPHONE, 1- GSM_RX\r\n");
		return;
	}

    adl_audioSetOption( record_resource_Handle, ADL_AUDIO_AMR_MIXED_VOICE, FALSE );
    adl_audioSetOption( record_resource_Handle, ADL_AUDIO_AMR_SPEECH_CODEC_RATE, ADL_AUDIO_AMR_RATE_12_20 );

    // Get Buffer size for Listen and initialize a buffer
	RetVal = adl_audioGetOption( record_resource_Handle, ADL_AUDIO_AMR_BUFFER_SIZE,&BufferSizeListen);
        if (RetVal != OK)
        {
            TRACE (( 1, "app_LISTENPLAY_CmdHandler: OK not received from adl_audioGetOption : %d",RetVal));
            adl_atSendResponsePort(ADL_AT_RSP, port_context, "\r\nERROR:adl_audioGetOption failed\r\n");

            return;
        }

	StreamBufferListen = adl_memGet(BufferSizeListen);
	TRACE (( 1, "app_LISTENPLAY_CmdHandler: BufferSizeListen: #%d", BufferSizeListen ));

	// Start listening
	RetVal = adl_audioStreamListen ( appAudioVoice_RX_Handle, ADL_AUDIO_AMR , appListenLowIrqHandle, appListenHighIrqHandle, StreamBufferListen);
	if (RetVal != OK)
	{
		TRACE (( 1, "app_RECORD_CmdHandler: OK not received from adl_audioStreamListen %d",RetVal));
		adl_atSendResponsePort(ADL_AT_RSP, port_context, "\r\nERROR:adl_audioStreamListen failed\r\n");

	    if(StreamBufferListen)
    	{
		    adl_memRelease(StreamBufferListen);
		   // StreamBufferListen= NULL;
        }

		return;
	}
}

/***************************************************************************/
/*  Function   : appListenLowIrqHandler                                    */
/*-------------------------------------------------------------------------*/
/*  Objet      : IRQ low level handler                                     */
/*-------------------------------------------------------------------------*/
/***************************************************************************/

bool appListenLowIrqHandler( adl_irqID_e Source, adl_irqNotificationLevel_e NotificationLevel, adl_irqEventData_t *Data )
{
        // Do NOT call the high level handler
        return 0;
}

/***************************************************************************/
/*  Function   : appListenHighIrqHandler                                   */
/*-------------------------------------------------------------------------*/
/*  Objet      : IRQ high level handler                                    */
/*-------------------------------------------------------------------------*/
/***************************************************************************/

bool appListenHighIrqHandler(adl_irqID_e Source, adl_irqNotificationLevel_e NotificationLevel,
					         adl_irqEventData_t *Data) {

    // This handler is called only for stopping the recording
    s32 RetVal;

    // Stop recording
    RetVal = adl_audioStop(record_resource_Handle);

    // Release PCM buffer
    if(StreamBufferListen)
    {
        adl_memRelease(StreamBufferListen);
        //StreamBufferListen = NULL;
    }

    if(RetVal != OK)
    {
        TRACE (( 1, "appListenHighIrqHandler: OK not received for adl_pcmStop/listen: #%d", RetVal));
        adl_atSendResponsePort(ADL_AT_RSP, port_context, "\r\nERROR:adl_audioStop for recording failed\r\n");
    }
    else
    {
        // Send OK
        adl_atSendResponsePort(ADL_AT_RSP, port_context, "\r\nOK\r\n"); // OK FOR AT+RECORD
    }

    return 0;
}

/***************************************************************************/
/*  Function   : AudioEventHandler                                        */
/*-------------------------------------------------------------------------*/
/*  Objet      : Audio Event Handler                                       */
/*-------------------------------------------------------------------------*/
/***************************************************************************/
void AudioEventHandler( s32 audioHandle, adl_audioEvents_e Event )  //add events
{
	TRACE (( 1, "Inside the AudioEventHandler: Event :: %d", Event ));

	return;
}

/***************************************************************************/
/*  Function   : adl_main                                                  */
/*-------------------------------------------------------------------------*/
/*  Object     : Customer application initialisation                       */
/*-------------------------------------------------------------------------*/
/***************************************************************************/
void adl_main ( adl_InitType_e InitType )
{
    // AMR Recorder application
    TRACE (( 1, "AMR_Record: Test Application" ));
    TRACE (( 1, __DATE__ ));
    TRACE (( 1, __TIME__ ));

    // Subscribe to IRQ service
    appListenLowIrqHandle = adl_irqSubscribe ( appListenLowIrqHandler, ADL_IRQ_NOTIFY_LOW_LEVEL, ADL_IRQ_PRIORITY_LOW_LEVEL, 1 );
    if( appListenLowIrqHandle < 0 )
        TRACE (( 1, "Listen Low IRQ handler subscription FAILED: %d ", appListenLowIrqHandle ));

    appListenHighIrqHandle = adl_irqSubscribe ( appListenHighIrqHandler, ADL_IRQ_NOTIFY_HIGH_LEVEL, ADL_IRQ_PRIORITY_HIGH_LEVEL, 1 );
    if( appListenHighIrqHandle < 0 )
        TRACE (( 1, "Listen High IRQ handler subscription FAILED: %d ", appListenHighIrqHandle ));

    // Subscribe to audio service
    appAudioMicrophone_Handle = adl_audioSubscribe ( ADL_AUDIO_MICROPHONE , AudioEventHandler, ADL_AUDIO_RESOURCE_OPTION_FORBID_PREEMPTION );
    if(appAudioMicrophone_Handle < 0 )
    	TRACE (( 1, "ADL_AUDIO_MICROPHONE cannot be subscribed :%d", appAudioMicrophone_Handle));

    appAudioVoice_RX_Handle = adl_audioSubscribe ( ADL_AUDIO_VOICE_CALL_RX , AudioEventHandler, ADL_AUDIO_RESOURCE_OPTION_FORBID_PREEMPTION );
    if(appAudioVoice_RX_Handle < 0 )
    	TRACE (( 1, "ADL_AUDIO_VOICE_CALL_RX cannot be subscribed : %d",appAudioVoice_RX_Handle  ));

    appAudioSpeaker_Handle = adl_audioSubscribe ( ADL_AUDIO_SPEAKER , AudioEventHandler, ADL_AUDIO_RESOURCE_OPTION_FORBID_PREEMPTION );
    if(appAudioSpeaker_Handle  < 0 )
    	TRACE (( 1, "ADL_AUDIO_SPEAKER cannot be subscribed: %d", appAudioSpeaker_Handle ));

    appAudioVoice_TX_Handle = adl_audioSubscribe ( ADL_AUDIO_VOICE_CALL_TX , AudioEventHandler, ADL_AUDIO_RESOURCE_OPTION_FORBID_PREEMPTION );
    if(appAudioVoice_TX_Handle  < 0 )
    	TRACE (( 1, "ADL_AUDIO_VOICE_CALL_TX cannot be subscribed : %d", appAudioVoice_TX_Handle  ));

    /* Subscribe for AT+RECORD command */
    adl_atCmdSubscribe (AUDIO_RECORD_CMD, app_RECORD_CmdHandler,  ADL_CMD_TYPE_PARA | 0x11 );
}

… but I obtain this result

09/12/28,04:28:48:875	ADL	1	Binary header at 00260000
09/12/28,04:28:48:890	ADL	1	AMR_Record: Test Application
09/12/28,04:28:48:890	ADL	1	Dec 28 2009
09/12/28,04:28:48:890	ADL	1	16:11:21
09/12/28,04:29:04:968	ADL	1	RECORD: GSM_RX
09/12/28,04:29:04:968	ADL	1	app_LISTENPLAY_CmdHandler: BufferSizeListen: #0
09/12/28,04:29:04:968	ADL	1	app_RECORD_CmdHandler: OK not received from adl_audioStreamListen -2

Thanks
Regards

Hiya,

-2 is ADL_RET_ERR_PARAM - a singularly useless error message as it doesn’t tell WHICH parameter in the function call is wrong.

However, the ADL user guide 6.30 (R7.4) states in section 3.33.8.2 that recording using AMR codec is only available from the microphone input.

Also, you will probably have to have a voice call active before you can attach to the RX stream to listen…

Can you get the PCM sample as supplied by Wavecom to work?

ciao, Dave

and neither does it tell you in what way it is “wrong”! :unamused: :angry:

Using format PCM it works, but in my application I am using already files .amr for the play, therefore I would want to continue to use the same format. I make it the recording to leave after at-command ATA in order to answer and to begin to voice call.
Using PCM format, i can convert file .wav to play it? (file . amr convert in file .h, file PCM convert ???)

Regards

Hiya,

It may be worthwhile checking which version of firmware you have in your device. The AMR audio facility has changed slightly over the life of the R7.x firmware versions…

ciao, Dave

Hi,
the firmware that use is the 7.4a, but to the same problem i had it with the 7.4, i have a doubt, if better to use format PCM instead that AMR? even if with AMR at least in play i have not problem…

Hiya,

I’ve had no problems playing back pre-recorded PCM in firmware R7.3 and R7.4.

I converted the .wav files into raw PCM, then wrote a small application which converted the raw PCM into C source files (with the PCM encoded as C arrays). In the PCM playback I could simply point the playback buffer to the appropriate C array and let it run.

This worked well for me.

ciao, Dave

you could send some example to me.
thanks
Regards

Hi David,

is there any chance that you could share this code? I am looking to try and play a stored wav file (converted into PCM) and store in the code for the Wavecom Supreme 10 and would be grateful for a any help.

Many thanks in advance if you are able to assist.

Paul