text: /*
   * @file
   * @brief a record demo in linux
   *
   * a simple record code. using alsa-lib APIs.
   * keep the function same as winrec.h
   *
   * Common steps:
   *	create_recorder,
   *	open_recorder, 
   *	start_record, 
   *	stop_record, 
   *	close_recorder,
   *	destroy_recorder
   *
   * @author		taozhang9
   * @date		2016/06/01
   */
  
  #ifndef __IFLY_WINREC_H__
  #define __IFLY_WINREC_H__
  
  #include "formats.h"
  /* error code */
  enum {
  	RECORD_ERR_BASE = 0,
  	RECORD_ERR_GENERAL,
  	RECORD_ERR_MEMFAIL,
  	RECORD_ERR_INVAL,
  	RECORD_ERR_NOT_READY
  };
  
  typedef struct {
  	union {
  		char *	name;
  		int	index;
  		void *	resv;
  	}u;
  }record_dev_id;
  
  /* recorder object. */
  struct recorder {
  	void (*on_data_ind)(char *data, unsigned long len, void *user_para);
  	void * user_cb_para;
  	volatile int state;		/* internal record state */
  
  	void * wavein_hdl;
  	/* thread id may be a struct. by implementation 
  	 * void * will not be ported!! */
  	pthread_t rec_thread; 
  	/*void * rec_thread_hdl;*/
  
  	void * bufheader;
  	unsigned int bufcount; 
  	
  	char *audiobuf;
  	int bits_per_frame;
  	unsigned int buffer_time;
  	unsigned int period_time;
  	size_t period_frames;
  	size_t buffer_frames;
  };
  
  #ifdef __cplusplus
  extern "C" {
  #endif /* C++ */
  
  /** 
   * @fn
   * @brief	Get the default input device ID
   *
   * @return	returns "default" in linux.
   *
   */
  record_dev_id get_default_input_dev();
  
  /**
   * @fn 
   * @brief	Get the total number of active input devices.
   * @return	
   */
  int get_input_dev_num();
  
  /**
   * @fn 
   * @brief	Create a recorder object.
   *
   * Never call the close_recorder in the callback function. as close
   * action will wait for the callback thread to quit. 
   *
   * @return	int			- Return 0 in success, otherwise return error code.
   * @param	out_rec		- [out] recorder object holder
   * @param	on_data_ind	- [in]	callback. called when data coming.
   * @param	user_cb_para	- [in] user params for the callback.
   * @see
   */
  int create_recorder(struct recorder ** out_rec, 
  				void (*on_data_ind)(char *data, unsigned long len, void *user_para), 
  				void* user_cb_para);
  
  /**
   * @fn 
   * @brief	Destroy recorder object. free memory. 
   * @param	rec	- [in]recorder object
   */
  void destroy_recorder(struct recorder *rec);
  
  /**
   * @fn 
   * @brief	open the device.
   * @return	int			- Return 0 in success, otherwise return error code.
   * @param	rec			- [in] recorder object
   * @param	dev			- [in] device id, from 0.
   * @param	fmt			- [in] record format.
   * @see
   * 	get_default_input_dev()
   */
  int open_recorder(struct recorder * rec, record_dev_id dev, WAVEFORMATEX * fmt);
  
  /**
   * @fn
   * @brief	close the device.
   * @param	rec			- [in] recorder object
   */
  
  void close_recorder(struct recorder *rec);
  
  /**
   * @fn
   * @brief	start record.
   * @return	int			- Return 0 in success, otherwise return error code.
   * @param	rec			- [in] recorder object
   */
  int start_record(struct recorder * rec);
  
  /**
   * @fn
   * @brief	stop record.
   * @return	int			- Return 0 in success, otherwise return error code.
   * @param	rec			- [in] recorder object
   */
  int stop_record(struct recorder * rec);
  
  /**
   * @fn
   * @brief	test if the recording has been stopped.
   * @return	int			- 1: stopped. 0 : recording.
   * @param	rec			- [in] recorder object
   */
  int is_record_stopped(struct recorder *rec);
  
  #ifdef __cplusplus
  } /* extern "C" */	
  #endif /* C++ */
  
  #endif
  