how to play wave cue markers

Hi

I have a sound with markers and would like to implement standard marker looping functionality.
Looks that should be easy with:

AudioClip myClip = AudioClip.Create(“MySinoid”,44100, 2, 44100, false, true, OnAudioRead, OnAudioSetPosition);

In function OnAudioRead I would like to provide my samples according to markers information,
but I have a problem even with playing simple clip properly from the begining to the end.

Can you please tell me why I can’t hear begining of my clip or where to set real_pos=0;

using UnityEngine;
using System.Collections;

public class clb_test : MonoBehaviour
{
 int real_pos=0;
 AudioSource looping_src=null;
 public AudioClip source_clip;
 float [] samples = null;
 public bool started=false;

 void Start() {
 
 AudioSettings.outputSampleRate=44100;
 looping_src=(AudioSource)gameObject.AddComponent("AudioSource"); 
 looping_src.ignoreListenerVolume = true;
 looping_src.playOnAwake=false;
 looping_src.loop=true;
 
 samples = new float[source_clip.samples * source_clip.channels];
 source_clip.GetData(samples,0);
 
 AudioClip myClip = AudioClip.Create("MySinoid",source_clip.frequency, source_clip.channels, source_clip.frequency, false, true, OnAudioRead, OnAudioSetPosition); 
 looping_src.clip = myClip; 
 
 }
 
    void OnAudioRead(float[] data) 
 {
        int count = 0;
 //string s="T:"+System.DateTime.Now.Second.ToString()+","+System.DateTime.Now.Millisecond.ToString();
 //Debug.Log(s+" real_pos:" +real_pos.ToString());
 
     while (count < data.Length) 
 {
         //data[count] = Mathf.Sign(Mathf.Sin(2 * Mathf.PI * 440 * position / sampleRate));
 
 int len=samples.Length;
 if (real_pos>=len)
 {
 data[count]=0;
 }
 else
 {
 data[count]=samples[real_pos];
 }
 
         count++;
 real_pos++;
 }
    }
    
 void OnAudioSetPosition(int newPosition) 
 {
 //string s="T:"+System.DateTime.Now.Second.ToString()+","+System.DateTime.Now.Millisecond.ToString();
        //Debug.Log("OnAudioSetPosition:"+ s + "new pos "+newPosition.ToString());
 
 if (!started)  //it not helps at all
 {
 real_pos=newPosition;  //If it is here play constantly 1st second of clip which is normal
 started=true;
 }
 
    }
 
 void OnGUI () 
 {
 if(GUILayout.Button("play"))
 {
 started=false;
 //real_pos=0; //if it is here can't hear begining of my clip (check with voice - then easy to detect bug)
 looping_src.Play();
 } 
 
 if(GUILayout.Button("stop"))
 {
 looping_src.Stop();
 started=false;
 }
 }
}

As far I know, the OnAudioRead and OnAudioSetPosition methods only fire events based on the unity playback position. Its supposed to give you a little more control of doing actions based on what sample data has just been played or if the playhead was moved. Unity does not support wave cues. If you want to use cues, try using Audacity and make “Labels”, which is there version of cues. These labels can be exported to a text file and then you can read that data into Unity. You will have to manually track the audio source playback time and match it with the label times.

I know this was a long, long time ago in a galaxy far, far away*, but for other users coming across this, I’ve got a simple workaround.

If you’re using Audition you can right click on the time and change it to samples, then your marker list will also show in samples. When you want to seek to a marker in Unity instead use AudioSource.timeSamples and refer to the marker list and instead of writing the marker name, write the sample value.

The net result will be identical, arguably with one fewer processing step (the marker is just a reference to a sample value anyway, so now the game doesn’t have to lookup the reference to get the sample value) and unlike AudioSource.time it’s not affected by compression, so it’s always accurate.

Hope that helps someone! :slight_smile:

*sorry, it was May the 4th yesterday!