#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <soundcard.h>
#include <stdio.h>
#include <stdlib.h>
/* Example of how to read input from C on the gp2x wiz */
/* by fells on gp32x.de */
static int mixer_fd = -1;
int fd_in;
FILE* file_out;
float seconds = 0;
#define SAMPLE_RATE 22050
#define BUF_SAMPLES 16384
static int mixer_open(const char *device) {
mixer_fd = open(device, O_RDWR);
if (mixer_fd == -1) return -1;
return 0;
}
static int mixer_set_recsrc(int channel) {
if(ioctl(mixer_fd, SOUND_MIXER_WRITE_RECSRC, &channel) == -1) return -1;
return 0;
}
static int mixer_set_level(int channel, int l, int r) {
int tmp;
tmp = (l & 0x7f) + ((r & 0x7f) << 8);
if (ioctl(mixer_fd, MIXER_WRITE(channel), &tmp) == -1) return -1;
return 0;
}
static int open_audio_device (char *name, int mode) {
int fd;
if ((fd = open (name, mode, 0)) == -1) {
perror (name);
exit (-1);
}
int format = AFMT_S16_NE; /* Native 16 bits */
if (ioctl (fd, SNDCTL_DSP_SETFMT, &format) == -1) {
perror ("SNDCTL_DSP_SETFMT");
exit (-1);
}
int channels = 2; // have to use 2 channels on pollux
if (ioctl (fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
perror ("SNDCTL_DSP_CHANNELS");
exit (-1);
}
int sample_rate = SAMPLE_RATE;
if (ioctl (fd, SNDCTL_DSP_SPEED, &sample_rate) == -1) {
perror ("SNDCTL_DSP_SPEED");
exit (-1);
}
return fd;
}
void process_input (void) {
short buffer[BUF_SAMPLES];
int bytes_read, samples_read, frames_read, i, level_min, level_max;
if ((bytes_read = read (fd_in, buffer, sizeof (buffer))) == -1) {
perror ("Audio read");
exit (-1); /* Or return an error code */
}
samples_read = bytes_read / 2; // 2 bytes per sample
frames_read = samples_read / 2; // because we are reading stereo data
level_max = 0;
level_min = 16384;
for (i = 0; i < samples_read; i=i+1) {
int v = buffer[i];
if (v > level_max) level_max = v;
if(v < level_min) level_min = v;
}
fwrite(buffer, sizeof(short), samples_read, file_out);
fflush (stdout);
seconds = seconds + ((float)frames_read/22050.0);
printf("(%d,%d) %2.2f\n", level_min, level_max,seconds);
}
int main(int argc, char**argv) {
int i;
// Open the mixer and the audio device
i = mixer_open("/dev/mixer");
fd_in = open_audio_device ("/dev/dsp", O_RDONLY);
// Set the recording source to mic
i = mixer_set_recsrc(SOUND_MIXER_MIC);
i = mixer_set_level(SOUND_MIXER_VOLUME, 100, 100);
// Debug note: there seems to be a bug in the pollux driver that the mic setting can't be "gotten"
// with the SOUND_MIXER_MIC -- for some reason, you need to get the mixer gain with SOUND_MIXER_LINE
// But you should still set the gain with SOUND_MIXER_MIC. See pollux-cs42L51.c
i = mixer_set_level(SOUND_MIXER_MIC, 85, 85); // the built in voice recorder sets mixer vol to 85 too
sleep(1);
char filename[255];
if(argc != 2) {
strcpy(filename, "/mnt/sd/out-sound.raw");
} else {
strcpy(filename, argv[1]);
}
file_out = fopen(filename,"w");
// Start recording
while (seconds < 10)
process_input ();
fclose(file_out);
exit (0);
}