Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added in-memory audio stream and audio level event #48

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion Plugin.AudioRecorder.Shared/AudioRecorderService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ public partial class AudioRecorderService
/// <remarks>This event will be raised on a background thread to allow for any further processing needed. The audio file will be <c>null</c> in the case that no audio was recorded.</remarks>
public event EventHandler<string> AudioInputReceived;

/// <summary>
/// This event is raised when the most recent audio level has been calculated.
/// </summary>
/// <remarks>This event will be raised on a background thread to allow for any further processing needed. The audio level will be <c>0.0f</c> in the case that no audio was recorded.</remarks>
public event EventHandler<float> AudioLevelUpdated;

/// <summary>
/// Gets/sets a value indicating if the <see cref="AudioRecorderService"/> should write audio data to a file.
/// </summary>
/// <remarks>Defaults to <c>true</c></remarks>
public bool WriteAudioDataToFile { get; set; } = true;

partial void Init ();

/// <summary>
Expand Down Expand Up @@ -146,6 +158,8 @@ void AudioStream_OnBroadcast (object sender, byte [] bytes)
{
var level = AudioFunctions.CalculateLevel (bytes);

AudioLevelUpdated?.Invoke(this, level);

if (level < NearZero && !audioDetected) // discard any initial 0s so we don't jump the gun on timing out
{
Debug.WriteLine ("level == {0} && !audioDetected", level);
Expand Down Expand Up @@ -247,7 +261,9 @@ void InitializeStream (int sampleRate)

if (recorder == null)
{
recorder = new WaveRecorder ();
recorder = new WaveRecorder {
WriteAudioDataToFile = WriteAudioDataToFile
};
}
}
catch (Exception ex)
Expand All @@ -264,5 +280,14 @@ public string GetAudioFilePath ()
{
return audioDetected ? FilePath : null;
}

/// <summary>
/// Gets a new <see cref="Stream"/> to the audio data in readonly mode.
/// </summary>
/// <returns>A <see cref="Stream"/> object that can be used to read the audio memory from the beginning.</returns>
public Stream GetAudioMemoryStream()
{
return recorder.GetAudioMemoryStream();
}
}
}
33 changes: 29 additions & 4 deletions Plugin.AudioRecorder.Shared/WaveRecorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ internal class WaveRecorder : IDisposable
{
string audioFilePath;
FileStream fileStream;
MemoryStream memoryStream;
StreamWriter streamWriter;
BinaryWriter writer;
int byteCount;
IAudioStream audioStream;

IAudioStream audioStream;

/// <summary>
/// Gets/sets a value indicating if the <see cref="WaveRecorder"/> should write audio data to a file.
/// </summary>
/// <remarks>Defaults to <c>true</c></remarks>
public bool WriteAudioDataToFile { get; set; } = true;

/// <summary>
/// Starts recording WAVE format audio from the audio stream.
/// </summary>
Expand All @@ -38,8 +45,16 @@ public async Task StartRecorder (IAudioStream stream, string filePath)
audioFilePath = filePath;
audioStream = stream;

fileStream = new FileStream (filePath, FileMode.Create, FileAccess.Write, FileShare.Read);
streamWriter = new StreamWriter (fileStream);
if (WriteAudioDataToFile)
{
fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read);
streamWriter = new StreamWriter(fileStream);
}
else
{
memoryStream = new MemoryStream();
streamWriter = new StreamWriter(memoryStream);
}
writer = new BinaryWriter (streamWriter.BaseStream, Encoding.UTF8);

byteCount = 0;
Expand Down Expand Up @@ -68,6 +83,15 @@ public Stream GetAudioFileStream ()
{
//return a new stream to the same audio file, in Read mode
return new FileStream (audioFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
}

/// <summary>
/// Gets a new <see cref="Stream"/> to the audio data in readonly mode.
/// </summary>
/// <returns>A <see cref="Stream"/> object that can be used to read the audio memory from the beginning.</returns>
public Stream GetAudioMemoryStream()
{
return memoryStream;
}

void StreamActiveChanged (object sender, bool active)
Expand Down Expand Up @@ -121,6 +145,7 @@ public void StopRecorder ()
writer.Dispose (); //this should properly close/dispose the underlying stream as well
writer = null;
fileStream = null;
memoryStream = null;
streamWriter = null;
}

Expand Down
5 changes: 5 additions & 0 deletions Samples/Forms/AudioRecord.Forms/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ public MainPage ()
TotalAudioTimeout = TimeSpan.FromSeconds (15),
AudioSilenceTimeout = TimeSpan.FromSeconds (2)
};
recorder.AudioLevelUpdated += Recorder_AudioLevelUpdated;

player = new AudioPlayer ();
player.FinishedPlaying += Player_FinishedPlaying;
}

public void Recorder_AudioLevelUpdated (object sender, float level)
{
}

async void Record_Clicked (object sender, EventArgs e)
{
await RecordAudio ();
Expand Down