Click here to Skip to main content
15,861,125 members
Articles / Programming Languages / Visual Basic
Article

Windows Media Audio compressor

Rate me:
Please Sign up or sign in to vote.
4.76/5 (25 votes)
8 Apr 20045 min read 301.5K   5K   106   44
Managed C++ Windows Media Audio (WMA) compressor.

Sample Image - Audio Compress

Introduction

As I mentioned in my previous article (C Sharp MP3 Compressor), I offer now a Windows Media Audio (WMA) compressor. This time I used managed C++ instead of C# in order to avoid the translation of interfaces and structures of the Windows Media Format SDK (WMF SDK). Microsoft has provided very limited managed support for their Windows Media SDKs (e.g. for the Windows Media Services SDK), but not for the WMF SDK. I think that Microsoft will logically include managed support for their WMF SDK in future versions, that's why I decided to avoid doing any translation. What I did was to create managed C++ classes that use some unmanaged classes, and have those unmanaged classes interact directly with the various Windows Media Format objects and interfaces.

In this work, there is code from the article A low level audio player in C# by Ianier Munoz.

Background

If you have never looked into the WMF SDK before, it is advisable that you take a look at the Windows Media Format SDK documentation for better understanding this article.

The following diagram represents the steps to create an Advanced Systems Format stream (ASF: the container format for Windows Media Audio and Windows Media Video-based content) using the WMF SDK:

Writing ASF Streams

Figure 1: Writing ASF Streams.

This diagram shows how to create ASF streams using a custom "Writer Sink". Custom writer sinks are needed for writing the resulting ASF stream to any kind of stream (in this case, any class derived from System.IO.Stream). As the diagram shows, the process is relatively simple. For more details about ASF creation, you can see Writing ASF Files and Using Custom Sinks in the Windows Media Format SDK documentation.

The compressor

The following figure is a simplified class diagram, which describes the managed version of the WMA compressor:

Windows Media Audio Compressor: Managed class diagram

Figure 2: Windows Media Audio Compressor: Managed class diagram.

The main class is WmaWriter, which interacts with the WMF SDK through unmanaged wrapper classes. It also acts as the sink object so the buffers received by its Write method are sent to the WMF writer object, which in turn sends back the compressed buffers through the sink interface. Finally, those buffers are written to the destination stream. WmaWriter receives the profile information through the class WmaWriterProfile, which represents the WMF IWMProfile.

WmaWriterProfileManger is a static class that contains some methods to handle profile creation and information. It also contains an array of WmaWriterProfile instances whose values represent the WMF System Profiles (audio only). This list of profiles should be enough for most purposes, but other profiles could also be created.

ManBuffer is a utility class for interfacing with the WMF SDK. It is just a managed implementation of buffer objects that implement INSSBuffer. Finally, ProfileManager is a utility class that creates and holds the WMF Profile Manager (IWMProfileManager).

If the WMF SDK was ported to managed code, this compressor could be implemented as shown in figure 2, with no more added complexity. Unfortunately, there is no such managed WMF SDK, therefore, some tricks and wrapper classes are necessary to implement the compressor. If you are interested in knowing the details, you can look at figure 3 in the implementation details section of this article.

Using the code

Using the WmaWriter is easy. You can use it in the same way you use BinaryWriter (WmaWriter is a specialization of BinaryWriter: see figure 2). The only difference with BinaryWriter is that you must indicate at creation time the format of the input data (data that the writer will receive) using a WaveFormat instance, and a profile defining the settings of the resulting compressed stream.

The following VB.NET code shows a simple way of compressing a WAV file using this compressor:

VB
Imports Yeti.MMedia
Imports Yeti.MMedia.Wmf
Imports WaveLib
Imports System.IO
....

  Dim InStr As WaveStream
  Dim writer As AudioWriter
  Dim buff() As Byte
  Dim read As Integer

  InStr = New WaveStream("SomeFile.wav")
  Try
    writer = New WmaWriter(New FileStream("SomeFile.wma", FileMode.Create), _
                          InStr.Format)
    'The previous line is equivalent to:
    'writer = New WmaWriter(New FileStream("SomeFile.wma", FileMode.Create), _
    '                       InStr.Format, _
    '                       WmaWriterProfileManager.AudioSystemProfiles(0))
    Try
      buff = New Byte(writer.OptimalBufferSize - 1) {}
      read = InStr.Read(buff, 0, buff.Length)
      While (read > 0)
        writer.Write(buff, 0, read)
        read = InStr.Read(buff, 0, buff.Length)
      End While
    Finally
      writer.Close()
    End Try
  Finally
    InStr.Close()
  End Try

I made the sample project in VB.NET just to please those who love VB. Anyway, you can use the compressor in C#, Managed C++, J# or any other CLS compliant language. The sample project of the MP3 compressor (also included in the source files) is written in C#. You can also refer to my C Sharp MP3 Compressor article.

