Added alsa mixer option to sound_device compile
Added alsa mixer option to sound_device compile

file:a/makefile -> file:b/makefile
--- a/makefile
+++ b/makefile
@@ -11,10 +11,13 @@
 CC=gcc
 CFLAGS=-O3 -Wall
 
-.PHONY: build disable-float
+SOUND_DEVICE_MODE=-D__OSS__
+SOUND_DEVICE_LIB=
+
+.PHONY: build enable-debug disable-float fast-algorithms sound-device-alsa
 build: create-dirs all
 
-all: bin/psk31 bin/filter_test bin/packet bin/sound_device bin/NOAA_ATP bin/mixer bin/forward
+all: bin/psk31 bin/filter_test bin/packet bin/sound_device bin/NOAA_ATP bin/mixer bin/forward bin/UARTRecord
 
 create-dirs:
 	mkdir -p bin
@@ -40,6 +43,18 @@
 	@echo "Faster Less accurate algorithms enabled"
 	$(eval DEFINES+=-DFAST_ALGORITHMS)
 
+# Set sound device to build with ALSA
+sound-device-alsa:
+	@echo "Sound device building with ALSA"
+	$(eval SOUND_DEVICE_MODE=-D__ALSA__)
+	$(eval SOUND_DEVICE_LIB=-lasound)
+
+# Set sound device to build with PULSE
+sound-device-pulse:
+	@echo "Sound device building with PULSE"
+	$(eval SOUND_DEVICE_MODE=-D__PULSE__)
+	$(eval SOUND_DEVICE_LIB=-lpulse -lpulse-simple)
+
 ###############################################################################
 # Mixes 2 raw audio files                                                     #
 ###############################################################################
@@ -106,10 +121,10 @@
 ###############################################################################
 
 bin/sound_device: build/obj/sound_device.o
-	$(CC) $(CFLAGS) -o $@ build/obj/sound_device.o -lpulse -lpulse-simple
+	$(CC) $(CFLAGS) -o $@ build/obj/sound_device.o $(SOUND_DEVICE_LIB)
 
 build/obj/sound_device.o: src/sound_device/sound_device.c
-	$(CC) $(CFLAGS) -o $@ -c src/sound_device/sound_device.c
+	$(CC) $(CFLAGS) $(SOUND_DEVICE_MODE) -o $@ -c src/sound_device/sound_device.c
 
 ###############################################################################
 # NOAA ATP decoder                                                            #

--- a/src/sound_device/sound_device.c
+++ b/src/sound_device/sound_device.c
@@ -3,20 +3,19 @@
  * @defgroup sound_device Audio Device Controllers

  */

 

-#ifdef __CYGWIN32__

-#define __OSS__

-#else

-#define __PULSE__

-#endif

+#include <unistd.h>

+#include <stdio.h>

+

+#include <stdbool.h>

+

+#include <errno.h>

 

 #ifdef __OSS__

 

-#include <unistd.h>

 #include <fcntl.h>

 #include <sys/types.h>

 #include <sys/ioctl.h>

 #include <stdlib.h>

-#include <stdio.h>

 #include <sys/soundcard.h>

 

 #define LENGTH 60    /* how many seconds of speech to store */

@@ -24,14 +23,9 @@
 #define SIZE 8      /* sample size: 8 or 16 bits */

 #define CHANNELS 1  /* 1 = mono 2 = stereo */

 

-#endif

-

-#ifdef __PULSE__

-

-#include <stdio.h>

-#include <unistd.h>

+#elif defined __PULSE__

+

 #include <string.h>

-#include <errno.h>

 

 #include <pulse/simple.h>

 #include <pulse/error.h>

@@ -59,6 +53,10 @@
     return ret;

 }

 

+#elif defined __ALSA__

+

+#include <alsa/asoundlib.h>

+

 #endif

 

 unsigned char buf[1024];

@@ -67,95 +65,198 @@
 

 	#ifdef __OSS__

 

-	int fd;		// sound device file descriptor */

