private void StartStreamingAudio(short[] initialData) { #if __ANDROID__ if (playingTrack != null) { if (playingTrack.PlayState == PlayState.Playing) { throw new InvalidOperationException("Audio is already playing."); } } playingTrack = new AudioTrack( // Stream type Android.Media.Stream.Music, // Frequency 44100, // Mono or stereo ChannelOut.Mono, // Audio encoding Android.Media.Encoding.Pcm16bit, // Length of the audio clip. (initialData.Length * 2) * 2, // Double buffering // Mode. Stream or static. AudioTrackMode.Stream); playingTrack.PeriodicNotification += OnStreamingAudioPeriodicNotification; playingTrack.SetPositionNotificationPeriod(initialData.Length); playingTrack.Play(); playingTrack.Write(initialData, 0, initialData.Length); #endif }
/// <summary> /// Start the platform-specific audio object and give it some initial data (beat0 and beat1) /// </summary> private void StartStreamingAudio(short[] beat0, short[] beat1) { #if __ANDROID__ playingTrack = new AudioTrack( // Stream type Android.Media.Stream.Music, // Frequency PLAYBACK_RATE, // Mono or stereo ChannelOut.Mono, // Audio encoding Android.Media.Encoding.Pcm16bit, // Length of the audio clip in bytes (samplesPerBeat * 2) * 2, //Multiply by 2 because we want two beats to fit in the playingTrack's memory // Mode. Stream or static. AudioTrackMode.Stream); //Set up notifications at the end of beats playingTrack.PeriodicNotification += OnStreamingAudioPeriodicNotification; playingTrack.SetPositionNotificationPeriod(samplesPerBeat); //Write the initial data and begin playing playingTrack.Write(beat0, 0, beat0.Length); playingTrack.Write(beat1, 0, beat1.Length); playingTrack.Play(); #endif #if __IOS__ audioQueue = new OutputAudioQueue(streamDesc); unsafe { //Allocate two buffers to store audio data AudioQueueBuffer *buffer0; AudioQueueBuffer *buffer1; audioQueue.AllocateBuffer(beat0.Length * 2, out buffer0); audioQueue.AllocateBuffer(beat1.Length * 2, out buffer1); //Copy initial audio data to the buffers fixed(short *beatData0 = beat0) { buffer0->CopyToAudioData((IntPtr)beatData0, beat0.Length * 2); } fixed(short *beatData1 = beat1) { buffer1->CopyToAudioData((IntPtr)beatData1, beat1.Length * 2); } //Add the buffers to the queue audioQueue.EnqueueBuffer((IntPtr)buffer0, beat0.Length * 2, null); audioQueue.EnqueueBuffer((IntPtr)buffer1, beat1.Length * 2, null); } //Set up periodic notifications audioQueue.BufferCompleted += OnStreamingAudioPeriodicNotification; audioQueue.Start(); #endif }
/********************************************************************************* * * *********************************************************************************/ public void ButtonPlay_Click(object sender, EventArgs e) { //String musicFolder = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryMusic).Path; String filePath = mRecFolder + "/sample_mono_8k8bit.wav"; //String filePath = musicFolder + "/sample_stereo_44k16bit.wav"; System.Diagnostics.Debug.WriteLine(filePath); File file = new File(filePath); FileInputStream inputStream = new FileInputStream(file); // Streamモードで再生を行うので、リングバッファサイズを取得 Int32 bufferSize = AudioTrack.GetMinBufferSize(mSamplingRate, ChannelOut.Mono, mFormat); System.Diagnostics.Debug.WriteLine("AudioTrack : GetMinBufferSize={0}", bufferSize); // Frame size TrackBuffer.Instance.Frames = mFrameSize; // AudioTrackを生成する mAudioTrack = new AudioTrack( Stream.Music, //Stream.VoiceCall, mSamplingRate, ChannelOut.Mono, mFormat, bufferSize, AudioTrackMode.Stream); // コールバックを指定 mAudioTrack.SetPlaybackPositionUpdateListener(new OnPlaybackPositionUpdateListener()); //通知の発生するフレーム数を指定 mAudioTrack.SetPositionNotificationPeriod(TrackBuffer.Instance.Frames); TrackBuffer.Instance.Clear(); Task.Run(() => { while (true) { if (TrackBuffer.Instance.Count > 5) { break; } } System.Diagnostics.Debug.WriteLine("AudioTrack play streaming data"); mAudioTrack.Play(); Byte[] wav = null; wav = TrackBuffer.Instance.Dequeue(); mAudioTrack.Write(wav, 0, wav.Length); wav = TrackBuffer.Instance.Dequeue(); mAudioTrack.Write(wav, 0, wav.Length); wav = TrackBuffer.Instance.Dequeue(); mAudioTrack.Write(wav, 0, wav.Length); wav = TrackBuffer.Instance.Dequeue(); mAudioTrack.Write(wav, 0, wav.Length); }); }
public TrackInfo(AudioTrack track, IntPtr javaDataBuffer, byte[] dataBuffer, int bufferSize) { Track = track; this.javaDataBuffer = javaDataBuffer; this.dataBuffer = dataBuffer; this.bufferSize = bufferSize; javaWriteCallValues = new JValue[3]; // add the callback feeding the audio track and updating play status Track.PeriodicNotification += (sender, args) => OnPeriodFinished(); var status = Track.SetPositionNotificationPeriod(bufferSize / 4); // in frame number ( 2 channels * 2 byte data = 4) if (status != TrackStatus.Success) { throw new AudioSystemInternalException("AudioTrack.SetNotificationMarkerPosition failed and failure was not handled. [error=" + status + "]."); } }