internal static partial class TonePlayer
{
[DllImport(Libraries.TonePlayer, EntryPoint = "tone_player_start_new")]
- internal static extern int Start(ToneType tone, IntPtr streamInfoHandle, int durationMs, out int playerId);
+ internal static extern TonePlayerError Start(ToneType tone, IntPtr streamInfoHandle,
+ int durationMs, out int id);
[DllImport(Libraries.TonePlayer, EntryPoint = "tone_player_stop")]
- internal static extern int Stop(int PlayerId);
+ internal static extern TonePlayerError Stop(int id);
}
}
using System;
using System.Runtime.InteropServices;
+using Tizen.Multimedia;
internal static partial class Interop
{
internal delegate void WavPlayerCompletedCallback(int playerId, IntPtr userData);
[DllImport(Libraries.WavPlayer, EntryPoint = "wav_player_start_new")]
- internal static extern int WavPlayerStart(string filePath, IntPtr streamInfoHandle, WavPlayerCompletedCallback completedCallback,
- IntPtr userData, out int playerId);
+ internal static extern WavPlayerError Start(string filePath, IntPtr streamInfoHandle,
+ WavPlayerCompletedCallback completedCallback, IntPtr userData, out int id);
[DllImport(Libraries.WavPlayer, EntryPoint = "wav_player_stop")]
- internal static extern int WavPlayerStop(int PlayerId);
+ internal static extern WavPlayerError Stop(int id);
}
}
+
<Import Project="../build/build.props" />
<PropertyGroup>
- <Version>1.0.0</Version>
+ <Version>1.0.1</Version>
<Description>Provides the Multimedia AudioIO API for Tizen .NET</Description>
</PropertyGroup>
*/
using System;
-using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace Tizen.Multimedia
{
- static internal class TonePlayerLog
- {
- internal const string LogTag = "Tizen.Multimedia.TonePlayer";
- }
-
/// <summary>
- /// The TonePlayer class allows you to play and stop playing the tone. To play a particular
- /// type of tone <see cref="Tizen.Multimedia.ToneType"/>,
- /// use <see cref="Tizen.Multimedia.TonePlayer.StartAsync"/>.
+ /// Provides the ability to play a tone.
/// </summary>
public static class TonePlayer
{
/// <summary>
/// Plays a tone, asynchronously.
/// </summary>
- /// <param name="tone">The tone type to play.</param>
- /// <param name="streamPolicy">The Audiostream policy object.</param>
- /// <param name="durationMs">The tone duration in milliseconds. -1 indicates an infinite duration.</param>
+ /// <param name="tone">A <see cref="ToneType"/> to play.</param>
+ /// <param name="streamPolicy">A <see cref="AudioStreamPolicy"/>.</param>
+ /// <param name="durationMilliseconds">The tone duration in milliseconds. -1 indicates an infinite duration.</param>
+ /// <returns>A task that represents the asynchronous operation.</returns>
+ /// <exception cref="ArgumentException"><paramref name="tone"/> is invalid.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="streamPolicy"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="durationMilliseconds"/> is less than -1.</exception>
+ /// <exception cref="InvalidOperationException">Any invalid operations occurred.</exception>
+ /// <exception cref="NotSupportedException"><paramref name="tone"/> is not a supported type.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="streamPolicy"/> has already been disposed.</exception>
+ public static Task StartAsync(ToneType tone, AudioStreamPolicy streamPolicy,
+ int durationMilliseconds)
+ {
+ return StartAsync(tone, streamPolicy, durationMilliseconds, CancellationToken.None);
+ }
+
+ /// <summary>
+ /// Plays a tone, asynchronously.
+ /// </summary>
+ /// <param name="tone">A <see cref="ToneType"/> to play.</param>
+ /// <param name="streamPolicy">A <see cref="AudioStreamPolicy"/>.</param>
+ /// <param name="durationMilliseconds">The tone duration in milliseconds. -1 indicates an infinite duration.</param>
/// <param name="cancellationToken">The cancellation token which can be used to stop playing the tone.</param>
- /// <exception cref="ArgumentException">In case of invalid parameters</exception>
- /// <exception cref="ArgumentNullException">In case of null parameters</exception>
- /// <exception cref="ArgumentOutOfRangeException">In case of play duration less than -1.</exception>
- /// <exception cref="InvalidOperationException">In case of any invalid operations</exception>
- /// <exception cref="NotSupportedException">In case of tone type not supported.</exception>
- public static async Task StartAsync(ToneType tone, AudioStreamPolicy streamPolicy, int durationMs, CancellationToken cancellationToken = default(CancellationToken))
+ /// <returns>A task that represents the asynchronous operation.</returns>
+ /// <exception cref="ArgumentException"><paramref name="tone"/> is invalid.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="streamPolicy"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="durationMilliseconds"/> is less than -1.</exception>
+ /// <exception cref="InvalidOperationException">Any invalid operations occurred.</exception>
+ /// <exception cref="NotSupportedException"><paramref name="tone"/> is not a supported type.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="streamPolicy"/> has already been disposed.</exception>
+ public static Task StartAsync(ToneType tone, AudioStreamPolicy streamPolicy,
+ int durationMilliseconds, CancellationToken cancellationToken)
{
- if (durationMs < -1)
+ if (durationMilliseconds < -1)
{
- throw new ArgumentOutOfRangeException(nameof(durationMs));
+ throw new ArgumentOutOfRangeException(nameof(durationMilliseconds), durationMilliseconds,
+ $"{nameof(durationMilliseconds)} can't be less than -1.");
}
if (streamPolicy == null)
{
throw new ArgumentNullException(nameof(streamPolicy));
+ }
+
+ ValidationUtil.ValidateEnum(typeof(ToneType), tone, nameof(tone));
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return Task.FromCanceled(cancellationToken);
}
- if (Enum.IsDefined(typeof(ToneType), tone) == false)
+ return StartAsyncCore(tone, streamPolicy, durationMilliseconds, cancellationToken);
+ }
+
+ private static async Task StartAsyncCore(ToneType tone, AudioStreamPolicy streamPolicy,
+ int durationMilliseconds, CancellationToken cancellationToken)
+ {
+
+ var tcs = new TaskCompletionSource<bool>();
+
+ Interop.TonePlayer.Start(tone, streamPolicy.Handle, durationMilliseconds, out var id).
+ Validate("Failed to play tone.");
+
+ using (RegisterCancellationAction(tcs, cancellationToken, id))
{
- throw new ArgumentException("Invalid ToneType provided : " + tone);
+ await WaitForDuration(tcs, cancellationToken, durationMilliseconds);
+
+ await tcs.Task;
}
+ }
- int id;
- var task = new TaskCompletionSource<int>();
- int ret = Interop.TonePlayer.Start(tone, streamPolicy.Handle, durationMs, out id);
- if (ret != (int)TonePlayerError.None)
+ private static async Task WaitForDuration(TaskCompletionSource<bool> tcs,
+ CancellationToken cancellationToken, int durationMilliseconds)
+ {
+ if (durationMilliseconds == -1)
{
- Log.Error(TonePlayerLog.LogTag, "Error Occured with error code: " + (TonePlayerError)ret);
- throw TonePlayerErrorFactory.CreateException(ret, "Failed to play tone.");
+ return;
}
- if (cancellationToken != CancellationToken.None)
+ try
{
- cancellationToken.Register((playerId) =>
- {
- int resultCancel = Interop.TonePlayer.Stop((int)playerId);
- if ((TonePlayerError)resultCancel != TonePlayerError.None)
- {
- Log.Error(TonePlayerLog.LogTag, "Failed to stop tone Player with error code: " + (TonePlayerError)resultCancel);
- }
- task.TrySetCanceled();
- }, id);
+ await Task.Delay(durationMilliseconds, cancellationToken);
+ tcs.TrySetResult(true);
}
+ catch (TaskCanceledException)
+ {
+ }
+ }
- if (durationMs != -1)
+ private static IDisposable RegisterCancellationAction(TaskCompletionSource<bool> tcs,
+ CancellationToken cancellationToken, int id)
+ {
+ if (cancellationToken.CanBeCanceled == false)
{
- Task delayTask = Task.Delay(durationMs, cancellationToken);
- await delayTask;
- if (delayTask.IsCompleted)
- {
- task.TrySetResult(id);
- }
+ return null;
}
- await task.Task;
+
+ return cancellationToken.Register(() =>
+ {
+ Interop.TonePlayer.Stop(id).Validate("Failed to cancel");
+ tcs.TrySetCanceled();
+ });
}
}
}
-/*
+/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
TypeNotSupported = TizenErrorTonePlayer | 0x01
}
- internal static class TonePlayerErrorFactory
+ internal static class TonePlayerErrorExtensions
{
- internal static Exception CreateException(int errorCode, string errorMessage)
+ internal static void Validate(this TonePlayerError error, string message)
{
- TonePlayerError err = (TonePlayerError)errorCode;
- Exception exp;
- if (string.IsNullOrEmpty(errorMessage))
+ if (error == TonePlayerError.None)
{
- errorMessage = err.ToString();
+ return;
}
- switch ((TonePlayerError)errorCode)
+ switch (error)
{
case TonePlayerError.InvalidParameter:
- {
- exp = new ArgumentException(errorMessage + "Invalid parameters provided");
- break;
- }
+ throw new ArgumentException(message);
case TonePlayerError.TypeNotSupported:
- {
- exp = new NotSupportedException(errorMessage + "Not Supported");
- break;
- }
+ throw new NotSupportedException(message);
case TonePlayerError.InvalidOperation:
- {
- exp = new InvalidOperationException(errorMessage + "Invalid Operation");
- break;
- }
+ throw new InvalidOperationException(message);
+
default:
- {
- exp = new InvalidOperationException(errorMessage);
- break;
- }
+ throw new InvalidOperationException(message);
+
}
- return exp;
}
}
}
* limitations under the License.
*/
-using System;
-
namespace Tizen.Multimedia
{
/// <summary>
/// </summary>
DtmfS,
/// <summary>
- /// Predefined DTMF sharP (#).
+ /// Predefined DTMF sharp (#).
/// </summary>
DtmfP,
/// <summary>
*/
using System;
-using System.Runtime.InteropServices;
+using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Tizen.Multimedia
{
- static internal class WavPlayerLog
- {
- internal const string LogTag = "Tizen.Multimedia.WavPlayer";
- }
-
/// <summary>
- /// The WavPlayer class allows you to simply play and stop a wav file. To play a certain
- /// wav file, call <see cref="Tizen.Multimedia.WavPlayer.StartAsync"/> with
- /// a path to the .wav file.
+ /// Provides the ability to play a wav file.
/// </summary>
public static class WavPlayer
{
/// <summary>
- /// Plays a WAV file with the stream information of AudioManager, asynchronously.
+ /// Plays a wav file based on the specified <see cref="AudioStreamPolicy"/>.
/// </summary>
- /// <param name="inputFilePath">The file path to play.</param>
- /// <param name="streamPolicy">The Audiostream policy object.</param>
- /// <param name="cancellationToken">The cancellation token which can be used to stop the Wav Player.</param>
- /// <returns>The WAV player ID.</returns>
- /// <exception cref="ArgumentException">In case of invalid parameters</exception>
- /// <exception cref="ArgumentNullException">In case of null parameters</exception>
- /// <exception cref="InvalidOperationException">In case of any invalid operations</exception>
- /// <exception cref="NotSupportedException">In case of format not supported.</exception>
- public static async Task StartAsync(string inputFilePath, AudioStreamPolicy streamPolicy, CancellationToken cancellationToken = default(CancellationToken))
+ /// <returns>A task that represents the asynchronous operation.</returns>
+ /// <param name="path">A file path to play.</param>
+ /// <param name="streamPolicy">A <see cref="AudioStreamPolicy"/>.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="path"/> is null.
+ /// <para>-or-</para>
+ /// <paramref name="streamPolicy"/> is null.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
+ /// <exception cref="FileNotFoundException"><paramref name="path"/> does not exists.</exception>
+ /// <exception cref="FileFormatException">The format of <paramref name=""/> is not supported.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="streamPolicy"/> has already been disposed of.</exception>
+ public static Task StartAsync(string path, AudioStreamPolicy streamPolicy)
{
- int id;
- var task = new TaskCompletionSource<int>();
+ return StartAsync(path, streamPolicy, CancellationToken.None);
+ }
- if (String.IsNullOrEmpty(inputFilePath))
+ /// <summary>
+ /// Plays a wav file based on the specified <see cref="AudioStreamPolicy"/>.
+ /// </summary>
+ /// <returns>A task that represents the asynchronous operation.</returns>
+ /// <param name="path">A file path to play.</param>
+ /// <param name="streamPolicy">A <see cref="AudioStreamPolicy"/>.</param>
+ /// <param name="cancellationToken">A cancellation token which can be used to stop.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="path"/> is null.
+ /// <para>-or-</para>
+ /// <paramref name="streamPolicy"/> is null.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
+ /// <exception cref="FileNotFoundException"><paramref name="path"/> does not exists.</exception>
+ /// <exception cref="FileFormatException">The format of <paramref name=""/> is not supported.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="streamPolicy"/> has already been disposed.</exception>
+ public static Task StartAsync(string path, AudioStreamPolicy streamPolicy,
+ CancellationToken cancellationToken)
+ {
+ if (path == null)
{
- throw new ArgumentNullException(nameof(inputFilePath));
+ throw new ArgumentNullException(nameof(path));
}
if (streamPolicy == null)
throw new ArgumentNullException(nameof(streamPolicy));
}
- Interop.WavPlayer.WavPlayerCompletedCallback _playerCompletedCallback = (int playerId, IntPtr userData) =>
+ if (File.Exists(path) == false)
{
- task.TrySetResult(playerId);
- };
- GCHandle callbackHandle = GCHandle.Alloc(_playerCompletedCallback);
+ throw new FileNotFoundException("File does not exists.", path);
+ }
- int ret = Interop.WavPlayer.WavPlayerStart(inputFilePath, streamPolicy.Handle, _playerCompletedCallback, IntPtr.Zero, out id);
- if (ret != (int)WavPlayerError.None)
+ return cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) :
+ StartAsyncCore(path, streamPolicy, cancellationToken);
+ }
+
+ private static async Task StartAsyncCore(string path, AudioStreamPolicy streamPolicy,
+ CancellationToken cancellationToken)
+ {
+ var tcs = new TaskCompletionSource<bool>();
+
+ Interop.WavPlayer.WavPlayerCompletedCallback cb = (id_, _) => tcs.TrySetResult(true);
+
+ Interop.WavPlayer.Start(path, streamPolicy.Handle, cb, IntPtr.Zero, out var id).
+ Validate("Failed to play.");
+
+ using (RegisterCancellationAction(tcs, cancellationToken, id))
{
- Log.Error(WavPlayerLog.LogTag, "Error Occured with error code: " + (WavPlayerError)ret);
- task.TrySetException(WavPlayerErrorFactory.CreateException(ret, "Failed to play Wav file."));
+ await tcs.Task;
}
+ }
- if (cancellationToken != CancellationToken.None)
+ private static IDisposable RegisterCancellationAction(TaskCompletionSource<bool> tcs,
+ CancellationToken cancellationToken, int id)
+ {
+ if (cancellationToken.CanBeCanceled == false)
{
- cancellationToken.Register((playerId) =>
- {
- int resultCancel = Interop.WavPlayer.WavPlayerStop((int)playerId);
- if ((WavPlayerError)resultCancel != WavPlayerError.None)
- {
- Log.Error(WavPlayerLog.LogTag, "Failed to stop Wav Player with error code: " + (WavPlayerError)resultCancel);
- }
- task.TrySetCanceled();
- }, id);
+ return null;
}
- await task.Task;
- callbackHandle.Free();
+ return cancellationToken.Register(() =>
+ {
+ Interop.WavPlayer.Stop(id).Validate("Failed to cancel");
+ tcs.TrySetCanceled();
+ });
}
}
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+ internal enum WavPlayerError
+ {
+ None = ErrorCode.None,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ TizenErrorWavPlayer = -0x01990000,
+ FormatNotSupported = TizenErrorWavPlayer | 0x01,
+ NotSupportedType = TizenErrorWavPlayer | 0x02
+ }
+
+ internal static class WavPlayerErrorExtensions
+ {
+ internal static void Validate(this WavPlayerError error, string message)
+ {
+ if (error == WavPlayerError.None)
+ {
+ return;
+ }
+
+ switch (error)
+ {
+ case WavPlayerError.InvalidParameter:
+ throw new ArgumentException(message);
+
+ case WavPlayerError.FormatNotSupported:
+
+ case WavPlayerError.NotSupportedType:
+ throw new NotSupportedException(message);
+
+ case WavPlayerError.InvalidOperation:
+ throw new InvalidOperationException(message);
+ }
+ }
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using Tizen.Internals.Errors;
-
-namespace Tizen.Multimedia
-{
- internal enum WavPlayerError
- {
- None = ErrorCode.None,
- InvalidParameter = ErrorCode.InvalidParameter,
- InvalidOperation = ErrorCode.InvalidOperation,
- TizenErrorWavPlayer = -0x01990000,
- FormatNotSupported = TizenErrorWavPlayer | 0x01,
- NotSupportedType = TizenErrorWavPlayer | 0x02
- }
-
- internal static class WavPlayerErrorFactory
- {
- internal static void ThrowException(int errorCode, string errorMessage = null, string paramName = null)
- {
- WavPlayerError err = (WavPlayerError)errorCode;
- if (string.IsNullOrEmpty(errorMessage))
- {
- errorMessage = err.ToString();
- }
-
- switch ((WavPlayerError)errorCode)
- {
- case WavPlayerError.InvalidParameter:
- throw new ArgumentException(errorMessage, paramName);
-
- case WavPlayerError.FormatNotSupported:
- case WavPlayerError.NotSupportedType:
- throw new NotSupportedException(errorMessage);
-
- case WavPlayerError.InvalidOperation:
- throw new InvalidOperationException(errorMessage);
- }
- }
-
- internal static Exception CreateException(int errorCode, string errorMessage)
- {
- WavPlayerError err = (WavPlayerError)errorCode;
- Exception exp;
- if (string.IsNullOrEmpty(errorMessage))
- {
- errorMessage = err.ToString();
- }
-
- switch ((WavPlayerError)errorCode)
- {
- case WavPlayerError.InvalidParameter:
- {
- exp = new ArgumentException(errorMessage + "Invalid parameters provided");
- break;
- }
-
- case WavPlayerError.FormatNotSupported:
- case WavPlayerError.NotSupportedType:
- {
- exp = new NotSupportedException(errorMessage + "Not Supported");
- break;
- }
-
- case WavPlayerError.InvalidOperation:
- {
- exp = new InvalidOperationException(errorMessage + "Invalid Operation");
- break;
- }
- default:
- {
- exp = new InvalidOperationException(errorMessage);
- break;
- }
- }
- return exp;
- }
- }
-}