-	int arg;	// argument for ioctl calls */

-	int status;	// return status of system calls */

-

-	/* open sound device */

-	fd = open("/dev/dsp", O_RDWR);

-	if (fd < 0) {

-		perror("open of /dev/dsp failed");

-		exit(1);

-	}

-

-	/* set sampling parameters */

-	arg = SIZE;	   /* sample size */

-	status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);

-	if(status == -1)

-		perror("SOUND_PCM_WRITE_BITS ioctl failed");

-	if(arg != SIZE)

-		perror("unable to set sample size");

-

-	arg = CHANNELS;  /* mono or stereo */

-	status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);

-

-	if (status == -1)

-		perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");

-	if(arg != CHANNELS)

-		perror("unable to set number of channels");

-

-	arg = RATE;	   /* sampling rate */

-	status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);

-	if (status == -1)

-		perror("SOUND_PCM_WRITE_WRITE ioctl failed");

-

-	char wbuf[1];

+		int fd;		// sound device file descriptor */

+		int arg;	// argument for ioctl calls */

+		int status;	// return status of system calls */

+

+		/* open sound device */

+		fd = open("/dev/dsp", O_RDWR);

+		if (fd < 0) {

+			perror("open of /dev/dsp failed");

+			return -1;

+		}

+

+		/* set sampling parameters */

+		arg = SIZE;	   /* sample size */

+		status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);

+		if(status == -1)

+			perror("SOUND_PCM_WRITE_BITS ioctl failed");

+		if(arg != SIZE)

+			perror("unable to set sample size");

+

+		arg = CHANNELS;  /* mono or stereo */

+		status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);

+

+		if (status == -1)

+			perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");

+		if(arg != CHANNELS)

+			perror("unable to set number of channels");

+

+		arg = RATE;	   /* sampling rate */

+		status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);

+		if (status == -1)

+			perror("SOUND_PCM_WRITE_WRITE ioctl failed");

+

+		while (1) { /* loop until Control-C */

+			status = read(fd, buf, 1024); /* record some sound */

+			if (status != 1024)

+				fprintf(stderr, "read wrong number of bytes %d\n", status);

 	

-	while (1) { /* loop until Control-C */

-		status = read(fd, buf, 1024); /* record some sound */

-		if (status != 1024)

-			perror((std::string("read wrong number of bytes")+util::intToStr(status)).c_str());

-

-		for(int i = 0; i < 1024; i++){

-			wbuf[0] = buf[i];

-			std::cout.write(wbuf, 1);

-		}

-		std::cout.flush();

-	}

-	#endif

-	#ifdef __PULSE__

-	    /* The sample type to use */

-    //static const 

-	pa_sample_spec ss;// = {

-        ss.format = PA_SAMPLE_U8;//,

-        ss.rate = 44100;//,

-        ss.channels = 1;

-    //};

-    pa_simple *s = NULL;

-    int ret = 1;

-    int error;

-

-    /* Create the recording stream */

-    if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) {

-        fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));

-        goto finish;

-    }

-

-    for (;;) {

-        uint8_t buf[BUFSIZE];

-

-        /* Record some data ... */

-        if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {

-            fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error));

-            goto finish;

-        }

-

-        /* And write it to STDOUT */

-        if (loop_write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) {

-            fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno));

-            goto finish;

-        }

-    }

-

-    ret = 0;

-

-finish:

-

-    if (s)

-        pa_simple_free(s);

-

-    return ret;

-	

-	#endif

+			int i;

+			for(i = 0; i < 1024; i++)

+				fputc(buf[i], stdout);

+

+			fflush(stdout);

+		}

+

+	#elif defined __PULSE__

+

+		pa_sample_spec ss;

+		ss.format = PA_SAMPLE_U8;

+		ss.rate = 44100;

+		ss.channels = 1;

+

+		pa_simple *s = NULL;

+		int ret = 1;

+		int error;

+

+		/* Create the recording stream */

+		if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) {

+			fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));

+			if(s)

