Commits

kunstmusik committed edea1e0

updated with voice type, SpinnerValueCacheable, first working version

  • Participants
  • Parent commits 2a7bed0

Comments (0)

Files changed (8)

AndroidManifest.xml

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.kunstmusik.touchvoice"
     android:versionCode="1"
-    android:versionName="1.0" >
+    android:versionName="1.0" android:installLocation="auto">
 
     <uses-sdk
         android:minSdkVersion="8"

res/layout/activity_main.xml

-<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/LinearLayout1"
+    android:id="@+id/RelativeLayout1"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="horizontal" >
 
-    <TableRow
-        android:id="@+id/tableRow1"
+    <com.kunstmusik.touchvoice.VerticalSeekBar
+        android:id="@+id/seekBar1"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_alignParentLeft="true"
+        android:layout_below="@+id/spinner1" />
+
+    <com.kunstmusik.touchvoice.MultiTouchView
+        android:id="@+id/view2"
         android:layout_width="fill_parent"
-        android:layout_height="fill_parent" >
+        android:layout_height="fill_parent"
+        android:layout_alignBaseline="@+id/seekBar1"
+        android:layout_alignParentTop="true"
+        android:layout_toRightOf="@+id/seekBar1" />
 
-        <com.kunstmusik.touchvoice.MultiTouchView
-            android:id="@+id/view1"
-            android:layout_weight="50"
-            android:background="@color/bgcolor" />
+    <Spinner
+        android:id="@+id/spinner1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:contentDescription="Voice" />
 
-        <com.kunstmusik.touchvoice.MultiTouchView
-            android:id="@+id/view2"
-            android:layout_weight="50" />
-    </TableRow>
-	
-</TableLayout>
+</RelativeLayout>

res/raw/multitouch_xy.csd

 ky chnget S_yName
 
 kenv linsegr 0, .001, 1, .1, 1, .25, 0
-a1 vco2 ky * .5 * kenv, 60 + (log(1 - kx) * 3000), 0
+;a1 vco2 ky * .5 * kenv, 60 + (log(1 - kx) * 3000), 0
+a1 vco2 ky * .5 * kenv, 60 + (log(1 - kx) * 1500), 0
 
 ga1 = ga1 + a1
 
 
 ibp_max_width = 200
 
-kbp_freq0 chnget "touch.0.bp_freq"
-kbp_freq1 chnget "touch.1.bp_freq"
-kbp_freq2 chnget "touch.2.bp_freq"
-kbp_freq3 chnget "touch.3.bp_freq"
-kbp_freq4 chnget "touch.4.bp_freq"
-
-kbp_width0 chnget "touch.0.bp_width"
-kbp_width1 chnget "touch.1.bp_width"
-kbp_width2 chnget "touch.2.bp_width"
-kbp_width3 chnget "touch.3.bp_width"
-kbp_width4 chnget "touch.4.bp_width"
-
-#define BP(num) #
-if(kbp_width$num > 0) then
-	a$num butterbp ga1, 60 + (log(1 - kbp_freq$num) * 3000), kbp_width$num * ibp_max_width
-else
-	a$num = 0
-endif
-#
+kmorf chnget "morph"
+kvoice_type chnget "voiceType"
+
+reset:
 
-$BP(0)
-$BP(1)
-$BP(2)
-$BP(3)
-$BP(4)
+itype = i(kvoice_type)
+
+if (kvoice_type != itype) then
+	reinit reset
+endif
 
-;a2 butterbp ga1, 60 + (log(1 - kbp_freq1) * 3000), kbp_width1 * ibp_max_width
-;a3 butterbp ga1, 60 + (log(1 - kbp_freq2) * 3000), kbp_width2 * ibp_max_width
-;a4 butterbp ga1, 60 + (log(1 - kbp_freq3) * 3000), kbp_width3 * ibp_max_width
-;a5 butterbp ga1, 60 + (log(1 - kbp_freq4) * 3000), kbp_width4 * ibp_max_width
+kmorfsmooth port kmorf, .025
 
-asum sum a0, a1, a2, a3, a4
+aout vowel2 ga1, kmorfsmooth, itype 
 
