public void SetInstantSoundingChar(SoundChars current) { //foreach (var img in soundCharImages) // img.color = Color.gray; //int index = (int)current; //if (0 <= index && index < soundCharImages.Length) // soundCharImages[index].color = soundCharImagesColoring[index]; }
void IncAmount(SoundChars which) { specificAmount[which] += specIncPerSec * specificChargeIncFactor[which] * Time.deltaTime; if (specificAmount[which] > 1f) { /* Debug.Log("INC TH " + which.ToString()); * Debug.Log("WINNING " + winning.ToString() );*/ } if (specificAmount[which] > 2f) { specificAmount[which] = 2f; } }
public void OnBeginChar(SoundChars current, int currentIndex) { //Debug.Log("OnBeginChar " + current.ToString() + " index=" + currentIndex); //delete this line, eventually foreach (var img in soundCharImages) { img.color = Color.gray; } int index = (int)current; if (0 <= index && index < soundCharImages.Length) { soundCharImages[index].color = soundCharImagesColoring[index]; } }
// Update is called once per frame void Update() { foreach (var k in specificAmount.Keys.ToArray()) { specificAmount[k] = Mathf.Max(0f, specificAmount[k] - specDecPerSec * Time.deltaTime); } if (Input.GetKeyDown(KeyCode.R) && Application.isEditor) { _code = ""; } var c = GetComponent <AudioMeasureCS>(); //FIXME: THIS QUEUE'S EFFECTS WILL BE AFFECTED BY FRAMERATE _queue.Enqueue(new QElem(c.PitchValue, c.DbValue)); if (_queue.Count > maxQLen) { _queue.Dequeue(); } //Debug.Log(_volumeQ.Aggregate("", (a, x) => a + string.Format(" {0:0.0}", x))); var reversedQ = _queue.Reverse().ToArray(); //Last first! var vflips = reversedQ.Aggregate( new { flips = 0, last = reversedQ.First().volume, ls = 1f } , (a, x) => { var delta = a.last - x.volume; var cls = Mathf.Sign(delta); var val = cls * a.ls <0 && Mathf.Abs(x.volume - a.last)> rrrVolumeThresholdDeltaDiff; return(new { flips = a.flips + (val ? 1 : 0), last = x.volume, ls = cls }); } ) .flips; var maxLastDb = reversedQ .Take(dbAvgQAmt) .Select(x => x.volume) .Max(); var pitch = reversedQ .Select(x => x.pitch) .Take(avgPitchCount) //.Skip(_queue.Count - avgPitchCount) //.Average(); .Median(); //.Max(); //Reason: "B" and "P" parts are detected as low-freq, so use the highest //var pitch = c.PitchValue; var str = string.Format("P{0:0.00}[{2:0.00}] V{1:0.00}", c.PitchValue, c.DbValue, pitch) + "\n" + _code; GetComponent <Text>().text = str; //Draw in texture if (enableTexFeedback && _texFeedback != null) { int y0, y1; TextureLine(_iFb, 0, _texFeedback.height, Color.white); y0 = Mathf.Clamp((int)((c.DbValue * 0.01f + 0.5f) * _texFeedback.height), 0, _texFeedback.height - 1); y1 = Mathf.Clamp((int)((_lastDb * 0.01f + 0.5f) * _texFeedback.height), 0, _texFeedback.height - 1); TextureLine(_iFb, y0, y1, Color.cyan); y0 = Mathf.Clamp((int)(4f * c.pitchIndex * _texFeedback.height / c.QSamples), 0, _texFeedback.height - 1); y1 = Mathf.Clamp((int)(4f * _lastPitchIndex * _texFeedback.height / c.QSamples), 0, _texFeedback.height - 1); TextureLine(_iFb, y0, y1, Color.red); //Draw current position pointer if (_iFb > 0) { var dbt = Mathf.Clamp((int)((volumeThreshold * 0.01f + 0.5f) * _texFeedback.height), 0, _texFeedback.height - 1); //var dbt2 = Mathf.Clamp((int)(((volumeThreshold + rrrVolumeDelta) * 0.01f + 0.5f) * _texFeedback.height), 0, _texFeedback.height - 1); var ptf = 1600f / (48000f / 2f) * (float)c.QSamples; // convert index to frequency var pt = Mathf.Clamp((int)(4f * ptf * _texFeedback.height / c.QSamples), 0, _texFeedback.height - 1); var adb = Mathf.Clamp((int)((maxLastDb * 0.01f + 0.5f) * _texFeedback.height), 0, _texFeedback.height - 1); TextureLine(_iFb, dbt, dbt, Color.blue); TextureLine(_iFb, adb, adb, Color.green); //TextureLine(_iFb, dbt2, dbt2, Color.gray); TextureLine(_iFb, pt, pt, Color.magenta); TextureLine(_iFb, _texFeedback.height / 2, _texFeedback.height / 2, Color.black); TextureLine(_iFb - 1, _texFeedback.height / 2, _texFeedback.height / 2, Color.white); //_texFeedback.SetPixel(_iFb, dbt, Color.blue); //_texFeedback.SetPixel(_iFb, _texFeedback.height / 2, Color.black); //_texFeedback.SetPixel(_iFb - 1, _texFeedback.height / 2, Color.white); } _texFeedback.Apply(); _iFb++; if (_iFb == _texFeedback.width) { _iFb = 0; } } SoundChars curr = SoundChars.Silence; if ( vflips > flipsThreshold //&& Mathf.Abs(pitch - _lastPitch) < rrrSamePitchSensitivity && maxLastDb > volumeThreshold ) { Utility.LogInfo("RRR " + vflips); curr = SoundChars.Rrr; IncAmount(SoundChars.Rrr); } if (c.DbValue > volumeThreshold) { SoundChars curr2 = SoundChars.Silence; if (1200f < pitch && pitch < 5000f) { curr2 = SoundChars.Bip; } else if (1f <= pitch && pitch < 1200f) { curr2 = SoundChars.Bop; } if (curr2 != SoundChars.Silence) { IncAmount(curr2); } if (curr == SoundChars.Silence) { curr = curr2; } } if (curr == SoundChars.Silence) { IncAmount(curr); } if (Input.GetKey(KeyCode.X)) { Debug.Log("X PITCH INDEX " + c.pitchIndex + " PITCH " + c.PitchValue + " CALCD PITCH=" + pitch); } _charge += Time.deltaTime; if (!_micProxy.microphoneEnabled) { _wordSounds.Clear(); } winning = specificAmount .Where(kv => kv.Key != SoundChars.Silence && kv.Value > 1f) .OrderByDescending(kv => kv.Value) .ThenBy(kv => kv.Key != SoundChars.Rrr) .Select(x => x.Key) .DefaultIfEmpty(SoundChars.Silence) .First() ; //Magic override curr = winning; if (curr == SoundChars.Silence) { if (_charge > silenceChargeTime) { if (curr != _last) { _micProxy.OnEndChar(_wordSounds.Count); } _charge = 0f; _detected = false; _last = curr; Utility.LogInfo("Reset!"); } } else { if (curr != _last) { _last = curr; //_charge = 0f; _detected = false; Utility.LogInfo("Change!"); } else if (_charge > noteChargeTime * specificChargeThreshold[curr] && !_detected) { _micProxy.OnBeginChar(curr, _wordSounds.Count); _detected = true; _code += SoundToChar[curr]; _wordSounds.Enqueue(curr); if (_wordSounds.Count == Word.MAX_DIGITS) { //NOTE: For different sized words the feed should be sent on a silence. var word = AppData.Instance.AvailableWords .FirstOrDefault(w => w.BipBopValues.Zip(_wordSounds, (s1, s2) => s1 == s2).All(x => x)); _code += "."; if (word != null) { _micProxy.Feed(word); _code += "!!"; _wordSounds.Clear(); } else { _wordSounds.Dequeue(); } } Utility.LogInfo(str); Utility.LogInfo("PITCH INDEX " + c.pitchIndex + " PITCH " + c.PitchValue + " CALCD PITCH=" + pitch); } } _lastPitch = pitch; _lastDb = c.DbValue; _lastPitchIndex = c.pitchIndex; _micProxy.SetInstantSoundingChar(_last); }