From 64611107cd5a5d6655fcdda18eb325f353e1e8ae Mon Sep 17 00:00:00 2001
From: Eli Billauer <eli.billauer@gmail.com>
Date: Tue, 24 Mar 2015 21:47:06 +0200
Subject: [PATCH] Add stdin input plugin

---
 libvisual-plugins/plugins/input/CMakeLists.txt     |    2 +
 .../plugins/input/stdin/CMakeLists.txt             |    3 +
 .../plugins/input/stdin/input_stdin.c              |  143 ++++++++++++++++++++
 3 files changed, 148 insertions(+), 0 deletions(-)
 create mode 100644 libvisual-plugins/plugins/input/stdin/CMakeLists.txt
 create mode 100644 libvisual-plugins/plugins/input/stdin/input_stdin.c

diff --git a/libvisual-plugins/plugins/input/CMakeLists.txt b/libvisual-plugins/plugins/input/CMakeLists.txt
index dec51f6..93b21a3 100644
--- a/libvisual-plugins/plugins/input/CMakeLists.txt
+++ b/libvisual-plugins/plugins/input/CMakeLists.txt
@@ -21,3 +21,5 @@ ENDIF()
 IF(ENABLE_WAVEIN)
   ADD_SUBDIRECTORY(wavein)
 ENDIF()
+
+ADD_SUBDIRECTORY(stdin)
diff --git a/libvisual-plugins/plugins/input/stdin/CMakeLists.txt b/libvisual-plugins/plugins/input/stdin/CMakeLists.txt
new file mode 100644
index 0000000..aa64647
--- /dev/null
+++ b/libvisual-plugins/plugins/input/stdin/CMakeLists.txt
@@ -0,0 +1,3 @@
+LV_BUILD_INPUT_PLUGIN(stdin
+  SOURCES      input_stdin.c
+)
diff --git a/libvisual-plugins/plugins/input/stdin/input_stdin.c b/libvisual-plugins/plugins/input/stdin/input_stdin.c
new file mode 100644
index 0000000..8358208
--- /dev/null
+++ b/libvisual-plugins/plugins/input/stdin/input_stdin.c
@@ -0,0 +1,143 @@
+/* Libvisual-plugins - Standard plugins for libvisual
+ *
+ * Copyright (C) 2015 Eli Billauer
+ *
+ * Authors: Eli Billauer <eli.billauer@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <libvisual/libvisual.h>
+
+VISUAL_PLUGIN_API_VERSION_VALIDATOR
+
+#define OUTPUT_RATE       44100
+#define OUTPUT_SAMPLES    4096
+#define FRAME_RATE        30
+#define BYTES_PER_FRAME   (OUTPUT_RATE * 4 / FRAME_RATE)
+
+typedef struct {
+  int loaded;                /**< plugin state */
+  void *databuf;
+} stdin_priv_t;
+
+static int  inp_stdin_init    (VisPluginData *plugin);
+static void inp_stdin_cleanup (VisPluginData *plugin);
+static int  inp_stdin_upload  (VisPluginData *plugin, VisAudio *audio);
+
+const VisPluginInfo *get_plugin_info( void )
+{
+	static VisInputPlugin input = {
+		.upload = inp_stdin_upload
+	};
+
+	static VisPluginInfo info = {
+		.type     = VISUAL_PLUGIN_TYPE_INPUT,
+
+		.plugname = "stdin",
+		.name     = "stdin",
+		.author   = "Eli Billauer <eli.billauer@gmail.com>",
+		.version  = "1.00",
+		.about    = "Use raw audio from standard input",
+		.help     = "This plugin assumes 16-bit signed stereo at 44100 Hz and a frame rate of 30Hz",
+		.license  = VISUAL_PLUGIN_LICENSE_LGPL,
+
+		.init     = inp_stdin_init,
+		.cleanup  = inp_stdin_cleanup,
+		.plugin   = &input
+	};
+
+	return &info;
+}
+
+static void allread(int fd, unsigned char *buf, int len) {
+  int received = 0;
+  int rc;
+
+  while (received < len) {
+    rc = read(fd, buf + received, len - received);
+        
+    if ((rc < 0) && (errno == EINTR))
+      continue;
+
+    if (rc < 0) {
+      perror("Error: Failed to read from standard input");
+      exit(1);
+    }
+        
+    if (rc == 0) {
+      // Quitting like this is a bit aggressive, but who cares?
+      fprintf(stderr, "Reached EOF -- quitting\n");
+      exit(0);
+    }
+ 
+    received += rc;
+  }
+} 
+
+static int inp_stdin_init( VisPluginData *plugin )
+{
+	stdin_priv_t *priv = NULL;
+
+	priv = visual_mem_new0(stdin_priv_t, 1);
+	visual_plugin_set_private (plugin, priv);
+
+	priv->databuf = visual_mem_malloc0(BYTES_PER_FRAME);
+
+	if (BYTES_PER_FRAME < OUTPUT_SAMPLES) {
+	  visual_log( VISUAL_LOG_CRITICAL,
+		      "Compilation parameters set poorly, BYTES_PER_FRAME < OUTPUT_SAMPLES");
+
+	  return FALSE;
+	}
+
+	priv->loaded = TRUE;
+
+	return TRUE;
+}
+
+static void inp_stdin_cleanup( VisPluginData *plugin )
+{
+	stdin_priv_t *priv = visual_plugin_get_private (plugin);
+
+	if ( priv->loaded )
+	  visual_mem_free( priv->databuf );
+
+	visual_mem_free( priv );
+}
+
+static int inp_stdin_upload( VisPluginData *plugin, VisAudio *audio )
+{
+	stdin_priv_t *priv = visual_plugin_get_private (plugin);
+
+	allread(0, priv->databuf, BYTES_PER_FRAME);
+
+	VisBuffer *buffer = visual_buffer_new_wrap_data ( priv->databuf, OUTPUT_SAMPLES, FALSE );
+	visual_audio_input (audio, buffer,
+	                    VISUAL_AUDIO_SAMPLE_RATE_44100,
+	                    VISUAL_AUDIO_SAMPLE_FORMAT_S16,
+	                    VISUAL_AUDIO_SAMPLE_CHANNEL_STEREO);
+	visual_buffer_unref (buffer);
+
+	return TRUE;
+}
-- 
1.7.2.3

