rendered paste body--- speexclient/speexclient.c 2010-09-03 12:44:29.890652316 -0400+++ speexclient-vogue/speexclient.c 2010-09-03 18:12:11.470922456 -0400@@ -46,7 +46,19 @@ #include <unistd.h> /* close() */ #include <string.h> /* memset() */ -#include "alsa_device.h"+/* #include "alsa_device.h" */++/* begin playwav2.c paste */++#include <fcntl.h>+#include <stdint.h>+#include <sys/mman.h>+#include <sys/ioctl.h>++#include <linux/ioctl.h>++/* end playwav2.c paste */+ #include <speex/speex.h> #include <speex/speex_jitter.h> #include <speex/speex_preprocess.h>@@ -55,9 +67,213 @@ #include <sched.h> +/* begin playwav2.c paste */++#if 0+#include <linux/msm_audio.h>+#else+/* ---------- linux/msm_audio.h -------- */++#define AUDIO_IOCTL_MAGIC 'a'++#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)+#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)+#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)+#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)+#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)+#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)+#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)+#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)+#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)+#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)++#define EQ_MAX_BAND_NUM 12++#define ADRC_ENABLE 0x0001+#define ADRC_DISABLE 0x0000+#define EQ_ENABLE 0x0002+#define EQ_DISABLE 0x0000+#define IIR_ENABLE 0x0004+#define IIR_DISABLE 0x0000++struct eq_filter_type+{+ int16_t gain;+ uint16_t freq;+ uint16_t type;+ uint16_t qf;+};++struct eqalizer+{+ uint16_t bands;+ uint16_t params[132];+};++struct rx_iir_filter+{+ uint16_t num_bands;+ uint16_t iir_params[48];+};+++struct msm_audio_config+{+ uint32_t buffer_size;+ uint32_t buffer_count;+ uint32_t channel_count;+ uint32_t sample_rate;+ uint32_t codec_type;+ uint32_t unused[3];+};++struct msm_audio_stats+{+ uint32_t out_bytes;+ uint32_t unused[3];+};++/* Audio routing */++#define SND_IOCTL_MAGIC 's'++#define SND_MUTE_UNMUTED 0+#define SND_MUTE_MUTED 1++struct msm_snd_device_config+{+ uint32_t device;+ uint32_t ear_mute;+ uint32_t mic_mute;+};++#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)++#define SND_METHOD_VOICE 0++#define SND_METHOD_VOICE_1 1++struct msm_snd_volume_config+{+ uint32_t device;+ uint32_t method;+ uint32_t volume;+};++#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)++/* Returns the number of SND endpoints supported. */++#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)++struct msm_snd_endpoint+{+ int id; /* input and output */+ char name[64]; /* output only */+};++/* Takes an index between 0 and one less than the number returned by+ * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a+ * SND endpoint. On input, the .id field contains the number of the+ * endpoint, and on exit it contains the SND index, while .name contains+ * the description of the endpoint.+ */++#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *)++#endif+/* ---------- -------- */++static int+do_route_audio_rpc (uint32_t device, int ear_mute, int mic_mute)+{+ if (device == -1UL)+ return 0;++ int fd;++ printf ("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute);++ fd = open ("/dev/msm_snd", O_RDWR);+ if (fd < 0)+ {+ perror ("Can not open snd device");+ return -1;+ }+ // RPC call to switch audio path+ /* rpc_snd_set_device(+ * device, # Hardware device enum to use+ * ear_mute, # Set mute for outgoing voice audio+ * # this should only be unmuted when in-call+ * mic_mute, # Set mute for incoming voice audio+ * # this should only be unmuted when in-call or+ * # recording.+ * )+ */+ struct msm_snd_device_config args;+ args.device = device;+ args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED;+ args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED;++ if (ioctl (fd, SND_SET_DEVICE, &args) < 0)+ {+ perror ("snd_set_device error.");+ close (fd);+ return -1;+ }++ close (fd);+ return 0;+}++static int+set_volume_rpc (uint32_t device, uint32_t method, uint32_t volume)+{+ int fd;++ printf ("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume);++ if (device == -1UL)+ return 0;++ fd = open ("/dev/msm_snd", O_RDWR);+ if (fd < 0)+ {+ perror ("Can not open snd device");+ return -1;+ }+ /* rpc_snd_set_volume(+ * device, # Any hardware device enum, including+ * # SND_DEVICE_CURRENT+ * method, # must be SND_METHOD_VOICE to do anything useful+ * volume, # integer volume level, in range [0,5].+ * # note that 0 is audible (not quite muted)+ * )+ * rpc_snd_set_volume only works for in-call sound volume.+ */+ struct msm_snd_volume_config args;+ args.device = device;+ args.method = method;+ args.volume = volume;++ if (ioctl (fd, SND_SET_VOLUME, &args) < 0)+ {+ perror ("snd_set_volume error.");+ close (fd);+ return -1;+ }+ close (fd);+ return 0;+}++static char *next;+static unsigned avail;++/* end playwav2.c paste */+ #define MAX_MSG 1500 -#define SAMPLING_RATE 16000+#define SAMPLING_RATE 8000 #define FRAME_SIZE 320 int main(int argc, char *argv[])@@ -72,7 +288,7 @@ int nfds; struct pollfd *pfds; SpeexPreprocessState *preprocess;- AlsaDevice *audio_dev;+ /*AlsaDevice *audio_dev;*/ int tmp; if (argc != 5)@@ -118,16 +334,69 @@ } /* Setup audio device */- audio_dev = alsa_device_open(argv[1], SAMPLING_RATE, 1, FRAME_SIZE);- + /* audio_dev = alsa_device_open(argv[1], SAMPLING_RATE, 1, FRAME_SIZE); */++/* begin playwav2.c paste */++ int fd = open ("/dev/msm_snd", O_RDWR);+ int mNumSndEndpoints;++ if (fd >= 0)+ {+ int rc = ioctl (fd, SND_GET_NUM_ENDPOINTS,+ &mNumSndEndpoints);++ printf ("found %d snd endpoints\n", mNumSndEndpoints);++ if (rc >= 0)+ {+ struct msm_snd_endpoint ept;+ int cnt;++ for (cnt = 0; cnt < mNumSndEndpoints; cnt++)+ {+ ept.id = cnt;+ ioctl (fd, SND_GET_ENDPOINT, &ept);+ printf (" %02d: %s / %d\n", cnt, ept.name, ept.id);+ }+ }+ else+ perror ("Could not retrieve number of MSM SND endpoints.");+ close (fd);+ }+ else+ perror ("Could not open MSM SND driver.");++ printf ("Select device %d.\n", 0);++// do_route_audio_rpc (0, SND_MUTE_MUTED, SND_MUTE_MUTED);+ do_route_audio_rpc(0,SND_MUTE_UNMUTED,SND_MUTE_UNMUTED);+++// printf ("enable PP\n");+// msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | IIR_ENABLE);++ printf ("Set master volume to %d.\n", 5);+#if 0+ set_volume_rpc (SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol);+ set_volume_rpc (SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol);+ set_volume_rpc (SND_DEVICE_BT, SND_METHOD_VOICE, vol);+ set_volume_rpc (SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol);+#endif++ /* dev=0xd ? */+ set_volume_rpc (0xd, SND_METHOD_VOICE_1, 5);++/* end playwav2.c paste */+ /* Setup the encoder and decoder in wideband */ void *enc_state, *dec_state;- enc_state = speex_encoder_init(&speex_wb_mode);+ enc_state = speex_encoder_init(&speex_nb_mode); tmp = 8; speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &tmp); tmp = 2; speex_encoder_ctl(enc_state, SPEEX_SET_COMPLEXITY, &tmp);- dec_state = speex_decoder_init(&speex_wb_mode);+ dec_state = speex_decoder_init(&speex_nb_mode); tmp = 1; speex_decoder_ctl(dec_state, SPEEX_SET_ENH, &tmp); SpeexBits enc_bits, dec_bits;@@ -145,9 +414,14 @@ int recv_started=0; /* Setup all file descriptors for poll()ing */- nfds = alsa_device_nfds(audio_dev);+ /* nfds = alsa_device_nfds(audio_dev); */+ nfds = 2; pfds = malloc(sizeof(*pfds)*(nfds+1));- alsa_device_getfds(audio_dev, pfds, nfds);+ /* alsa_device_getfds(audio_dev, pfds, nfds); */+ pfds[0].fd = open("/dev/msm_pcm_in", O_RDWR);+ pfds[0].events = POLLIN;+ pfds[1].fd = open("/dev/msm_pcm_out", O_RDWR);+ pfds[1].events = POLLOUT; pfds[nfds].fd = sd; pfds[nfds].events = POLLIN; @@ -164,8 +438,104 @@ preprocess = speex_preprocess_state_init(FRAME_SIZE, SAMPLING_RATE); speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, echo_state); - alsa_device_start(audio_dev);- + /* alsa_device_start(audio_dev); */++/* begin playwav2.c paste */++// unsigned char buf[8192];+ unsigned char buf[320]+ struct msm_audio_config cfg;+ unsigned sz;+ unsigned total = 0;++ if (pfds[0].fd < 0)+ {+ perror ("cannot open msm_pcm_in");+ return -1;+ }++ /* config change should be a read-modify-write operation */+ if (ioctl (pfds[0].fd, AUDIO_GET_CONFIG, &cfg))+ {+ perror ("cannot read write audio config");+ return -1;+ }++ cfg.channel_count = 1;+ cfg.sample_rate = 8000;+ cfg.buffer_size = 320;+ if (ioctl (pfds[0].fd, AUDIO_SET_CONFIG, &cfg))+ {+ perror ("cannot write write audio config");+ return -1;+ }++ if (ioctl (pfds[0].fd, AUDIO_GET_CONFIG, &cfg))+ {+ perror ("cannot read write audio config");+ return -1;+ }++ sz = cfg.buffer_size;+ fprintf (stderr, "write buffer size %d x %d\n", sz, cfg.buffer_count);+ if (sz > sizeof (buf))+ {+ fprintf (stderr, "write buffer size %d too large\n", sz);+ return -1;+ }++ if (ioctl (pfds[0].fd, AUDIO_START, 0))+ {+ perror ("cannot start write audio");+ return -1;+ }++ struct msm_audio_config config;+ struct msm_audio_stats stats;+ unsigned sz2;+ char buf2[320];++ if (pfds[1].fd < 0)+ {+ perror ("pcm_play: cannot open audio device");+ return -1;+ }++ if (ioctl (pfds[1].fd, AUDIO_GET_CONFIG, &config))+ {+ perror ("could not get read config");+ return -1;+ }++ config.channel_count = 1;+ config.sample_rate = 8000;+ config.buffer_size = 320;+ if (ioctl (pfds[1].fd, AUDIO_SET_CONFIG, &config))+ {+ perror ("could not set read config");+ return -1;+ }+ sz2 = config.buffer_size;+ if (sz2 > sizeof (buf2))+ {+ fprintf (stderr, "read buffer too big\n");+ return -1;+ }++/* fprintf (stderr, "prefill\n");+ for (n = 0; n < config.buffer_count; n++)+ {+ if (fill (buf, sz, cookie))+ break;+ if (write (afd, buf, sz) != sz)+ break;+ } */++ ioctl (pfds[1].fd, AUDIO_START, 0);+++/* end playwav2.c paste */+ /* Infinite loop on capture, playback and receiving packets */ while (1) {@@ -188,8 +558,8 @@ } /* Ready to play a frame (playback) */- if (alsa_device_playback_ready(audio_dev, pfds, nfds))- {+// if (alsa_device_playback_ready(audio_dev, pfds, nfds))+// { short pcm[FRAME_SIZE]; if (recv_started) {@@ -200,18 +570,24 @@ pcm[i] = 0; } /* Playback the audio and reset the echo canceller if we got an underrun */- if (alsa_device_write(audio_dev, pcm, FRAME_SIZE))+// if (alsa_device_write(audio_dev, pcm, FRAME_SIZE))+#if 0+ if (ioctl (pfds[1].fd, AUDIO_GET_STATS, &stats) == 0)+ fprintf (stderr, "%10d\n", stats.out_bytes);+#endif+ if (write (pfds[1].fd, pcm, FRAME_SIZE)) speex_echo_state_reset(echo_state); /* Put frame into playback buffer */ speex_echo_playback(echo_state, pcm);- }+// } /* Audio available from the soundcard (capture) */- if (alsa_device_capture_ready(audio_dev, pfds, nfds))- {+// if (alsa_device_capture_ready(audio_dev, pfds, nfds))+// { short pcm[FRAME_SIZE], pcm2[FRAME_SIZE]; char outpacket[MAX_MSG]; /* Get audio from the soundcard */- alsa_device_read(audio_dev, pcm, FRAME_SIZE);+// alsa_device_read(audio_dev, pcm, FRAME_SIZE);+ read (pfds[0].fd, pcm, FRAME_SIZE); /* Perform echo cancellation */ speex_echo_capture(echo_state, pcm, pcm2);@@ -240,7 +616,7 @@ close(sd); exit(1); }- }+// } }