-asum balance asum, ga1
+rireturn
 
 ;a1 moogladder ga1, kcutoff, kresonance
 
-aL, aR reverbsc asum, asum, .72, 5000
+aL, aR reverbsc aout, aout, .72, 5000
 
 outs aL, aR
 

res/values/strings.xml

     <string name="hello_world">Hello world!</string>
     <string name="menu_settings">Settings</string>
     <string name="title_activity_main">VoiceTouch</string>
+    <string-array name="voice_types">
+        <item>Bass</item>
+        <item>Countertenor</item>
+        <item>Tenor</item>
+        <item>Alto</item>
+        <item>Soprano</item>
+    </string-array>
 
 </resources>

src/com/kunstmusik/touchvoice/MainActivity.java

 
 import android.os.Bundle;
 import android.view.Menu;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.SeekBar;
+import android.widget.Spinner;
 
 import com.csounds.CsoundObj;
 
+import csnd.CsoundMYFLTArray;
+
 public class MainActivity extends BaseCsoundActivity {
 
-	MultiTouchView view1, view2;
+	SeekBar seekBar;
+	MultiTouchView view2;
+	Spinner voiceType;
 
 	/** Called when the activity is first created. */
 	@Override
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.activity_main);
 
-		view1 = (MultiTouchView) findViewById(R.id.view1);
+		seekBar = (SeekBar) findViewById(R.id.seekBar1);
 		view2 = (MultiTouchView) findViewById(R.id.view2);
+		voiceType = (Spinner) findViewById(R.id.spinner1);
+		
+		ArrayAdapter<CharSequence> adapter = ArrayAdapter
+                .createFromResource(this, R.array.voice_types,
+                                android.R.layout.simple_spinner_item);
+		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+		voiceType.setAdapter(adapter);
+		
+		csoundObj.addValueCacheable(new SpinnerValueCacheable(voiceType, "voiceType"));
+		
 		