+				pa_simple_free(s);

+			return -1;

+		}

+

+		while(true) {

+			uint8_t buf[BUFSIZE];

+

+			/* Record some data ... */

+			if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {

+				fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error));

+				if(s)

+					pa_simple_free(s);

+				return -1;

+			}

+

+			/* And write it to STDOUT */

+			if (loop_write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) {

+				fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno));

+				if(s)

+					pa_simple_free(s);

+				return -1;

+			}

+		}

+

+		if (s)

+			pa_simple_free(s);

+

+	#elif defined __ALSA__

+

+		int err;

+		char *buffer;

+		int buffer_frames = 128;

+		unsigned int rate = 11025;

+		snd_pcm_t *capture_handle;

+		snd_pcm_hw_params_t *hw_params;

+		snd_pcm_format_t format = SND_PCM_FORMAT_S8;

+

+		if((err = snd_pcm_open (&capture_handle, argv[1], SND_PCM_STREAM_CAPTURE, 0)) < 0) {

+			fprintf(stderr, "cannot open audio device %s (%s)\n", argv[1], snd_strerror(err));

+		    return -1;

+		}

+

+		fprintf(stderr, "audio interface opened\n");

+

+		if((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {

+			fprintf(stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror(err));

+			return -1;

+		}

+

+		fprintf(stderr, "hw_params allocated\n");

+

+		if((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0) {

+			fprintf(stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror(err));

+		    return -1;

+		}

+

+		fprintf(stderr, "hw_params initialized\n");

+

+		if((err = snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {

+			fprintf(stderr, "cannot set access type (%s)\n", snd_strerror(err));

+			return -1;

+		}

+

+		fprintf(stderr, "hw_params access set\n");

+

+		if((err = snd_pcm_hw_params_set_format (capture_handle, hw_params, format)) < 0) {

+			fprintf(stderr, "cannot set sample format (%s)\n", snd_strerror(err));

+			return -1;

+		}

+

+		fprintf(stderr, "hw_params format set\n");

+

+		if((err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &rate, 0)) < 0) {

+			fprintf(stderr, "cannot set sample rate (%s)\n", snd_strerror(err));

+			return -1;

+		}

+

+		fprintf(stderr, "hw_params rate set\n");

+

+		if((err = snd_pcm_hw_params_set_channels(capture_handle, hw_params, 2)) < 0) {

+			fprintf(stderr, "cannot set channel count (%s)\n", snd_strerror(err));

+			return -1;

+		}

+

+		fprintf(stderr, "hw_params channels set\n");

+

+		if((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0) {

+			fprintf(stderr, "cannot set parameters (%s)\n", snd_strerror(err));

+			return -1;

+		}

+

+		fprintf(stderr, "hw_params set\n");

+

+		snd_pcm_hw_params_free (hw_params);

+

+		fprintf(stderr, "hw_params freed\n");

+

+		if((err = snd_pcm_prepare(capture_handle)) < 0) {

+			fprintf(stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror(err));

+			exit (1);

+		}

+

+		fprintf(stderr, "audio interface prepared\n");

+

+		buffer = malloc(128 * snd_pcm_format_width(format) / 8 * 2);

+

+		fprintf(stdout, "buffer allocated\n");

+

+		while(true){

+			if((err = snd_pcm_readi (capture_handle, buffer, buffer_frames)) != buffer_frames){

+				fprintf (stderr, "read from audio interface failed (%s)\n", snd_strerror(err));

+				return -1;

+			}

+			int i;

+			for(i = 0; i < 128 * snd_pcm_format_width(format) / 8; i++)

+				fputc(buffer[i*2], stdout);

+			fflush(stdout);

+		}

+

+		free(buffer);

+

+		fprintf(stderr, "buffer freed\n");

+

+		snd_pcm_close(capture_handle);

+		fprintf(stderr, "audio interface closed\n");

+

+	#else

+

+		#error "No Sound Library selected!"

+

+    #endif

+

+	return 0;

+

 }