singrdk/base/Applications/Play/Play.sg

140 lines
4.7 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: Play.sg
//
// Note: Simple audio test program.
//
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Threading;
using Microsoft.Contracts;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Directory;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
[assembly: Transform(typeof(ApplicationResourceTransform))]
namespace Microsoft.Singularity.Applications
{
// use driver category for now.
// Once the appropriate categories have been defined this will need to change
// Also waiting for Compile Time reflection to eliminate static constructor etc.
[ConsoleCategory(DefaultAction=true)]
internal sealed class PlayConfiguration
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
[Endpoint]
public readonly TRef<SoundDeviceContract.Imp:Start> ImpRef;
reflective internal PlayConfiguration();
internal int AppMain() {
return Play.AppMain(this);
}
}
public class Play
{
private static SoundDeviceContract.Imp:Ready OpenSoundDevice(PlayConfiguration! config)
{
// extract imp handed in as part of process creation
SoundDeviceContract.Imp! imp = (config.ImpRef).Acquire();
// get it into the ready state
Console.WriteLine("[{0}] Waiting for SB channel.", Thread.CurrentThread.GetThreadId());
switch receive
{
case imp.Success():
Console.WriteLine("[{0}] Got SB channel.", Thread.CurrentThread.GetThreadId());
break;
case imp.ContractNotSupported():
delete imp;
throw new Exception("Didn't Get SB channel. (ContractNotSupported)");
case imp.ChannelClosed():
delete imp;
throw new Exception("Didn't Get SB channel. (Channel closed)");
}
return imp;
}
internal static int AppMain(PlayConfiguration! config)
{
if (WavAudio.Content == null || WavAudio.Content.Length == 0) {
Console.WriteLine("No WAV audio to play.");
return 1;
}
return DoPlay(config);
return 0;
}
private static int DoPlay(PlayConfiguration! config) {
SoundDeviceContract.Imp audio = OpenSoundDevice(config);
if (audio == null) {
Console.WriteLine("Couldn't open audio device.");
return 2;
}
int threadId = Thread.CurrentThread.GetThreadId();
assume WavAudio.Content != null;
try {
for (int i = 0; i < WavAudio.Content.Length; i++) {
Console.WriteLine("[{1}] Playing WAV audio {0}.", i, threadId);
byte[] wav = (!)WavAudio.Content[i];
byte[] in ExHeap buffer = Bitter.FromByteArray(wav);
// Copy contents into buffer WavAudio.Content[i]
audio.SendPlayWav(buffer);
switch receive
{
case audio.RecvAckPlayWav(oldbuffer):
Console.WriteLine("[{1}] Done playing WAV audio {0}.", i,
threadId);
delete oldbuffer;
break;
case audio.RecvNakPlayWav(oldbuffer):
Console.WriteLine("[{1}] Failed to play WAV audio {0}.",
i, threadId);
delete oldbuffer;
break;
case audio.ChannelClosed():
Console.WriteLine("[{1}] SoundDevice channel closed unexpectedly {0}.",
i, threadId);
return 1;
}
}
}
finally {
delete audio;
}
return 0;
}
}
}