Beispiel #1
0
void Logging_task(uint_32 param)
{
   _queue_id         log_qid;
   LOG_MESSAGE_PTR   msg_ptr;
#if DEMOCFG_ENABLE_USB_FILESYSTEM
  MQX_FILE_PTR      log_fp;
#endif
 
   // create a pool of logging messages   
   log_pool = _msgpool_create(sizeof(LOG_MESSAGE), LOG_POOL_SIZE, 0, 0);

   // open a message queue to receive log message on
   log_qid = _msgq_open(LOG_QUEUE, 0);
   
      
   // signal that initialization is complete
   _lwsem_post(&Logging_init_sem);

   while (TRUE) {
      // wait for a message
      msg_ptr = _msgq_receive(log_qid, 0);

      if (msg_ptr) {
         #if DEMOCFG_ENABLE_USB_FILESYSTEM
            // check to see if a filesystem is available
            if (_lwsem_poll(&USB_Stick)) {

               // Open the log file and position to the end
               log_fp = fopen(LOG_FILE,"a");

               if (log_fp) {
                  fseek(log_fp,0,IO_SEEK_END);
         
                  do {
                     // Write the message to the log file
                     write(log_fp,msg_ptr->MESSAGE, strlen(msg_ptr->MESSAGE));

                     // Return the message back to the message pool
                     _msg_free(msg_ptr);

                     // check for another message
                     msg_ptr = _msgq_poll(log_qid);
                  } while (msg_ptr != NULL);

                  // close the file
                  fclose(log_fp);
               }

               // Indicate that the USB stick is no longer in use
               _lwsem_post(&USB_Stick);
            } else {
               _msg_free(msg_ptr);
            }
         #else
            printf(msg_ptr->MESSAGE);
            _msg_free(msg_ptr);
         #endif
      }
   }
}
Beispiel #2
0
static boolean usbstick_attached() {
#if DEMOCFG_ENABLE_USB_FILESYSTEM
    if (_lwsem_poll(&USB_Stick)) {
        _lwsem_post(&USB_Stick);
        return TRUE;
    } else
#endif      
        return FALSE;
}
Beispiel #3
0
static void usb_status_fn(HTTPD_SESSION_STRUCT *session) {
#if DEMOCFG_ENABLE_USB_FILESYSTEM
    if (_lwsem_poll(&USB_Stick)) {
        httpd_sendstr(session->sock, "visible");
        _lwsem_post(&USB_Stick);
    }
    else
#endif      
        httpd_sendstr(session->sock, "hidden");
}
Beispiel #4
0
/*!
 * \brief 	MQX API handler for usermode - part of wrapper around standard MQX API
 *  which require privilege mode.
 *
 * \param[in] api_no API number - number of wrapped function
 * \param[in] params generic parameter - direct use with called MQX API fn
 *
 * \return uint32_t return of called function
 */
uint32_t _mqx_api_call_handler
    (
        // [IN] API number - number of wrapped function
        MQX_API_NUMBER_ENUM api_no,
        // [IN] generic parameter - direct use with called MQX API fn
        MQX_API_CALL_PARAMS_PTR params
    )
{
    int32_t res = -1;
    uint32_t param0 = params->param0;
    uint32_t param1 = params->param1;
    uint32_t param2 = params->param2;
    uint32_t param3 = params->param3;
    uint32_t param4 = params->param4;

    switch (api_no) {

    // _lwsem
    case MQX_API_LWSEM_POLL:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)))
            res = (uint32_t)_lwsem_poll((LWSEM_STRUCT_PTR)param0);
        break;
    case MQX_API_LWSEM_POST:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)))
            res = _lwsem_post((LWSEM_STRUCT_PTR)param0);
        break;
    case MQX_API_LWSEM_WAIT:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)))
            res = _lwsem_wait((LWSEM_STRUCT_PTR)param0);
        break;
    case MQX_API_LWSEM_CREATE:
        res = _lwsem_create_internal((LWSEM_STRUCT_PTR)param0, (_mqx_int)param1, (bool)param2, TRUE);
        break;
#if MQX_HAS_TICK
    case MQX_API_LWSEM_WAIT_FOR:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)) && (!param1 || _psp_mem_check_access(param1, sizeof(MQX_TICK_STRUCT), MPU_UM_RW)))
            res = _lwsem_wait_for((LWSEM_STRUCT_PTR)param0, (MQX_TICK_STRUCT_PTR)param1);
        break;
    case MQX_API_LWSEM_WAIT_TICKS:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)))
            res = _lwsem_wait_ticks((LWSEM_STRUCT_PTR)param0, (_mqx_uint)param1);
        break;
    case MQX_API_LWSEM_WAIT_UNTIL:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0)) && (!param1 || _psp_mem_check_access(param1, sizeof(MQX_TICK_STRUCT), MPU_UM_RW)))
            res = _lwsem_wait_until((LWSEM_STRUCT_PTR)param0, (MQX_TICK_STRUCT_PTR)param1);
        break;
    case MQX_API_LWSEM_DESTROY:
        if (MQX_OK == (res = _lwsem_usr_check((LWSEM_STRUCT_PTR)param0))) {
            res = _lwsem_destroy_internal((LWSEM_STRUCT_PTR)param0, TRUE);
        }
        break;

