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.6K   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

 
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 
GeneralRe: Runtime error Pin
Idael Cardoso11-Nov-04 6:56
Idael Cardoso11-Nov-04 6:56 
GeneralRe: Runtime error Pin
Volen12-Nov-04 12:30
Volen12-Nov-04 12:30 
Hi,
Thanks for the reply.
Actually the problem was not caused by the code you wrote. Another module couldn't load additional native modules that where not described properly in its documentation. These modules are provided with VS.NET and the resolution was to add them to the Setup package.
The good news is that I realized to compile your code without warnings - you just have to include DllMain for your module and add /nodefaultlib compile switches for some of the libs included by the project.
So thaks again!

Regards,
Jordan
GeneralRe: Runtime error Pin
Idael Cardoso19-Nov-04 7:51
Idael Cardoso19-Nov-04 7:51 
QuestionSkipping forward on a track?? Pin
Peter Tewkesbury14-Sep-04 23:57
professionalPeter Tewkesbury14-Sep-04 23:57 
AnswerRe: Skipping forward on a track?? Pin
Idael Cardoso16-Sep-04 5:28
Idael Cardoso16-Sep-04 5:28 
GeneralRe: Skipping forward on a track?? Pin
Peter Tewkesbury4-Oct-04 4:08
professionalPeter Tewkesbury4-Oct-04 4:08 
GeneralRe: Skipping forward on a track?? Pin
Idael Cardoso10-Oct-04 9:07
Idael Cardoso10-Oct-04 9:07 
GeneralRe: Skipping forward on a track?? Pin
Peter Tewkesbury15-Oct-04 4:46
professionalPeter Tewkesbury15-Oct-04 4:46 
GeneralRe: Skipping forward on a track?? Pin
Idael Cardoso17-Oct-04 23:54
Idael Cardoso17-Oct-04 23:54 
Generalcustom writer sink Pin
gucki130826-Aug-04 22:10
gucki130826-Aug-04 22:10 
GeneralRe: custom writer sink Pin
Idael Cardoso3-Sep-04 6:05
Idael Cardoso3-Sep-04 6:05 
GeneralDecompressor Pin
vpantaleo30-Apr-04 23:24
vpantaleo30-Apr-04 23:24 
GeneralRe: Decompressor Pin
Idael Cardoso7-May-04 4:33
Idael Cardoso7-May-04 4:33 
QuestionUse the WMF in the smartphone 2003. OK? Pin
conan52013-Apr-04 19:44
conan52013-Apr-04 19:44 
AnswerRe: Use the WMF in the smartphone 2003. OK? Pin
Idael Cardoso15-Apr-04 3:25
Idael Cardoso15-Apr-04 3:25 
GeneralAppend WMA Files Pin
Veibert11-Apr-04 17:18
Veibert11-Apr-04 17:18 
GeneralRe: Append WMA Files Pin
Idael Cardoso11-Apr-04 23:00
Idael Cardoso11-Apr-04 23:00 
GeneralRe: Append WMA Files Pin
Idael Cardoso23-Apr-04 8:18
Idael Cardoso23-Apr-04 8:18 
GeneralHi TESt Pin
Shanghaier11-Apr-04 10:25
Shanghaier11-Apr-04 10:25 

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.