Cabbage Logo
Back to Cabbage Site

Pitch conversion problems and sound distortion in Unity

Hello, not sure what’s going on, but a csound program works fine in QT but distorts when run by Unity/CS.

Here’s the simple instrument:

<Cabbage>
form caption("forBehaviorTree"), size(300, 200)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -m0d
</CsOptions>
<CsInstruments>

sr = 44100
ksmps = 128
nchnls = 2
0dbfs = 1.0

instr 1
; setup
iCos ftgen 0, 0, 8192, 11, 1
iamp = p4
kfreq = cpspch(p5)		; 12 tone ET
; ifreq cpsxpch p5, 31, 3.5, 1	; 31 tone

; asig oscil iamp, ifreq, 2	; table 2
; tone gen
asig gbuzz 1, kfreq, 75, 1, 0.9, iCos

ifiltrise = 0.005
ifiltdec1 = 0.05
ifiltdec2 = p3 - (ifiltrise + ifiltdec1)
kfiltenv linseg 300, ifiltrise, 2500, ifiltdec1, 1000, ifiltdec2, 300

afilt moogladder asig, kfiltenv, 0.2

; output
aout linen afilt * iamp, 0.01, p3, 0.1
outs aout, aout
endin

</CsInstruments>
<CsScore>
f0 z		; run forever
t 0 100	; tempo, slow down after x, y, z times in ordered pairs
</CsScore>
</CsoundSynthesizer>

Here’s the section of CS in Unity:

[Task]
bool Turn(float angle)
{
	var p = this.transform.position + Quaternion.AngleAxis (angle, Vector3.up) * this.transform.forward;
	target = p;
	if(timedPlayback <= 0.0f)
	{
		csoundUnity.sendScoreEvent("i1 0 0.5 0.5 7.04 ");	// mary had...
		csoundUnity.sendScoreEvent("i1 1 0.5 0.5 7.06 ");	// mary had...
		csoundUnity.sendScoreEvent("i1 2 0.5 0.5 7.08 ");	// mary had...
		timedPlayback = timerReload;
	}
	return true;
}

it’s in a behavior tree. csound seems to initialize properly without error messages (except for a few dylibs) and runs audio, but the pitches don’t track properly and the sound is distorted. I’ve put a score in the instrument and in that context it sounds fine, not sure what the problem is.

Thanks for any help!!!

(sorry but the markers in the csound program are hidden, I think you get the idea… how should I copy the program or attach it?)

Are the sampling rates set correctly for your project? Also, you may want to set audio priority to the highest level. If that doesn’t work maybe you can prepare a simple project for me to try?

P.s. You can use the format code button when posting code. That will show the tags :+1:

[edit] You can also try bringing your ksmps value down to 32 or 16. I find these values work well in Unity.

Wow, that did the trick, to lower ksmps to 32!
So I now have a different problem. What is the technique to send timed score events to Csound from unity?
it seems to ignore the delay onset times in the message (it’s all chords), so
“i1 2 0.5…” happens immediately. Do I need to make longer strings and send everything at once? How does it know where one event statement ends and the other begins?

Thanks!!!

That’s odd, those events shouldn’t fire until the specified time has passed. But in general I would use Csound for all the timing. That way you can be sure things will be in time. Timing in Unity is not great unless you tap into the OnFilterRead method. In general I think it’s best to send info from Csound to trigger gui events, rather than the other way around.

Ok, I will do some experiments to figure timing.
Not sure I know what you mean by triggering gui events… the game knows about the game space where things happen and updates parameters of the Csound instrument, but Csound doesn’t.
Also, do you mean OnAudioFilterRead to process blocks of sample data? Are these blocks I’d have to maintain in the Unity CS code? Also, my understanding is that OnFixedUpdate in Unity is pretty reliable for timing.

The OnAudioFilterRead timing is sample accurate. No issues there. If events are being sequenced musically like in a DAW it’s best to sequence them in Csound. But if you just need to trigger sounds based in book timed events in the game don’t it the way you should work fine. I’m still not sure why those score events play straight away. I’ll take a look.