Another example of using the writer could be an improved version of the ripper described in my article "C Sharp Ripper" to rip directly to WMA format. In the file Form1.cs, inside the handler of the "Save as.." button, there is the line:

C#
m_Writer = new WaveWriter(WaveFile, Format);

Which may be changed to:

C#
m_Writer = new WmaWriter(WaveFile, Format);

The rest of the code remains without change and, of course, if you need more control on the compressor parameters, then you should add extra code to supply a WmaWriterProfile instance in the constructor.

Implementation details

The figure below is a more complete class diagram of the compressor, showing the managed classes and interfaces and their relations with the WMF SDK interfaces.

Image 4

Figure 3: Windows Media Audio Compressor: implementation details.

I'm going to avoid the explanation of the implementation details. I just included the class diagram for those who want to see how this project was implemented and help them to better understand the code included with this article.

If you only want to use the compressor as is, then you can safely ignore these implementation details.

Conclusion

As showed here, the use of this compressor is relatively easy even if the implementation is somewhat complex due to interaction of managed and unmanaged code. There are some features of Windows Media Format that are not included in this project, such as DRM support, metadata attributes and two-pass encoding.

The sample code is given for demonstration purposes only, you can use it as reference if you need to develop some product with these technologies. When a managed version of WMF SDK is available, it will be easier to implement managed solutions using WMF. At the moment, this approach could be a good solution, considering that the unmanaged part can be suppressed without changing the design of managed part.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
France France
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionGetting the compiled DLL's only... Pin
jpope8-Aug-11 4:11
jpope8-Aug-11 4:11 
Generalis there a way to split a mp3 file into several mp3 files in c# Pin
lovethisgame5-Mar-11 14:18
lovethisgame5-Mar-11 14:18 
GeneralConverting from WMA to WAV Pin
sreeju.koothaduth2-Nov-10 3:48
sreeju.koothaduth2-Nov-10 3:48 
QuestionHow would you take the wma file and stream to a socket Pin
Douglas Jauregui31-Dec-09 9:42
Douglas Jauregui31-Dec-09 9:42 
Questionwindows media encoder 9 Pin
kayru25-Mar-09 22:27
kayru25-Mar-09 22:27 
AnswerRe: windows media encoder 9 Pin
kayru25-Mar-09 23:48
kayru25-Mar-09 23:48 
GeneralRe: windows media encoder 9 Pin
Douglas Jauregui31-Dec-09 9:38
Douglas Jauregui31-Dec-09 9:38 
QuestionRegarding License !! Pin
Nikhil_777718-Feb-09 8:33
Nikhil_777718-Feb-09 8:33 
GeneralConverting Mono Files Pin
shaktisinh28-Nov-08 18:35
shaktisinh28-Nov-08 18:35 
GeneralConvert wav to wma Pin
msurni30-Jul-08 20:22
msurni30-Jul-08 20:22 
GeneralMedia Player make reader files faster Pin
Omar.Pessoa21-Jul-08 8:04
Omar.Pessoa21-Jul-08 8:04 
GeneralUnable to compile (48 errors) Pin
asp-1236-Dec-07 2:21
asp-1236-Dec-07 2:21 
QuestionMany many problems when i build Pin
Ibrahim Dwaikat3-Nov-07 13:11
Ibrahim Dwaikat3-Nov-07 13:11 
GeneralRuntime error under windows 2000 pro Pin
ahmedoofRashadvich15-Mar-06 4:00
ahmedoofRashadvich15-Mar-06 4:00 
QuestionBad link in article? Pin
CodeStalker28-Feb-06 12:45
CodeStalker28-Feb-06 12:45 
AnswerRe: Bad link in article? Pin
Idael Cardoso10-Mar-06 7:49
Idael Cardoso10-Mar-06 7:49 
GeneralCannot Compile under Release Pin
kgoodrich1-Nov-05 7:57
kgoodrich1-Nov-05 7:57 
GeneralRe: Cannot Compile under Release Pin
Idael Cardoso30-Dec-05 8:22
Idael Cardoso30-Dec-05 8:22 
GeneralWav to Wma Compressor using DMO Pin
boy_in_washington12-May-05 22:50
boy_in_washington12-May-05 22:50 
GeneralRe: Wav to Wma Compressor using DMO Pin
Idael Cardoso3-Jul-05 5:35
Idael Cardoso3-Jul-05 5:35 
GeneralCorrupted wma files Pin
Member 17710042-May-05 21:31
Member 17710042-May-05 21:31 
GeneralRe: Corrupted wma files Pin
Idael Cardoso3-Jul-05 5:28
Idael Cardoso3-Jul-05 5:28 
QuestionHow to configure compression level Pin
fifthnormal27-Nov-04 16:20
fifthnormal27-Nov-04 16:20 
AnswerRe: How to configure compression level Pin
Idael Cardoso28-Nov-04 8:26
Idael Cardoso28-Nov-04 8:26 
GeneralRuntime error Pin
Volen1-Nov-04 4:57
Volen1-Nov-04 4:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.