-		view1.initTouch(csoundObj, 
-				null, 
-				null,
-				"touch.%d.bp_freq", 
-				"touch.%d.bp_width");
+		csoundObj.addSlider(seekBar, "morph", 0.0, 12.0);
 		
 		view2.initTouch(csoundObj, 
 				"i1.%d 0 -2 %d", 
 		String csd = getResourceFileAsString(R.raw.multitouch_xy);
 		File f = createTempFile(csd);
 
-		csoundObj.addValueCacheable(view1);
 		csoundObj.addValueCacheable(view2);
 
 		csoundObj.startCsound(f);

src/com/kunstmusik/touchvoice/MultiTouchView.java

 
 public class MultiTouchView extends View implements CsoundValueCacheable {
 	
-	private static final int TOUCH_MAX = 5;
+	private static final int TOUCH_MAX = 10;
 	
 	int touchIds[] = new int[TOUCH_MAX];
 	float touchX[] = new float[TOUCH_MAX];

src/com/kunstmusik/touchvoice/SpinnerValueCacheable.java

+package com.kunstmusik.touchvoice;
+
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.Spinner;
+
+import com.csounds.CsoundObj;
+import com.csounds.valueCacheable.CsoundValueCacheable;
+
+import csnd.CsoundMYFLTArray;
+
+public class SpinnerValueCacheable implements CsoundValueCacheable {
+
+	private CsoundObj csoundObj;
+	private int cachedPosition;
+	private Spinner spinner;
+	private CsoundMYFLTArray channel;
+	private String channelName;
+	boolean dirty = true;
+	OnItemSelectedListener listener;
+	
+	public SpinnerValueCacheable(Spinner spinner, String channelName) {
+		this.spinner = spinner;
+		this.channelName = channelName;
+		
+		listener = new OnItemSelectedListener() {
+
+			public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
+				cachedPosition = pos;
+				dirty = true;
+			}
+
+			public void onNothingSelected(AdapterView<?> arg0) {
+			}
+		};
+		
+		spinner.setOnItemSelectedListener(listener);
+	}
+	
+	public void setup(CsoundObj csoundObj) {
+		this.csoundObj = csoundObj;
+		this.cachedPosition = spinner.getSelectedItemPosition();
+		this.channel = csoundObj.getInputChannelPtr(channelName);
+		this.channel.SetValue(0, cachedPosition);
+	}
+
+	public void updateValuesToCsound() {
+
+		if(dirty) {
+			this.channel.SetValue(0, cachedPosition);
+			dirty = false;
+		}
+		
+	}
+
+	public void updateValuesFromCsound() {
+	}
+
+	public void cleanup() {
+		spinner.setOnItemSelectedListener(null);
+		channel.Clear();
+		channel = null;
+	}
+
+}

src/com/kunstmusik/touchvoice/VerticalSeekBar.java

+package com.kunstmusik.touchvoice;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.SeekBar;
+
+/**
+ * Code used from 
+ * http://stackoverflow.com/questions/631238/modifying-the-android-seekbar-widget-to-operate-vertically
+ *
+ */
+
+public class VerticalSeekBar extends SeekBar {
+
+	public VerticalSeekBar(Context context) {
+		super(context);
+	}
+
+	public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
+		super(context, attrs, defStyle);
+	}
+
+	public VerticalSeekBar(Context context, AttributeSet attrs) {
+		super(context, attrs);
+	}
+
+	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+		super.onSizeChanged(h, w, oldh, oldw);
+	}
+
+	@Override
+	protected synchronized void onMeasure(int widthMeasureSpec,
+			int heightMeasureSpec) {
+		super.onMeasure(heightMeasureSpec, widthMeasureSpec);
+		setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
+	}
+
+	protected void onDraw(Canvas c) {
+		c.rotate(-90);
+		c.translate(-getHeight(), 0);
+
+		super.onDraw(c);
+	}
+
+	private OnSeekBarChangeListener onChangeListener;
+
+	@Override
+	public void setOnSeekBarChangeListener(
+			OnSeekBarChangeListener onChangeListener) {
+		this.onChangeListener = onChangeListener;
+	}
+
+	private int lastProgress = 0;
+
+	@Override
+	public boolean onTouchEvent(MotionEvent event) {
+		if (!isEnabled()) {
+			return false;
+		}
+
+		switch (event.getAction()) {
+		case MotionEvent.ACTION_DOWN:
+			onChangeListener.onStartTrackingTouch(this);
+			setPressed(true);
+			setSelected(true);
+			break;
+		case MotionEvent.ACTION_MOVE:
+			// Calling the super seems to help fix drawing problems
+			super.onTouchEvent(event);
+			int progress = getMax()
+					- (int) (getMax() * event.getY() / getHeight());
+
+			// Ensure progress stays within boundaries of the seekbar
+			if (progress < 0) {
+				progress = 0;
+			}
+			if (progress > getMax()) {
+				progress = getMax();
+			}
+
+			// Draw progress
+			setProgress(progress);
+
+			// Only enact listener if the progress has actually changed
+			// Otherwise the listener gets called ~5 times per change
+			if (progress != lastProgress) {
+				lastProgress = progress;
+				onChangeListener.onProgressChanged(this, progress, true);
+			}
+
+			onSizeChanged(getWidth(), getHeight(), 0, 0);
+			onChangeListener.onProgressChanged(this, getMax()
+					- (int) (getMax() * event.getY() / getHeight()), true);
+			setPressed(true);
+			setSelected(true);
+			break;
+		case MotionEvent.ACTION_UP:
+			onChangeListener.onStopTrackingTouch(this);
+			setPressed(false);
+			setSelected(false);
+			break;
+		case MotionEvent.ACTION_CANCEL:
+			super.onTouchEvent(event);
+			setPressed(false);
+			setSelected(false);
+			break;
+		}
+		return true;
+	}
+
+	public synchronized void setProgressAndThumb(int progress) {
+		setProgress(getMax() - (getMax() - progress));
+		onSizeChanged(getWidth(), getHeight(), 0, 0);
+	}
+
+	public synchronized void setMaximum(int maximum) {
+		setMax(maximum);
+	}
+
+	public synchronized int getMaximum() {
+		return getMax();
+	}
+}