Wednesday, March 18, 2009
XAML PT community lauched
I would like to thank Fullsix Portugal for sponsoring this community.
Saturday, February 21, 2009
Web site frontend performance
This week I presented at DevDays09 the session WUX303 – Optimização de Performance de Web Sites. This session had great feedback. It was ranked number 7 of the overall 75 sessions of the event.
It was an overview of the book “High Performance Web Sites” by Steve Souders. I presented the 14 rules and showed some demos and tools that help on optimizing your website.
Here are some of the tools I used:
- YSlow
- IBM Page Detailer
- Microsoft Visual Round Trip Analyser
- Hammerhead
- Cuzzilion
- Performance Webpage Test (Online)
- Fiddler2
Here are the slides of the presentation and the demos.
Sunday, February 15, 2009
Changing sound frequency for game
Hi!
I wanted to be able to change a sound frequency according to the strength applied to a element inside a game. Based on this thread I changed the sample to allow to change at real time the frequency of the sound being played.
The code that does the thing is:
1: BufferDescription d = new BufferDescription();
2: d.ControlFrequency = true;
3: sound = new SecondaryBuffer("C:\\Windows\\Media\\ding.wav", d, applicationDevice);
4: sound.Frequency = 0; //The default frequency
5: sound.Play(0, BufferPlayFlags.Looping);6: if you want to change the frequency:
7: sound.Frequency = <some value>;
Here is the complete code:
(you need to add a reference to Microsoft.DirectX.DirectSound)
1: using System;
2: using System.IO;
3: using System.Drawing;
4: using System.Collections;
5: using System.ComponentModel;
6: using System.Windows.Forms;
7: using System.Data;
8: 9: using Microsoft.DirectX.DirectSound;
10: 11: namespace Noisey
12: {13: /// <summary>
14: /// Very simple test form
15: /// </summary>
16: public class MainForm : System.Windows.Forms.Form
17: {18: private System.Windows.Forms.Button btnPlay;
19: /// <summary>
20: /// Required designer variable.
21: /// </summary>
22: private System.ComponentModel.Container components = null;
23: 24: Device applicationDevice; 25: SecondaryBuffer sound;26: private BufferDescription d;
27: 28: private TrackBar trackBar1;
29: private TextBox txtFreq;
30: private Label label1;
31: private Label label2;
32: private Button btnStop;
33: private OpenFileDialog openFileDialog1;
34: private Button btnNewFile;
35: private Label lblFile;
36: private Label label3;
37: 38: 39: 40: public MainForm()
41: {42: //
43: // Required for Windows Form Designer support
44: //
45: InitializeComponent(); 46: 47: //
48: // Add any constructor code after InitializeComponent call
49: //
50: applicationDevice = new Device();
51: applicationDevice.SetCooperativeLevel(this, CooperativeLevel.Normal);
52: 53: d = new BufferDescription();
54: // Set descriptor’s flags
55: d.ControlPan = true;
56: d.ControlVolume = false;
57: d.ControlFrequency = true;
58: d.ControlEffects = false;
59: 60: //Load a default file
61: sound = new SecondaryBuffer("C:\\Windows\\Media\\ding.wav", d, applicationDevice);
62: sound.Frequency = 0; //The default frequency
63: 64: //Disable stop button because it's not playing yet.
65: btnStop.Enabled = false;
66: } 67: 68: /// <summary>
69: /// Clean up any resources being used.
70: /// </summary>
71: protected override void Dispose(bool disposing)
72: {73: if (disposing)
74: {75: if (components != null)
76: { 77: components.Dispose(); 78: } 79: }80: base.Dispose(disposing);
81: } 82: 83: #region Windows Form Designer generated code
84: /// <summary>
85: /// Required method for Designer support - do not modify
86: /// the contents of this method with the code editor.
87: /// </summary>
88: private void InitializeComponent()
89: {90: this.btnPlay = new System.Windows.Forms.Button();
91: this.trackBar1 = new System.Windows.Forms.TrackBar();
92: this.txtFreq = new System.Windows.Forms.TextBox();
93: this.label1 = new System.Windows.Forms.Label();
94: this.label2 = new System.Windows.Forms.Label();
95: this.btnStop = new System.Windows.Forms.Button();
96: this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
97: this.btnNewFile = new System.Windows.Forms.Button();
98: this.lblFile = new System.Windows.Forms.Label();
99: this.label3 = new System.Windows.Forms.Label();
100: ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
101: this.SuspendLayout();
102: //
103: // btnPlay
104: //
105: this.btnPlay.Location = new System.Drawing.Point(18, 64);
106: this.btnPlay.Name = "btnPlay";
107: this.btnPlay.Size = new System.Drawing.Size(87, 20);
108: this.btnPlay.TabIndex = 0;
109: this.btnPlay.Text = "Play Sound";
110: this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click);
111: //
112: // trackBar1
113: //
114: this.trackBar1.Location = new System.Drawing.Point(37, 124);
115: this.trackBar1.Maximum = 50000;
116: this.trackBar1.Minimum = 1000;
117: this.trackBar1.Name = "trackBar1";
118: this.trackBar1.Size = new System.Drawing.Size(190, 45);
119: this.trackBar1.TabIndex = 1;
120: this.trackBar1.Value = 30000;
121: this.trackBar1.ValueChanged += new System.EventHandler(this.trackBar1_ValueChanged);
122: //
123: // txtFreq
124: //
125: this.txtFreq.Enabled = false;
126: this.txtFreq.Location = new System.Drawing.Point(43, 185);
127: this.txtFreq.Name = "txtFreq";
128: this.txtFreq.Size = new System.Drawing.Size(100, 20);
129: this.txtFreq.TabIndex = 2;
130: //
131: // label1
132: //
133: this.label1.AutoSize = true;
134: this.label1.Location = new System.Drawing.Point(40, 108);
135: this.label1.Name = "label1";
136: this.label1.Size = new System.Drawing.Size(100, 13);
137: this.label1.TabIndex = 3;
138: this.label1.Text = "Frequency Change:";
139: //
140: // label2
141: //
142: this.label2.AutoSize = true;
143: this.label2.Location = new System.Drawing.Point(43, 166);
144: this.label2.Name = "label2";
145: this.label2.Size = new System.Drawing.Size(97, 13);
146: this.label2.TabIndex = 4;
147: this.label2.Text = "Current Frequency:";
148: //
149: // btnStop
150: //
151: this.btnStop.Location = new System.Drawing.Point(111, 61);
152: this.btnStop.Name = "btnStop";
153: this.btnStop.Size = new System.Drawing.Size(88, 21);
154: this.btnStop.TabIndex = 5;
155: this.btnStop.Text = "Stop";
156: this.btnStop.UseVisualStyleBackColor = true;
157: this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
158: //
159: // openFileDialog1
160: //
161: this.openFileDialog1.FileName = "openFileDialog1";
162: this.openFileDialog1.FileOk += new System.ComponentModel.CancelEventHandler(this.openFileDialog1_FileOk);
163: //
164: // btnNewFile
165: //
166: this.btnNewFile.Location = new System.Drawing.Point(205, 61);
167: this.btnNewFile.Name = "btnNewFile";
168: this.btnNewFile.Size = new System.Drawing.Size(75, 23);
169: this.btnNewFile.TabIndex = 6;
170: this.btnNewFile.Text = "Open";
171: this.btnNewFile.UseVisualStyleBackColor = true;
172: this.btnNewFile.Click += new System.EventHandler(this.btnNewFile_Click);
173: //
174: // lblFile
175: //
176: this.lblFile.AutoSize = true;
177: this.lblFile.Location = new System.Drawing.Point(23, 30);
178: this.lblFile.Name = "lblFile";
179: this.lblFile.Size = new System.Drawing.Size(148, 13);
180: this.lblFile.TabIndex = 7;
181: this.lblFile.Text = "C:\\Windows\\Media\\ding.wav";
182: //
183: // label3
184: //
185: this.label3.AutoSize = true;
186: this.label3.Location = new System.Drawing.Point(23, 9);
187: this.label3.Name = "label3";
188: this.label3.Size = new System.Drawing.Size(63, 13);
189: this.label3.TabIndex = 8;
190: this.label3.Text = "Current File:";
191: //
192: // MainForm
193: //
194: this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
195: this.ClientSize = new System.Drawing.Size(292, 260);
196: this.Controls.Add(this.label3);
197: this.Controls.Add(this.lblFile);
198: this.Controls.Add(this.btnNewFile);
199: this.Controls.Add(this.btnStop);
200: this.Controls.Add(this.label2);
201: this.Controls.Add(this.label1);
202: this.Controls.Add(this.txtFreq);
203: this.Controls.Add(this.trackBar1);
204: this.Controls.Add(this.btnPlay);
205: this.Name = "MainForm";
206: this.Text = "Sound Frequency Changer";
207: ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
208: this.ResumeLayout(false);
209: this.PerformLayout();
210: 211: }212: #endregion
213: 214: /// <summary>
215: /// The main entry point for the application.
216: /// </summary>
217: [STAThread]218: static void Main()
219: {220: Application.Run(new MainForm());
221: } 222: 223: private void btnPlay_Click(object sender, System.EventArgs e)
224: { 225: 226: sound.Play(0, BufferPlayFlags.Looping);227: btnPlay.Enabled = false;
228: btnStop.Enabled = true;
229: } 230: 231: private void trackBar1_ValueChanged(object sender, EventArgs e)
232: { 233: txtFreq.Text = trackBar1.Value.ToString(); 234: sound.Frequency = trackBar1.Value;235: btnPlay.Enabled = true;
236: } 237: 238: private void btnNewFile_Click(object sender, EventArgs e)
239: {240: openFileDialog1.Filter = "wav files (*.wav)|*.wav|All files (*.*)|*.*";
241: openFileDialog1.ShowDialog(); 242: } 243: 244: private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
245: { 246: sound.Stop();247: btnPlay.Enabled = true;
248: btnStop.Enabled = false;
249: lblFile.Text = openFileDialog1.FileName;250: sound = new SecondaryBuffer(openFileDialog1.FileName, d, applicationDevice);
251: sound.Frequency = 0; //The default frequency
252: 253: } 254: 255: private void btnStop_Click(object sender, EventArgs e)
256: { 257: sound.Stop();258: btnStop.Enabled = false;
259: btnPlay.Enabled = true;
260: } 261: } 262: } 263: 264:
This will allow me to use a beam or phaser sound to create the appearance of strength applied on a element.
Monday, January 19, 2009
Dynamic Loading Expression Media Player Template and passing parameters by code
Following my previous post on How to pass parameters to the Expression MediaPlayer component by code, here is a solution that builds upon this post to Dynamicaly load the Media Player inside your app and pass parameters to it.
You can test loading of the player here. The source code can also be downloaded here.
The loading and costumization of the parameters is done like this:
// Download the Media Player using WebClient
private void downloadVideoPlayer()
{
WebClient downloader = new WebClient();
downloader.OpenReadCompleted += new OpenReadCompletedEventHandler(onDownloadVideoPlayerCompleted);
downloader.OpenReadAsync(new Uri("MediaPlayerTemplate.xap", UriKind.Relative));
lblLoadPlayer.Text = "Downloading Media Player";
}
// Once the Media Player is downloaded
private void onDownloadVideoPlayerCompleted(object sender, OpenReadCompletedEventArgs args)
{
try
{
string appManifest = new StreamReader(Application.GetResourceStream(new StreamResourceInfo(args.Result, null), new Uri("AppManifest.xaml",UriKind.Relative)).Stream).ReadToEnd();
XElement deploymentRoot = XDocument.Parse(appManifest).Root;
List<XElement> deploymentParts = (from assemblyParts in deploymentRoot.Elements().Elements()
select assemblyParts).ToList();
Assembly asm = null;
foreach (XElement xElement in deploymentParts)
{
string source = xElement.Attribute("Source").Value;
AssemblyPart asmPart = new AssemblyPart();
StreamResourceInfo streamInfo = Application.GetResourceStream(new StreamResourceInfo(args.Result, "application/binary"), new Uri(source, UriKind.Relative));
if (source == "MediaPlayerTemplate.dll")
{
asm = asmPart.Load(streamInfo.Stream);
}
else asmPart.Load(streamInfo.Stream);
}
MediaPlayerTemplate.Page myPlayer = asm.CreateInstance("MediaPlayerTemplate.Page") as MediaPlayerTemplate.Page;
Dictionary<string,string> dic = new Dictionary<string, string>();
dic.Add("autoplay", "true");
dic.Add("enablecaptions", "true");
dic.Add("muted", "false");
dic.Add("stretchmode", "0");
dic.Add("displaytimecode", "false");
dic.Add("playlist", "<playList><playListItems><playListItem title=\"\" description=\"\" mediaSource=\"silverlight.wmv\" adaptiveStreaming=\"False\" thumbSource=\"\" frameRate=\"23.9760431376968\" width=\"512\" height=\"284\" ><chapters><chapter position=\"11.256\" title=\"MYMARKER01\" /><chapter position=\"20.033\" thumbnailSource=\"silverlight_20.033.jpg\" title=\"Capitulo%201\" /><chapter position=\"45.585\" thumbnailSource=\"silverlight_45.585.jpg\" title=\"Chapter%202\" /><chapter position=\"58.646\" thumbnailSource=\"silverlight_58.646.jpg\" title=\"Chapter%203\" /><chapter position=\"72.199\" thumbnailSource=\"silverlight_72.199.jpg\" title=\"Chapter%204\" /></chapters></playListItem></playListItems></playList>");
myPlayer.StartUp(dic);
cnvMediaPlayer.Children.Add(myPlayer);
lblLoadPlayer.Text = "";
LayoutRoot.UpdateLayout();
}
catch (Exception e)
{
lblLoadPlayer.Text = "Download Error: " + e.Message;
}
}
If you download the source code you will need to create your own playlist that points to a a movie of your own and set the thumbnails and chapters as you wish. Check the following line of code inside VideoPlayerHoster, Page.xaml.cs
dic.Add("playlist", "<playList>...
The Dynamic loading was implemented by looking at these 2 posts:
http://www.silverlighthack.com/post/2008/09/29/Silverlight-2-(RC0-RTM)-Dynamic-Assembly-Loading.aspx
http://silverlight.net/learn/learnvideo.aspx?video=65687
Using Expression Encoder 2 MediaPlayer Templates in your application
Microsoft Expression Encoder 2 SP1 now includes a set of Silverlight 2 Output Templates:
After installing SP1 you'll have a some Silverlight 2 templates in "C:\Program Files\Microsoft Expression\Encoder 2\Templates\en".
The Templates use 2 controls that implement most of the logic that we need on our media apps: MediaPlayer and ExpressionPlayer. These controls take care of all basic media handling functionalities but also Video Marker handling, Chapters and chapter thumbnails, playlists, cpations, etc.
Out-of-the-box the templates can be hosted in a html or aspx page and the parameters passed when loading the XAP. Here is the html of the page that is created when running your template:
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="MediaPlayerTemplate.xap"/>
<param name="onerror" value="onSilverlightError" />
<param name="initparams" value='autoplay=<$=TemplateParameter.AutoPlay$>,autoload=<$=TemplateParameter.AutoLoad$>,enablecaptions=<$=TemplateParameter.EnableCaptions$>,muted=<$=TemplateParameter.Muted$>,stretchmode=<$=TemplateParameter.StretchMode$>,displaytimecode=<$=TemplateParameter.DisplayTimecode$>,playlist=<$=PlayListParam(TemplateParameter.AllowedCodecs)$>' />
All customization is made via the initparams.If you want to use the MediaPlayer inside your own Silverlight application (that happens to use a media player) you need to make same changes in order to pass the parameters by code and not by the initparams of the silverlight object command in HTML as the template does.
When Silverlight loads the XAP via HTML it calls:
public Page(object sender, StartupEventArgs e)
{InitializeComponent();
myPlayer.OnStartup(sender, e);
}
Since you cannot create a StartupEventArgs class because it is marked as internal we need another way to pass our parameters from code.
Here are the changes:
1. In ExpressionPlayerControl.cs change the OnStartup method to receive a Dictionary<string, string> instead of StartupEventArgs:
public override void OnStartup(object sender, StartupEventArgs e)
replace by
public override void OnStartup(object sender, Dictionary<string, string> e)
2. Inside the OnStartup method replace "e.InitParams" for InitParams.
3. Since ExpressionPlayer derives from MediaPlayer and OnStartup is overrided we also need to update the OnStartup method in MediaPayer.cs:
public override void OnStartup(object sender, StartupEventArgs e)
replace by
public override void OnStartup(object sender, Dictionary<string, string> e)
4. Since you changed the method signature you also need to update the call to it on Page.xaml.cs and cast it to Dictionary<string, string>:
public Page(object sender, StartupEventArgs e)
{InitializeComponent();
myPlayer.OnStartup(sender, (Dictionary<string, string>) e.InitParams);
}
5. Create a new method that will allow your code to costumize the player:
public void StartUp(Dictionary<string, string> InitParams)
{ myPlayer.OnStartup(this, InitParams);}
6. Now you are ready to costumize your mediaplayer from code:
1: MediaPlayerTemplate.Page myPlayer = asm.CreateInstance("MediaPlayerTemplate.Page") as MediaPlayerTemplate.Page;
2: Dictionary<string,string> dic = new Dictionary<string, string>();
3: dic.Add("autoplay", "true");
4: dic.Add("enablecaptions", "true");
5: dic.Add("muted", "false");
6: dic.Add("stretchmode", "0");
7: dic.Add("displaytimecode", "false");
8: dic.Add("playlist", "<playList><playListItems><playListItem title=\"\" description=\"\" mediaSource=\"silverlight.wmv\" adaptiveStreaming=\"False\" thumbSource=\"\" frameRate=\"23.9760431376968\" width=\"512\" height=\"284\" ><chapters><chapter position=\"11.256\" title=\"MYMARKER01\" /><chapter position=\"20.033\" thumbnailSource=\"silverlight_20.033.jpg\" title=\"Capitulo%201\" /><chapter position=\"45.585\" thumbnailSource=\"silverlight_45.585.jpg\" title=\"Chapter%202\" /><chapter position=\"58.646\" thumbnailSource=\"silverlight_58.646.jpg\" title=\"Chapter%203\" /><chapter position=\"72.199\" thumbnailSource=\"silverlight_72.199.jpg\" title=\"Chapter%204\" /></chapters></playListItem></playListItems></playList>");
9: 10: myPlayer.StartUp(dic);(assuming myPlayer was defined in your Xaml)
Saturday, December 13, 2008
Host Deep Zoom project on Silverlight Streaming
It doesn't seem possible at first because the interface asks you to upload only the xap file. So ... where do we put the images ? You just need to do some "magic" as explained here
Here is a sample project hosted there.
Unexpected browser crash with Silverlight 2
It seems there is an issue mixing ScaleTransform and MultiScaleImage control as also posted on the Silverlight Forums
The Application that has this problem is this one when you enable the checkbox useScaleTransform, but with a different Deep Zoom output. with the one shown here does not seem to reproduce the problem :(
Here is the entry on the event viewer:
Faulting application IEXPLORE.EXE, version 7.0.6000.16764, time stamp 0x48f6a2ed, faulting module ntdll.dll, version 6.0.6000.16386, time stamp 0x4549bdf8, exception code 0xc0000029, fault offset 0x000675fc, process id 0xf18, application start time 0x01c95d5ad4de2d60.