#endif // MQX_HAS_TICK

    // _lwevent
#if MQX_USE_LWEVENTS
    case MQX_API_LWEVENT_CLEAR:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)))
            res = _lwevent_clear((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1);
        break;
    case MQX_API_LWEVENT_SET:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)))
            res = _lwevent_set((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1);
        break;
    case MQX_API_LWEVENT_SET_AUTO_CLEAR:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)))
            res = _lwevent_set_auto_clear((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1);
        break;
    case MQX_API_LWEVENT_WAIT_FOR:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)) && \
            (!param3 || _psp_mem_check_access(param3, sizeof(MQX_TICK_STRUCT), MPU_UM_RW))) {
            res = _lwevent_wait_for((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, (bool)param2, (MQX_TICK_STRUCT_PTR)param3);
        }
        break;
    case MQX_API_LWEVENT_WAIT_FOR_TICKS:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0))) {
            res = _lwevent_wait_ticks((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, (bool)param2, (_mqx_uint)param3);
        }
        break;
    case MQX_API_LWEVENT_WAIT_UNTIL:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0)) && \
            (!param3 || _psp_mem_check_access(param3, sizeof(MQX_TICK_STRUCT), MPU_UM_RW))) {
            res = _lwevent_wait_until((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, (bool)param2, (MQX_TICK_STRUCT_PTR)param3);
        }
        break;
    case MQX_API_LWEVENT_GET_SIGNALLED:
        res = _lwevent_get_signalled();
        break;

    case MQX_API_LWEVENT_CREATE:
        res = _lwevent_create_internal((LWEVENT_STRUCT_PTR)param0, (_mqx_uint)param1, TRUE);
        break;

    case MQX_API_LWEVENT_DESTROY:
        if (MQX_OK == (res = _lwevent_usr_check((LWEVENT_STRUCT_PTR)param0))) {
            res = _lwevent_destroy_internal((LWEVENT_STRUCT_PTR)param0, TRUE);
        }
        break;
#endif

#if MQX_USE_LWMSGQ
    case MQX_API_LWMSGQ_INIT:
        res = _lwmsgq_init_internal((void *)param0, (_mqx_uint)param1, (_mqx_uint)param2, TRUE);
        break;
    case MQX_API_LWMSGQ_RECEIVE:
        if (MQX_OK == (res = _lwmsgq_usr_check((LWMSGQ_STRUCT_PTR)param0)) && \
            _psp_mem_check_access(param1, ((LWMSGQ_STRUCT_PTR)param0)->MSG_SIZE, MPU_UM_RW) && \
            (!param4 || _psp_mem_check_access(param4, sizeof(MQX_TICK_STRUCT), MPU_UM_RW)))
            res = _lwmsgq_receive((void *)param0, (_mqx_max_type_ptr)param1, (_mqx_uint)param2, (_mqx_uint)param3, (MQX_TICK_STRUCT_PTR)param4);

        break;
    case MQX_API_LWMSGQ_SEND:
        if (MQX_OK == (res = _lwmsgq_usr_check((LWMSGQ_STRUCT_PTR)param0)) && \
            _psp_mem_check_access(param1, ((LWMSGQ_STRUCT_PTR)param0)->MSG_SIZE, MPU_UM_RW))
            res = _lwmsgq_send((void *)param0, (_mqx_max_type_ptr)param1, (_mqx_uint)param2);
        break;
#endif // MQX_USE_LWMSGQ

    case MQX_API_TASK_CREATE:
        res = _task_create_internal((_processor_number)param0, (_mqx_uint)param1, (uint32_t)param2, TRUE);
        break;
    case MQX_API_TASK_DESTROY:
        res = _task_destroy_internal((_task_id)param0, TRUE);
        break;
    case MQX_API_TASK_ABORT:
        res = _task_abort_internal((_task_id)param0, TRUE);
        break;
    case MQX_API_TASK_READY:
        _task_ready((void *)param0);
        res = MQX_OK;       // irelevant, function is without return value
        break;
    case MQX_API_TASK_SET_ERROR:
        res = _task_set_error((_mqx_uint)param0);
        break;
    case MQX_API_TASK_GET_TD:
        res = (uint32_t)_task_get_td((_task_id)param0);
        break;

#if MQX_USE_LWMEM
    case MQX_API_LWMEM_ALLOC:
        res = (uint32_t)_usr_lwmem_alloc_internal((_mem_size)param0);
        break;

    case MQX_API_LWMEM_ALLOC_FROM:
        if (_psp_mem_check_access(param0, sizeof(LWMEM_POOL_STRUCT), MPU_UM_RW) && \
            _psp_mem_check_access((uint32_t)(((LWMEM_POOL_STRUCT_PTR)param0)->POOL_ALLOC_START_PTR), (char*)(((LWMEM_POOL_STRUCT_PTR)param0)->POOL_ALLOC_END_PTR) - (char*)(((LWMEM_POOL_STRUCT_PTR)param0)->POOL_ALLOC_START_PTR), MPU_UM_RW))
            res = (uint32_t)_lwmem_alloc_from((_lwmem_pool_id)param0, (_mem_size)param1);
        else
            res = 0; // NULL, allocation failed
        break;

    case MQX_API_LWMEM_FREE:
        if (_psp_mem_check_access(param0, 4, MPU_UM_RW))
            res = _lwmem_free((void *)param0);
        break;

    case MQX_API_LWMEM_CREATE_POOL:\
        if (_psp_mem_check_access(param0, sizeof(LWMEM_POOL_STRUCT), MPU_UM_RW) && \
            _psp_mem_check_access(param1, param2, MPU_UM_RW))
            res = (uint32_t)_lwmem_create_pool((LWMEM_POOL_STRUCT_PTR)param0, (void *)param1, (_mem_size)param2);
        break;

    case MQX_API_LWMEM_REALLOC:
        if (_psp_mem_check_access(param0, 4, MPU_UM_RW))
          res = (uint32_t)_lwmem_realloc((void *)param0,(_mem_size)param1);
        break;
#endif // MQX_USE_LWMEM

    // _time
    case MQX_API_TIME_DELAY:
        _time_delay(param0);
        res = MQX_OK;       // irelevant, function is without return value
        break;

#if MQX_HAS_TICK
    case MQX_API_TIME_DELAY_TICKS:
        _time_delay_ticks(param0);
        res = MQX_OK;       // irelevant, function is without return value
        break;
    case MQX_API_TIME_GET_ELAPSED_TICKS:
        if (_psp_mem_check_access(param0, sizeof(MQX_TICK_STRUCT), MPU_UM_RW)) {
            _time_get_elapsed_ticks((MQX_TICK_STRUCT_PTR)param0);
            res = MQX_OK;       // irelevant, function is without return value
        }
        else {
            _task_set_error(MQX_ACCESS_ERROR);
        }

        break;
#endif // MQX_HAS_TICK
    default:
        while (1);
    }

    return res;
}
Beispiel #5
0
void local_player_task(uint_32 para) 
{
	_mqx_int return_code, res;
	my_audio_format_t format;
	FILE_PTR stream_ptr = NULL, stream_ptr1 = NULL;      //device_ptr = NULL, 
	uint_32 mclk_freq, fs_freq, bit_width = 0;
	I2S_STATISTICS_STRUCT stats;
	int32_t numberOfSamples =0, sampleProduced, bufOut;
	file_meta_data_t * metadata = NULL;
	audio_stream_type_t stream_type;
	char_ptr mem_ptr = NULL;
	boolean shell_cmd = FALSE;
        CCI_Ctx ctx;
	int32_t strLen, i;
	uint32_t file_extension=0;
	
	_task_id pcm_flush_id = MQX_NULL_TASK_ID;
	uint_32 cnt = 0;
	int32_t max_audio_buf_size = 0;
	lp_param_t *  lpp_param =  (lp_param_t *)para;
        TASK_TEMPLATE_STRUCT task_template;

	printf("local_player_task.. Enter 1\n");
	if (msi_snd_init_with_periodbuffer(1024, 18) != 0) /* for SPI sd card play FLAC, 18K buffer is at least! */
	{
		LOCALPLAY_LOG("  Error: Unable to open the device \"%s\".\n",
				AUDIO_DIVECE_NAME_STR);
		return;
	}
	
	/* create semaphore must before pcm_flush_task */
	if(MQX_OK != _lwsem_create(&pcm_decoded_sem, 0))
	{
		LOCALPLAY_LOG("\n Error - Unable to creat lwsem: pcm_decoded_sem\n");
	}
	
	
        LOCALPLAY_LOG("Creating pcm flush task.........\n");

        task_template.TASK_TEMPLATE_INDEX  = 0;
        task_template.TASK_ADDRESS         = pcm_flush_task;
        task_template.TASK_STACKSIZE       = 2000;
        task_template.TASK_PRIORITY        = 12;
        task_template.TASK_NAME            = "pcm_flush";
        task_template.TASK_ATTRIBUTES      = 0;
        task_template.CREATION_PARAMETER   = 0;
        task_template.DEFAULT_TIME_SLICE   = 0;

        pcm_flush_id = _task_create_blocked(0, 0, (uint_32)&task_template);

        if (pcm_flush_id  == MQX_NULL_TASK_ID)
        {
            printf("local_player_task create pcm_flush_task failed \n");
            goto clean_up;
        }
        else{
            gPcmFlushTaskFinish = 0;
            _task_ready(_task_get_td(pcm_flush_id));
            _lwevent_set(&player_event, PLAYER_EVENT_MSK_SONG_RESUME);
        }


	metadata = (file_meta_data_t *) _mem_alloc_system_zero(sizeof(file_meta_data_t));
	if (NULL == metadata) 
	{
		LOCALPLAY_LOG("\n Failed to allocate memory for metadata.\n");
		return;
	}

        decoding = TRUE;
	
	while (1) {

#ifndef  USB_ACCESSORY_PLAY		
		_lwevent_wait_ticks(
				&player_event,
				PLAYER_EVENT_MSK_SONG_READY | PLAYER_EVENT_MSK_SD_FS_UNMOUNTED
						| PLAYER_EVENT_MSK_SHELL_COMMAND, FALSE, 0);
#else
_lwevent_wait_ticks(
				&player_event,
				PLAYER_EVENT_MSK_SONG_READY | PLAYER_EVENT_MSK_SD_FS_UNMOUNTED
						| PLAYER_EVENT_MSK_SHELL_COMMAND | PLAYER_EVENT_MSK_USB_ATTACHED, FALSE, 0);		
#endif
		shell_cmd = FALSE;


#ifdef USB_ACCESSORY_PLAY
		if (player_event.VALUE & PLAYER_EVENT_MSK_USB_ATTACHED) {
					_lwevent_clear(&player_event, PLAYER_EVENT_MSK_USB_ATTACHED);
					//LOCALPLAY_LOG("__guoyifang__: sd_player_task PLAYER_EVENT_MSK_USB_ACC_ATTACHED \n");
					break;
				}
#endif

		if (player_event.VALUE & PLAYER_EVENT_MSK_SD_FS_UNMOUNTED) {
			_lwevent_clear(&player_event, PLAYER_EVENT_MSK_SD_FS_UNMOUNTED);
			//LOCALPLAY_LOG("__guoyifang__: sd_player_task PLAYER_EVENT_MSK_SD_FS_UNMOUNTED \n");
			break;
		}	

		if (player_event.VALUE & PLAYER_EVENT_MSK_SONG_READY) {
			_lwevent_clear(&player_event, PLAYER_EVENT_MSK_SONG_READY);
		}

		if (player_event.VALUE & PLAYER_EVENT_MSK_SHELL_COMMAND) {
			_lwevent_clear(&player_event, PLAYER_EVENT_MSK_SHELL_COMMAND);
			shell_cmd = TRUE;
		}

		LOCALPLAY_LOG(" --------------------------------------------------------------\n");

	    printf("play lock umount at %d\n",lpp_param->lp_type);
	    _lwsem_wait(lpp_param->mfs_io_sem);
	    /******************decoding is a critical value, assume decoding is TRUE every time.*******************/    
	    printf("SET decoding.\n");
	    decoding = TRUE; // next/prev btn ISR may clear decoding to 0
	    /*******************************************/
		/*config the audio subsystem according metadata*/
		        		printf(
		        				"  Open stream file %s\n", full_path);
		        		stream_ptr = fopen(full_path, "r");
		        		if (stream_ptr == NULL) {
		        			printf("  Unable to open the file: %s\n", full_path);
		        			goto clean_up;
		        		}

		        		stream_ptr1 = fopen(full_path, "r");
		        		if (stream_ptr1 == NULL) {
		        			printf("  Unable to open the file: %s\n", full_path);
		        			goto clean_up;
		        		}
		        		
		                /* Determine the extension of the file */ 
		                i=0;
		                strLen= strlen((const char *)full_path);

		                if(strLen > 4){
		                    /* find the '.' */
		                    while(strLen--){
		                        if(full_path[i]=='.')
		                            break;
		                        i++;
		                    }
		                    if(strLen){
		                        char *p;
		                        /* Copy out the extension : 8.3 filename */
		                        memcpy(&file_extension, full_path+i+1, 3);
		                        p = (char *) (&file_extension);
		                        for(i = 0; i < 4; i++, p++){
		                            if((*p >= 'a') && (*p <= 'z')){
		                                *p -= ('a' - 'A');
		                            }
		                        }
		                    } 

		                    ctx.user_data = (void*) stream_ptr;
		                    ctx.cci_dec_read = get_file_data;;
		                    ctx.cci_dec_seek = seek_file_data;
		                    ctx.cci_dec_tell = get_file_position;

		                    /* Check if metadata was found. */
		                    return_code = cci_extract_meta_data(file_extension, metadata, &ctx);        
		        		    if (return_code != 0) {
		        			    printf("\n Metadata not found\n");
		        			    goto clean_up;
		        		    }

		        		    print_metadata(metadata); //todo

		                } else {
		        			printf("\n Metadata not found\n");
		        			goto clean_up;
		                }
		                if ( metadata->stream_type == STREAM_TYPE_MP3 ) {
		                	/* Seek from the beginning of the file */ 
		                    seek_file_data(0, metadata->start_pos, 0, stream_ptr);
		                } else {
		                	/* Seek from the beginning of the file */
		                	seek_file_data(0, 0, 0, stream_ptr);
		        		}
		        
		        
		        stream_type = metadata->stream_type;

#if 0	
		format.audio_format.ENDIAN = AUDIO_LITTLE_ENDIAN;
		format.audio_format.ALIGNMENT = AUDIO_ALIGNMENT_LEFT;
		if((streamType == kCodecStreamTypePcm) ||	// bitsPerSample Value is 8/16/24
				/*
				 * The demo not support kCodecStreamTypeImaAdpcm/kCodecStreamTypeMsAdpcm currently.
				 */
				(streamType == kCodecStreamTypeImaAdpcm) || // bitsPerSample Value is 4
				(streamType == kCodecStreamTypeMsAdpcm))	// bitsPerSample Value is 4
		{	
			format.audio_format.BITS = metadata->i32BitsPerSample;
		}else{
			format.audio_format.BITS = 16; 
		}
		
		// Currently, the wave decoder output 16bits only for kCodecStreamTypePcm.
		format.audio_format.BITS = 16;
		
		format.audio_format.SIZE = (format.audio_format.BITS + 7)/8;

		
		format.audio_format.CHANNELS = metadata->i32NumChannels;
		format.fs_freq = metadata->u32SampleRate;

		fs_freq = format.fs_freq;
		mclk_freq = fs_freq * CLK_MULT;
		// Setup audio data format in device 
		if (ioctl(device_ptr, IO_IOCTL_AUDIO_SET_IO_DATA_FORMAT,
				&format.audio_format) != I2S_OK) {
			LOCALPLAY_LOG("  Error: Input data format not supported.\n");
			goto clean_up;
		}
		// Setup rest of parameters - master clock, valid data bits and sampling frequency 
		if ((ioctl(device_ptr, IO_IOCTL_I2S_SET_MCLK_FREQ, &mclk_freq) != I2S_OK)
				|| (ioctl(device_ptr, IO_IOCTL_I2S_SET_DATA_BITS,
						&format.audio_format.BITS) != I2S_OK)
				|| (ioctl(device_ptr, IO_IOCTL_I2S_SET_FS_FREQ, &fs_freq)
						!= I2S_OK)) {
			LOCALPLAY_LOG("  Error: Unable to setup \"%s\" device driver.\n",
					AUDIO_DIVECE_NAME_STR);
			goto clean_up;
		}

		// Setup audio codec 
		return_code = SetupCodec(device_ptr);
		if (return_code != 0) {
			LOCALPLAY_LOG("  Audio codec configuration failed. Error 0x%X.\n",
					return_code);
			goto clean_up;
		}

		ioctl(device_ptr, IO_IOCTL_I2S_GET_FS_FREQ, &fs_freq);
		ioctl(device_ptr, IO_IOCTL_I2S_GET_DATA_BITS, &bit_width);
		LOCALPLAY_LOG("  Playback information\n");
		LOCALPLAY_LOG("  Sampling frequency:     %d Hz\n", fs_freq);
		LOCALPLAY_LOG("  Bit depth:              %d bits\n", (uint_8)bit_width);
		LOCALPLAY_LOG("  Channels:               ");
		
		if (format.audio_format.CHANNELS == 1) {
			LOCALPLAY_LOG("mono\n");
		} else {
			LOCALPLAY_LOG("stereo\n");
		}
#else
		if((stream_type == STREAM_TYPE_PCM) ||	// bitsPerSample Value is 8/16/24
		/*
		 * The demo not support kCodecStreamTypeImaAdpcm/kCodecStreamTypeMsAdpcm currently.
		 */
		(stream_type == STREAM_TYPE_IMAADPCM) || // bitsPerSample Value is 4
		(stream_type == STREAM_TYPE_MSADPCM))	// bitsPerSample Value is 4
		{	
			format.audio_format.BITS = metadata->bits_per_sample;
		}else{
			format.audio_format.BITS = 16; 
		}
		
		format.audio_format.CHANNELS = metadata->num_channels;
		// Currently, the wave decoder output 16bits only for kCodecStreamTypePcm.
		format.audio_format.BITS = 16;
#if 0
		if(audio_ioctl(setChNum, format.audio_format.CHANNELS)!= I2S_OK)
        {
		  LOCALPLAY_LOG("  Error: audio_ioctl setChNum failed.\n");
		  goto clean_up;
        }
		if(audio_ioctl(setBitWidth, format.audio_format.BITS)!= I2S_OK)
		{

		  LOCALPLAY_LOG("  Error: audio_ioctl setBitWidth failed.\n");
		  goto clean_up;
		}
#endif
		
		format.fs_freq = metadata->sample_rate;
		
#if 0
		if(audio_ioctl(setSamplerate, format.fs_freq)!= I2S_OK)
	    {
		  LOCALPLAY_LOG("  Error: audio_ioctl setSamplerate failed.\n");
		  goto clean_up;
	    }
#endif
		msi_snd_set_format(format.fs_freq, format.audio_format.BITS, format.audio_format.CHANNELS);
	

#endif

		mem_ptr = (char_ptr) _mem_alloc_system_zero(codec_get_mem_info(stream_type));
		if (NULL == mem_ptr) {
			LOCALPLAY_LOG("Failed to allocate memory for the decoder.\n");
			goto clean_up;
		}

		// MP4 decoder need two fd
		g_userData[0] = (int) stream_ptr;
		g_userData[1] = (int) stream_ptr1;
		if (metadata->audio_sub_type == MEDIA_SUBTYPE_ADTS)
			g_userData[2] = 1;
		else if (metadata->audio_sub_type == MEDIA_SUBTYPE_M4A)
			g_userData[2] = 2;
		else if ( metadata->stream_type == STREAM_TYPE_OPUS )
		{
			g_userData[2] = metadata->sample_rate;
			g_userData[3] = metadata->num_channels;
	    }
		else
			g_userData[2] = 0; 

		g_callbackFunctionArray[0] = (int32_t *) &get_file_data;
		g_callbackFunctionArray[1] = (int32_t *) &seek_file_data;
		g_callbackFunctionArray[2] = (int32_t *) &get_file_position;

		while (1) {
			res = codec_init(stream_type, (long **)&mem_ptr,g_callbackFunctionArray,
								&g_userData[0]);
			if (res == CODEC_INIT_ERROR) {
				LOCALPLAY_LOG("\n  Codec Init Failed with error code %d\n", res);
				decoding = FALSE; 
				goto clean_up;
			}
			if (res == CODEC_MORE_DATA_REQUIRED) {
				LOCALPLAY_LOG("\n  More Data Processing Required for Init \n");
			}
			if (res == CODEC_SUCCESS) {
				LOCALPLAY_LOG("\n  Codec Init Done Successfully \n\n");
				break;
			}
			else {
				printf("codec init other err\n");
				decoding = FALSE;
				goto clean_up;
			}
		}

		if (res == CODEC_SUCCESS) {
			LOCALPLAY_LOG("  Playing %s...\n\n", full_path);
		//	ioctl(device_ptr, IO_IOCTL_I2S_CLEAR_STATISTICS, NULL);
			/* Reset variables before every song's playbacking */
			
			//printf("SET decoding.\n");
			//decoding = TRUE; // next/prev btn ISR may clear decoding to 0
			cnt = 0;

			max_audio_buf_size = 0;
			g_audio_buf_ptr = NULL;
			//_lwevent_clear(&player_event, PLAYER_EVENT_MSK_AUDIO_BUF_FILLED);
			/* Clear pcm_decoded_sem for play next song */
			_lwsem_poll(&pcm_decoded_sem);
			_lwsem_poll(&pcm_decoded_sem);  
					
			if(MQX_OK != _lwsem_create(&pcm_flush_sem, AUDIO_BUF_CNT))
			{
				LOCALPLAY_LOG("\n Error - Unable to create lwsem: pcm_flush_sem\n");
			}
			
			/*
			 * umute
			 */
			msi_snd_umute();
			//sai_dma_output_init();
			
			while (decoding) {
				/*
				 * For FLAC decoder, it produced more than 18K bytes per frame, and takes about 30ms. 
				 * While take 44.1K/16bit/2ch/4Kbytes DMA buffer as example, the margin time is 4K/4/2/44100~=10ms. 
				 * We need bigger DMA buffer, or decode in a ping-pong way.
				 */		
				res = codec_decode(stream_type, (long **)&mem_ptr, &sampleProduced,
										&bufOut);
              
				if (res == CODEC_END_OF_DECODE) {					
					printf("\n  End of Decode \n");
					break;
				}
				else if (res == CODEC_DECODE_ERROR) {
					printf("\n  Codec Decode Failed \n");
					break;
				}
				else if(res != CODEC_SUCCESS){
					printf("codec_decode else err %d\n",res);
						break;
				}
				
				cnt += sampleProduced;
				
				while (decoding) 
				 {
					numberOfSamples = codec_get_pcm_samples(stream_type,
											(long **)&mem_ptr, &sampleProduced, &bufOut);
					if (numberOfSamples == 0)
						break;
					
#if 1
					if (max_audio_buf_size < sampleProduced) { //More bigger buffer needed
						max_audio_buf_size = sampleProduced;
						if (NULL != g_audio_buf_ptr) {
							LOCALPLAY_LOG(" Bigger buffer needed.\n");
							_mem_free(g_audio_buf_ptr);
						}
						g_audio_buf_ptr = (uchar_ptr) _mem_alloc_system_zero(max_audio_buf_size);
						if (NULL == g_audio_buf_ptr) {
							LOCALPLAY_LOG(" Failed to allocate g_audio_buf_ptr. max_audio_buf_size %d \n", max_audio_buf_size);
							decoding = 0;
							break;
						}	
#if 1
						//sai_dma_buffer_adjust(sampleProduced);			
#endif
					}
#endif
					
				    if (MQX_OK != _lwsem_wait(&pcm_flush_sem))
				    {
					  LOCALPLAY_LOG("\n Error: Wait for pcm_flush_sem failed.\n");
					 // _task_set_error(res);
				    }
				    
					_mem_copy((void *)bufOut, g_audio_buf_ptr, sampleProduced);
                                        //g_audio_buf_ptr = bufOut;
					g_buf_bytes_to_flush = sampleProduced;
		
					if (_lwsem_post(&pcm_decoded_sem) != MQX_OK)
					 {
					   LOCALPLAY_LOG("\n  pcm_flush : Error - Unable to set pcm_decoded_sem.");
					 }

					if (numberOfSamples == sampleProduced)
						sampleProduced = 0;
				 }//end while decoding
	 	  }//end while decoding
		}//end if res==kCodeSuccess
		
		#if 0
		fflush(device_ptr);
		#else
		msi_snd_mute();

                if (MQX_OK != _lwsem_wait(&pcm_flush_sem))
                    LOCALPLAY_LOG("\n Error: Wait for latest pcm_flush_sem failed.\n");
		msi_snd_flush();
		#endif
		
#if 1
		//sai_dma_output_stop();
#endif	
#if 0
		/* Print transfer statistics */
		if (ioctl(device_ptr, IO_IOCTL_I2S_GET_STATISTICS, &stats) != I2S_OK) {
			LOCALPLAY_LOG("  Error: Cannot read I2S statistics.\n");
		} else {
			LOCALPLAY_LOG("\n  Playback stats\n");
			LOCALPLAY_LOG("  Total interrupts:              %d\n", stats.INTERRUPTS);
			LOCALPLAY_LOG("  Bytes requested for transmit:  %d\n",
					stats.PACKETS_REQUESTED * format.audio_format.SIZE);
			LOCALPLAY_LOG("  Bytes transmitted:             %d\n",
					stats.TX_PACKETS * format.audio_format.SIZE);
			LOCALPLAY_LOG("  Underruns of hardware FIFO:    %d\n", stats.FIFO_ERROR);
			LOCALPLAY_LOG("  Software buffer empty:         %d\n", stats.BUFFER_ERROR);
		}
#endif
	        LOCALPLAY_LOG("\n  DONE\n");
			
		clean_up:
		printf("done to clean up,decoding %d \n",decoding);		
		/* Clean up for next song */
		if (NULL != mem_ptr) {
			_mem_free(mem_ptr);
			mem_ptr = NULL;
		}
		if (NULL != g_audio_buf_ptr) {
			_mem_free(g_audio_buf_ptr);
			g_audio_buf_ptr = NULL;
		}
		if (NULL != stream_ptr) {
			res = fclose(stream_ptr);
			if ((res != MQX_OK)&&(res != MFS_DISK_IS_WRITE_PROTECTED)) {
				/*LOCALPLAY_LOG*/printf("  Error: Unable to close file 0x%x.\n", res);
			}
			stream_ptr = NULL;
		}
		if (NULL != stream_ptr1) {
			res = fclose(stream_ptr1);
			if ((res != MQX_OK)&&(res != MFS_DISK_IS_WRITE_PROTECTED)) {
				/*LOCALPLAY_LOG*/printf("  Error: Unable to close file 0x%x.\n", res);
			}
			stream_ptr1 = NULL;
		}
		
		if(MQX_OK != _lwsem_destroy(&pcm_flush_sem))
		  {
			LOCALPLAY_LOG("\n Error - Unable to destroy lwsem: pcm_flush_sem\n");
		  }

		if (decoding == TRUE) { // playback finished in normal way, ie, next/prev not pressed
			if (!shell_cmd) { 	// and was not triggered by Shell
				// just like next btn being pressed
				_lwevent_set(&player_event, PLAYER_EVENT_MSK_NEXT_BTN_PRESSED);
			}
		}
		
	    /* if exit this task ,must route this point ! */
	    printf("play unlock umount at %d\n",lpp_param->lp_type);
	    _lwsem_post(lpp_param->mfs_io_sem);
	}//end while(1)
#if 0
	// clean up further
	if (NULL != device_ptr) {	
		if (fclose(device_ptr) != MQX_OK) {
			LOCALPLAY_LOG("  Error: Unable to close \"%s\" device driver.\n",
					full_path);
		}
	}
#else	
	msi_snd_deinit();
#endif
			
	if (NULL != metadata)
		_mem_free(metadata);	

	if (MQX_NULL_TASK_ID != pcm_flush_id)
	  {
            gPcmFlushTaskFinish = 1;
	    _lwsem_post(&pcm_decoded_sem);
            while(gPcmFlushTaskFinish == 1){
                _sched_yield();
            }

            //_task_destroy(pcm_flush_id);
	    pcm_flush_id = MQX_NULL_TASK_ID;
	    ///*LOCALPLAY_LOG*/printf(" pcm flush task destoryed \n");
	  }
	
	if(MQX_OK != _lwsem_destroy(&pcm_decoded_sem))
		  {
			LOCALPLAY_LOG("\n Error - Unable to destroy lwsem: pcm_decoded_sem\n");
		  }
	
  //printf("__guoyifang__: sd_player_task %d set PLAYER_TASK_KILLED.\n",lpp_param->lp_type);
  _lwevent_set(&player_event, PLAYER_EVENT_MSK_PLAYER_TASK_KILLED);
  
  printf("sd_player_task  exit.\n");
  //_task_block(); //wait for being destroyed
  
}
/*FUNCTION****************************************************************
*
* Function Name    : _dspi_dma_transfer
* Returned Value   : number of bytes transferred
* Comments         :
*   Internal routine performing actual DMA transfer of given width
*   If txbuf is NULL the function expects dummy pattern already prepared in dspi_info_ptr->TX_BUFFER
*
*END*********************************************************************/
static _mqx_int _dspi_dma_transfer
    (
        /* [IN] Device specific context structure */
        DSPI_DMA_INFO_STRUCT_PTR       dspi_info_ptr,

        /* [IN] Data to transmit */
        uint8_t                     *txbuf,

        /* [OUT] Received data */
        uint8_t                     *rxbuf,

        /* [IN] Length of transfer in bytes */
        uint32_t                        len,

        /* [IN] Width of data register access for DMA transfer */
        int                            regw
    )
{
    DMA_TCD                            tx_tcd;
    DMA_TCD                            rx_tcd;

    #if PSP_ENDIAN == MQX_LITTLE_ENDIAN
        if (regw > 1) {
            regw = -regw;
        }
    #endif

    if (NULL != rxbuf) {
        dma_tcd_reg2mem(&rx_tcd, &(dspi_info_ptr->DSPI_PTR->POPR), regw, rxbuf, len);
    }
    else {
        dma_tcd_reg2mem(&rx_tcd, &(dspi_info_ptr->DSPI_PTR->POPR), regw, dspi_info_ptr->RX_BUF, len);
        rx_tcd.LOOP_DST_OFFSET = -regw;
    }

    if (NULL != txbuf) {
        dma_tcd_mem2reg(&tx_tcd, &(dspi_info_ptr->DSPI_PTR->PUSHR), regw, txbuf, len);
    }
    else {
        dma_tcd_mem2reg(&tx_tcd, &(dspi_info_ptr->DSPI_PTR->PUSHR), regw, dspi_info_ptr->TX_BUF, len);
        tx_tcd.LOOP_SRC_OFFSET = -regw;
    }

    /* ensure that the semaphore is at zero count */
    while (_lwsem_poll(&dspi_info_ptr->EVENT_IO_FINISHED)) {}

    dma_transfer_submit(dspi_info_ptr->DMA_RX_CHANNEL, &rx_tcd, NULL);
    dma_transfer_submit(dspi_info_ptr->DMA_TX_CHANNEL, &tx_tcd, NULL);

    /* block the task until completion of the background operation */
    _lwsem_wait(&dspi_info_ptr->EVENT_IO_FINISHED);

    if (dma_channel_status(dspi_info_ptr->DMA_RX_CHANNEL, NULL, NULL)
        || dma_channel_status(dspi_info_ptr->DMA_TX_CHANNEL, NULL, NULL)
       )
    {
        return 0;
    }

    return len;
}