Click here to Skip to main content
Click here to Skip to main content

Windows Media Audio compressor

By , 8 Apr 2004
 

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:

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:

m_Writer = new WaveWriter(WaveFile, Format);

Which may be changed to:

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.

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

About the Author

Idael Cardoso
Web Developer
France France
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMedia Player make reader files fastermemberOmar.Pessoa21 Jul '08 - 8:04 
Hi, i am a braziliam developer. I have an application that read a lot of files, when i open the Windows Media Player my application go faster than normal.
 
Do you know why? A windows buffer for files? How to implement this?
 
Thanks.
 
Omar - VC++ Programmer

GeneralUnable to compile (48 errors)memberasp-1236 Dec '07 - 2:21 
I'm getting the following problems when I try compiling yeti.wmf:
 
Error 1 error C3816: 'class W' was previously declared or defined with a different managed modifier c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Utility.h 53
Error 2 error C3149: 'W' : cannot use this type here without a top-level '*' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Utility.h 54
Error 3 error C2993: 'W' : illegal type for non-type template parameter '__formal' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Utility.h 54
Error 4 error C2061: syntax error : identifier 'W' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Utility.h 57
Error 5 error C2061: syntax error : identifier 'W' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Utility.h 73
Error 6 error C2143: syntax error : missing ';' before '*' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Utility.h 92
Error 7 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Utility.h 92
Error 8 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Utility.h 93
Error 10 error C3451: 'uuid': cannot apply unmanaged attribute to 'IManBuffer' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 18
Error 11 error C2975: 'ManWrapper' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 38
Error 12 error C2955: 'ManWrapper' : use of class template requires template argument list c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 38
Error 13 error C2512: 'ManWrapper' : no appropriate default constructor available c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 41
Error 14 error C2326: 'HRESULT CBuffer::GetManBuffer(void **)' : function cannot access 'ManWrapper::m_IntfHandle' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 53
Error 15 error C2662: 'ManWrapper::GetIntf' : cannot convert 'this' pointer from 'CBuffer' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 64
Error 16 error C2662: 'ManWrapper::GetIntf' : cannot convert 'this' pointer from 'CBuffer' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 69
Error 17 error C2662: 'ManWrapper::GetIntf' : cannot convert 'this' pointer from 'CBuffer' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 74
Error 18 error C2662: 'ManWrapper::GetIntf' : cannot convert 'this' pointer from 'CBuffer' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 79
Error 19 error C2662: 'ManWrapper::GetIntf' : cannot convert 'this' pointer from 'CBuffer' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 84
Error 20 error C2975: 'ManWrapper' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 96
Error 21 error C2955: 'ManWrapper' : use of class template requires template argument list c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 96
Error 22 error C2662: 'ManWrapper::QueryInterface' : cannot convert 'this' pointer from 'CBuffer' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 96
Error 23 error C2975: 'ManWrapper' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 101
Error 24 error C2955: 'ManWrapper' : use of class template requires template argument list c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 101
Error 25 error C2662: 'ManWrapper::AddRef' : cannot convert 'this' pointer from 'CBuffer' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 101
Error 26 error C2975: 'ManWrapper' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 105
Error 27 error C2955: 'ManWrapper' : use of class template requires template argument list c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 105
Error 28 error C2662: 'ManWrapper::Release' : cannot convert 'this' pointer from 'CBuffer' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\Buffer.h 105
Error 29 error C2975: 'ManWrapper' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\WriterSink.h 25
Error 30 error C2955: 'ManWrapper' : use of class template requires template argument list c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\WriterSink.h 26
Error 31 error C2512: 'ManWrapper' : no appropriate default constructor available c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\WriterSink.h 28
Error 32 error C2662: 'ManWrapper::GetIntf' : cannot convert 'this' pointer from 'CWriterSink' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\WriterSink.h 33
Error 33 error C2662: 'ManWrapper::GetIntf' : cannot convert 'this' pointer from 'CWriterSink' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\WriterSink.h 38
Error 34 error C2662: 'ManWrapper::GetIntf' : cannot convert 'this' pointer from 'CWriterSink' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\WriterSink.h 43
Error 35 error C2662: 'ManWrapper::GetIntf' : cannot convert 'this' pointer from 'CWriterSink' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\WriterSink.h 48
Error 36 error C2662: 'ManWrapper::GetIntf' : cannot convert 'this' pointer from 'CWriterSink' to 'ManWrapper &' c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\WriterSink.h 53
Error 37 error C2660: 'ManWrapper::Create' : function does not take 2 arguments c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\yeti.WmaWriter.h 49
Error 38 error C2660: 'ManWrapper::Create' : function does not take 2 arguments c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\yeti.WmaWriter.h 148
Error 39 error C3867: 'WmaUserCtrls::EditWmaWriter::editFormat1_ConfigChange': function call missing argument list; use '&WmaUserCtrls::EditWmaWriter::editFormat1_ConfigChange' to create a pointer to member c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\EditWmaWriter.h 177
Error 40 error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s) c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\EditWmaWriter.h 177
Error 41 error C3867: 'WmaUserCtrls::EditWmaWriter::comboBoxProfiles_SelectionChangeCommitted': function call missing argument list; use '&WmaUserCtrls::EditWmaWriter::comboBoxProfiles_SelectionChangeCommitted' to create a pointer to member c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\EditWmaWriter.h 204
Error 42 error C3350: 'System::EventHandler' : a delegate constructor expects 2 argument(s) c:\temp\wmacompressor\wmacompressor\mmedia\yeti.wmf\EditWmaWriter.h 204
Error 43 Type 'WmaUserCtrls.EditWmaWriter' is not defined. C:\temp\WMACompressor\WMACompressor\MMedia\WmaCompress\Config.vb 35 39 WmaCompress
Error 44 Type 'WmaUserCtrls.EditWmaWriter' is not defined. C:\temp\WMACompressor\WMACompressor\MMedia\WmaCompress\Config.vb 41 29 WmaCompress
Error 46 Type 'WmaWriterConfig' is not defined. C:\temp\WMACompressor\WMACompressor\MMedia\WmaCompress\Form1.vb 197 20 WmaCompress
Error 47 Type 'WmaWriterConfig' is not defined. C:\temp\WMACompressor\WMACompressor\MMedia\WmaCompress\Form1.vb 202 16 WmaCompress
Error 49 Type 'WmaWriterConfig' is not defined. C:\temp\WMACompressor\WMACompressor\MMedia\WmaCompress\Form1.vb 207 21 WmaCompress
Error 53 Type 'WmaWriter' is not defined. C:\temp\WMACompressor\WMACompressor\MMedia\WmaCompress\Form1.vb 260 24 WmaCompress

QuestionMany many problems when i buildmemberIbrahim Dwaikat3 Nov '07 - 13:11 
Hi
 
I am using VS 2005
 
when I Compile it gives me these errors:
 
Error 1 fatal error C1083: Cannot open include file: 'wmsdk.h': No such file or directory
 
Error 2 Invalid Resx file. Could not load file or assembly 'file:///d:\windows media audio compressor\wmacompressor\wmacompressor\mmedia\debug\yeti.wmf.dll' or one of its dependencies. The system cannot find the file specified.
 
Error 3 Type 'WmaUserCtrls.EditWmaWriter' is not defined.
 
Error 4 Type 'WmaUserCtrls.EditWmaWriter' is not defined.
 
Error 6 Type 'WmaWriterConfig' is not defined
 
Error 7 Type 'WmaWriterConfig' is not defined
 

 
what is the solution please
 
Visit Me
 
www.engibrahim.tk

GeneralRuntime error under windows 2000 promemberahmedoofRashadvich15 Mar '06 - 4:00 
Hi,
first i'd like to thank you about sharing this great project it's very helpful.
Second the error:
When i tried to run the module of Wav to WMA compressor under Windows 2000 pro. with the first configuration option
"Audio low bit rate voice-oriented content (6.5 kbps)", I got this runtime error
"The process can't access the file (the file path) because it's being used by another process".
I can't find any reason specially it's working greatly with Windows XP pro.
I'll be very pleased, if you help me to solve this error.
Thanks.

 
A.M.R.
QuestionBad link in article?memberCodeStalker28 Feb '06 - 12:45 
Hello-
The link to the MP3 Compressor instead points to your article MP3 Ripper. I did locate the MP3 Compressor thru your profile / Articles submitted link though... Thanks for the good info.
 
JFischer
 
-- modified at 18:45 Tuesday 28th February, 2006
AnswerRe: Bad link in article?memberIdael Cardoso10 Mar '06 - 7:49 
You have right, I make a mistake when I posted the update for the article, the correct link is: C Sharp MP3 Compressor[^]
 
Thanks,
Idael.
GeneralCannot Compile under Releasememberkgoodrich1 Nov '05 - 7:57 
Has anyone had the problem with compiling under Release settings. I cannot seem to get the thing to compile and link under release settings. Anyone have any suggestions?????
 
Thanks,
Kendal
 
Kendal Goodrich
GeneralRe: Cannot Compile under ReleasememberIdael Cardoso30 Dec '05 - 8:22 
Try modifying yeti.wmf.vcproj as folows (Modifying WMF SDK directories according to your installation):
 
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
     ProjectType="Visual C++"
     Version="7.10"
     Name="yeti.wmf"
     ProjectGUID="{7FD21499-4A76-4314-B05A-D0B10CDC494A}"
     RootNamespace="yetiWmaWriter"
     Keyword="ManagedCProj">
     <Platforms>
          <Platform
               Name="Win32"/>
     </Platforms>
     <Configurations>
          <Configuration
               Name="Debug|Win32"
               OutputDirectory="$(SolutionDir)$(ConfigurationName)"
               IntermediateDirectory="$(ConfigurationName)"
               ConfigurationType="2"
               UseOfATL="0"
               ATLMinimizesCRunTimeLibraryUsage="FALSE"
               CharacterSet="1"
               ManagedExtensions="TRUE">
               <Tool
                    Name="VCCLCompilerTool"
                    Optimization="0"
                    AdditionalIncludeDirectories="..\WMSDK\WMFSDK9\include"
                    PreprocessorDefinitions="WIN32;_DEBUG"
                    MinimalRebuild="FALSE"
                    BasicRuntimeChecks="0"
                    RuntimeLibrary="1"
                    UsePrecompiledHeader="3"
                    WarningLevel="3"
                    DebugInformationFormat="3"/>
               <Tool
                    Name="VCCustomBuildTool"/>
               <Tool
                    Name="VCLinkerTool"
                    AdditionalDependencies="WMVCORE.lib"
                    ShowProgress="0"
                    OutputFile="$(OutDir)\$(ProjectName).dll"
                    LinkIncremental="2"
                    SuppressStartupBanner="TRUE"
                    AdditionalLibraryDirectories="..\WMSDK\WMFSDK9\lib"
                    GenerateDebugInformation="TRUE"
                    AssemblyDebug="1"
                    ResourceOnlyDLL="FALSE"/>
               <Tool
                    Name="VCMIDLTool"/>
               <Tool
                    Name="VCPostBuildEventTool"/>
               <Tool
                    Name="VCPreBuildEventTool"/>
               <Tool
                    Name="VCPreLinkEventTool"/>
               <Tool
                    Name="VCResourceCompilerTool"/>
               <Tool
                    Name="VCWebServiceProxyGeneratorTool"/>
               <Tool
                    Name="VCXMLDataGeneratorTool"/>
               <Tool
                    Name="VCWebDeploymentTool"/>
               <Tool
                    Name="VCManagedWrapperGeneratorTool"/>
               <Tool
                    Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
          </Configuration>
          <Configuration
               Name="Release|Win32"
               OutputDirectory="$(SolutionDir)$(ConfigurationName)"
               IntermediateDirectory="$(ConfigurationName)"
               ConfigurationType="2"
               UseOfATL="0"
               ATLMinimizesCRunTimeLibraryUsage="FALSE"
               CharacterSet="1"
               ManagedExtensions="TRUE">
               <Tool
                    Name="VCCLCompilerTool"
                    AdditionalIncludeDirectories="..\WMSDK\WMFSDK9\include"
                    PreprocessorDefinitions="WIN32;NDEBUG"
                    MinimalRebuild="FALSE"
                    ExceptionHandling="TRUE"
                    RuntimeLibrary="0"
                    UsePrecompiledHeader="3"
                    WarningLevel="3"
                    DebugInformationFormat="0"/>
               <Tool
                    Name="VCCustomBuildTool"/>
               <Tool
                    Name="VCLinkerTool"
                    AdditionalDependencies="WMVCORE.lib"
                    OutputFile="$(OutDir)\$(ProjectName).dll"
                    LinkIncremental="1"
                    AdditionalLibraryDirectories="..\WMSDK\WMFSDK9\lib"
                    IgnoreAllDefaultLibraries="FALSE"
                    GenerateDebugInformation="FALSE"
                    SubSystem="0"/>
               <Tool
                    Name="VCMIDLTool"/>
               <Tool
                    Name="VCPostBuildEventTool"/>
               <Tool
                    Name="VCPreBuildEventTool"/>
               <Tool
                    Name="VCPreLinkEventTool"/>
               <Tool
                    Name="VCResourceCompilerTool"/>
               <Tool
                    Name="VCWebServiceProxyGeneratorTool"/>
               <Tool
                    Name="VCXMLDataGeneratorTool"/>
               <Tool
                    Name="VCWebDeploymentTool"/>
               <Tool
                    Name="VCManagedWrapperGeneratorTool"/>
               <Tool
                    Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
          </Configuration>
     </Configurations>
     <References>
          <AssemblyReference
               RelativePath="mscorlib.dll"/>
          <AssemblyReference
               RelativePath="System.dll"/>
          <AssemblyReference
               RelativePath="System.Data.dll"/>
          <AssemblyReference
               RelativePath="System.Drawing.dll"/>
          <AssemblyReference
               RelativePath="System.Windows.Forms.dll"/>
          <AssemblyReference
               RelativePath="System.XML.dll"/>
          <ProjectReference
               ReferencedProjectIdentifier="{315EE7BF-EAE2-42C0-BFC6-CCA9160F3CFE}"
               Name="yeti.mmedia"/>
     </References>
     <Files>
          <Filter
               Name="Source Files"
               Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
               UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
               <File
                    RelativePath=".\AssemblyInfo.cpp">
               </File>
               <File
                    RelativePath=".\consts.cpp">
               </File>
               <File
                    RelativePath=".\EditWmaWriter.cpp">
               </File>
               <File
                    RelativePath=".\Profile.cpp">
               </File>
               <File
                    RelativePath=".\ProfileManager.cpp">
               </File>
               <File
                    RelativePath=".\Stdafx.cpp">
                    <FileConfiguration
                         Name="Debug|Win32">
                         <Tool
                              Name="VCCLCompilerTool"
                              UsePrecompiledHeader="1"/>
                    </FileConfiguration>
                    <FileConfiguration
                         Name="Release|Win32">
                         <Tool
                              Name="VCCLCompilerTool"
                              UsePrecompiledHeader="1"/>
                    </FileConfiguration>
               </File>
               <File
                    RelativePath=".\WmaWriter.cpp">
               </File>
               <File
                    RelativePath=".\WmaWriterProfile.cpp">
               </File>
               <File
                    RelativePath=".\yeti.WmaWriter.cpp">
               </File>
          </Filter>
          <Filter
               Name="Header Files"
               Filter="h;hpp;hxx;hm;inl;inc;xsd"
               UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
               <File
                    RelativePath=".\Buffer.h">
               </File>
               <File
                    RelativePath=".\consts.h">
               </File>
               <File
                    RelativePath=".\EditWmaWriter.h"
                    FileType="4">
                    <File
                         RelativePath=".\EditWmaWriter.resX">
                         <FileConfiguration
                              Name="Debug|Win32">
                              <Tool
                                   Name="VCManagedResourceCompilerTool"
                                   ResourceFileName="$(IntDir)/yetiwmf.EditWmaWriter.resources"/>
                         </FileConfiguration>
                         <FileConfiguration
                              Name="Release|Win32">
                              <Tool
                                   Name="VCManagedResourceCompilerTool"
                                   ResourceFileName="$(IntDir)/yetiwmf.EditWmaWriter.resources"/>
                         </FileConfiguration>
                    </File>
               </File>
               <File
                    RelativePath=".\Profile.h">
               </File>
               <File
                    RelativePath=".\ProfileManager.h">
               </File>
               <File
                    RelativePath=".\resource.h">
               </File>
               <File
                    RelativePath=".\Stdafx.h">
               </File>
               <File
                    RelativePath=".\Utility.h">
               </File>
               <File
                    RelativePath=".\WmaWriter.h">
               </File>
               <File
                    RelativePath=".\WmaWriterConfig.h">
               </File>
               <File
                    RelativePath=".\WmaWriterProfile.h">
               </File>
               <File
                    RelativePath=".\WriterSink.h">
               </File>
               <File
                    RelativePath=".\yeti.WmaWriter.h">
               </File>
          </Filter>
          <Filter
               Name="Resource Files"
               Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
               UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
               <File
                    RelativePath=".\app.ico">
               </File>
               <File
                    RelativePath=".\app.rc">
               </File>
          </Filter>
          <File
               RelativePath=".\ReadMe.txt">
          </File>
     </Files>
     <Globals>
          <Global
               Name="RESOURCE_FILE"
               Value="app.rc"/>
     </Globals>
</VisualStudioProject>

 
Regards,
Idael
GeneralWav to Wma Compressor using DMOsussWmaBoy12 May '05 - 22:50 
hi
I am looking for some help on writing some code which compresses a wav file to a wma file using Directshow media object. I do not want to creat the IWMSyncWriter as this is too slow. Any help would be highly appreciated
 
thanks
GeneralRe: Wav to Wma Compressor using DMOmemberIdael Cardoso3 Jul '05 - 5:35 
Hi,
I don't the example that you need but I think that won't be faster than using the Windows Media Format SDK because you would add another layer. Remember that Directshow filters uses WMF SDK to handle asf files.
 
Idael
GeneralCorrupted wma filesmemberGerardo Orozco2 May '05 - 21:31 
Hello Idael!
 
First of all, thanks for sharing this great piece of work! Big Grin | :-D
 
I have a question and hope you can point me in the right direction,
I'm using your WMA compressor code from a multithreaded application that is simultaneously compressing several realtime audio streams. I'm having certain problems after the number of concurrent threads with active wma compressor instances exceed a certain amount (after 4 or 5 compressor instances, I begin to experience corrupted wma files).
 
Perceptually, the files produced by these compressor instances seem to be OK, however, they are not seekable. Trying to seek a position gives me an Invalid File Type error message under WMP 9.
Also, trying to run a WMA repair utility on those files, virtually all data chunks are flagged as corrupt. I suspected that maybe the multiple threads were starving, but as it comes, the CPU load is low.
 
Have you tested your component in a multithreaded scenarios?
Do you have any suggestions ?
 
Thanks a lot in advance! Smile | :)

 
Gerardo Orozco
GeneralRe: Corrupted wma filesmemberIdael Cardoso3 Jul '05 - 5:28 
Hi,
There is important to note that the compression process is a processor intensive task, so one must take especial care in multithreading application more if some compressors are running at the same time.
 
When we use the IMWWriterAdvanced method to create asf file the obtained files have problem when we try to seek . I advise you to use my Windows Media SDK Translation[^] and create your asf files as recommended in the Windows Media SDK documentation. Another thing to do is re-index the compressed file, here you can find the code to do it: Mannaged WMF Samples[^]

 
Best regards,
Idael
QuestionHow to configure compression levelmemberfifthnormal27 Nov '04 - 16:20 
Hi!
 
Great program! I would like to know how change the level of compression used in the resulting file. I would like to have a better quality wma file produced. Do you know how?
 
Thanks,
 
Daniel
AnswerRe: How to configure compression levelmemberIdael Cardoso28 Nov '04 - 8:26 
Thanks,
 
In Windows Media technologies compression properties (quality, codec, bitrate, etc) and other configuration of ASF files are defined in a collection of data called Profile. To obtain a compressed file with a different quality you should use another profile whith the writer object. Look for Profile, Custom Profiles and System profiles in the Windows Media Format SDK documentation.
 
In the code showed in the article if you chage the line where writer is created by this one:
writer = New WmaWriter(New FileStream("SomeFile.wma", FileMode.Create), _
InStr.Format, _
WmaWriterProfileManager.AudioSystemProfiles(14))
 
You will obtain a 128 Kbs wma file better than CD quality. The previous code use the system profile MProfile_V80_128StereoAudio.
 
I advise to use the code of my article C Sharp Windows Media Format SDK Translation[^]
 
Regards,
Idael
GeneralRuntime errormemberVolen1 Nov '04 - 4:57 
Hi,
I use yeti.wmf in a C# application, but have some problems with it.
First of all I tried to make a setup for my application and install it in a non development environment. The installation was successful, but I get an error while trying to start the application shown in an "Common Language Runtime Debugging Services" dialog. The messages is:
"Application generated an exception that could not be handled...". The error occurs in both Debug and Release mode of the application. I found that the type of the exception is "TypeInitilizationException" and it is thrown before entering the Main function of the application. I think that it is caused by the yeti.wmf assembly because there were not any problems before adding this project to my solution.
There is a warning message while building the project:
"LINK : warning LNK4243: DLL containing objects compiled with /clr is not linked with /NOENTRY; image may not run correctly"
I supposed that this may cause the error at runtime. I tryed to rebuild the project with /NOENTRY but I got the following error:
"LIBCMTD.lib(crt0.obj) : error LNK2019: unresolved external symbol _main referenced in function _mainCRTStartup".
 
I'd like to bring into relief that the runtime error occurs only on a non development machine.
 
Do you have any idea about that problem? Your help will be appreciated!!
 
Jordan Jordanov
GeneralRe: Runtime errormemberIdael Cardoso11 Nov '04 - 6:56 
Hi,
Does your installation program install the Windows Media Format redistribution module (wmfredist.exe)? If the Windows Media Format is not installed in the target machine an application that use my code can not work.
 
In either case I advise you to use the code of my article Windows Media Format SDK translation, is more recent and all in c#.
 
Regards,
Idael
GeneralRe: Runtime errormemberVolen12 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 errormemberIdael Cardoso19 Nov '04 - 7:51 
Smart trick to avoid the warning Smile | :) But you can use the compiled library withour problem, the warning is due to the mixture of managed and unmanged code, of course I agree that is better to compile a code and to have a warning and error free compilation Smile | :)
 
Good luck,
Idael.
QuestionSkipping forward on a track??memberPeter Tewkesbury14 Sep '04 - 23:57 
Hi,
 
Firstly, thanks for the great s/w. Smile | :) Smile | :)
 
Secondly a question. When I copy a CD to hard disk using Windows Media Player 9, and then play the tracks, I can move forward, or backwards in the track, and it will play from the newly selected point in the track. However, if I copy a track using your library, and then play it using Windows Media Player 9, when I move forwards or backwards, and track always jumps back to the start of the track and plays from there. Also, I can not skip a track forward or backward.
 
Do you have any thoughts on these questions?? Confused | :confused:
 
Thanks again
 
Peter Tewkesbury
 
Peter Tewkesbury
Lead Developer

AnswerRe: Skipping forward on a track??memberIdael Cardoso16 Sep '04 - 5:28 
I have tested my code before but I already did after read your message and it worked for me. What I did to test is use the code from my article C Sharp Ripper and change the line:
private WaveWriter m_Writer = null; 
by
private AudioWriter m_Writer = null; 
and the line:
m_Writer = new WaveWriter(WaveFile, Format);
must be changed by:
m_Writer = new WmaWriter(WaveFile, Format);
Of course, a reference must be added in the CDCopier project to the yeti.wmf project. The resulting WMA files are correctly seek able (tested with WMP 9 and Winamp). While this code works I encourage to use the code from my article: C Sharp Windows Media SDK Translation. If you continue having the same problem you can give more details about your particular code to see if I can test and help you.

 
Regards,
Idael
GeneralRe: Skipping forward on a track??memberPeter Tewkesbury4 Oct '04 - 4:08 
Hi,
 
Sorry for the long delay, but I have been busy.
 
I am writing a small util which will copy a Audio CD to my PocketPC without the need to first RIP it onto the PC. Whilest the audio files that are created work on the PC, and you can move forward and back in the track on the PC, you can not do this on the Pocket PC. If I use Windows Media Player to Rip to the PC & then transfer the files to the Pocket PC, I can move forward & back in the track.
 
As far as I can tell the encoding used is the same. The only difference is that my Utility does not show the duration of the track correcly on the Pocket PC.
 
(I Disabled the DRM when RIPing the CD using Windows Media Player)
 
Do you have any ideas???
 
Peter Confused | :confused:
 

 
Peter Tewkesbury
Lead Developer
SecurityCentre PLC

GeneralRe: Skipping forward on a track??memberIdael Cardoso10 Oct '04 - 9:07 
Excuse me for answering so late: I had to ask a friend to help me to test with his Pocket PC because now I don’t have to test with.

The Windows Media player use a IWMWriterFileSink objects (note that IWMWriter.SetOuputFilename creates transparently a file sink object) when it compresses the data read from CD to obtain the WMA file. The writer sinks objects automatically add indexes to resulting file and those indexes are different when you use custom writer sinks (IWMWriterSink). As in my code I implemented a custom writer sink the resulting file is not suitable indexed and when is copied (and optionally converted by the ActiveSync) to the Pocket PC the seek feature in the device won’t as expected. The custom writer sink implementation is needed in order to write to compressed data to any System.IO.Stream, not only to files.
 
You have two solutions:
- Don’t use the WmaWriter class but create the IWMWriter and use the IWMWriter.SetOuputFilename method.
- Use the IWMIndexer object to create the correct index to a file compressed using the WmaWriter class. At http://icardoso.free.fr/projects/ManWMFSaples2.php you can find a code that shows how an ASF file could be indexing using the C# WMF SDK translation that I wrote.

 
Idael
GeneralRe: Skipping forward on a track??memberPeter Tewkesbury15 Oct '04 - 4:46 
Thanks for the information. I now have a working solution. Roll eyes | :rolleyes:
 
Can you tell me if there is any way of adding these indexes to the wma file using a .NET Stream class???

 
Peter Tewkesbury
Lead Developer

GeneralRe: Skipping forward on a track??memberIdael Cardoso17 Oct '04 - 23:54 
Using custom writer sinks is not possible to obtain a file indexed as you wish without re-indexing it after, so it is needed to use IWMFileWriterSink through the method IWMWriter.SetOutputFilename. If you want to implement BinaryWriter as I did in the class WmaWriter that creates the correct indexed file then you should compress the received data to a temporary file and override the Close method of the BinaryWriter to copy the compressed temporary file to the resulting Stream.
 
Idael
Generalcustom writer sinkmembergucki130826 Aug '04 - 22:10 
hi!
 
i'm trying to write a custom writer sink using the IWMWriterSink but it
doesn't work at all. could you please help me, best provide some simple
example code? also, how to i then create my customer writer sink object
so i can attach it to the writer using AddSink?
 
my current code looks like this:
--
class CMySink: public IWMWriterSink
{
public:
HRESULT STDMETHODCALLTYPE OnHeader(
/* [in] */ INSSBuffer *pHeader)
{
return S_OK;
}
 
HRESULT STDMETHODCALLTYPE IsRealTime(
/* [out] */ BOOL *pfRealTime)
{
return S_OK;
}
 
HRESULT STDMETHODCALLTYPE AllocateDataUnit(
/* [in] */ DWORD cbDataUnit,
/* [out] */ INSSBuffer **ppDataUnit)
{
return S_OK;
}
 
HRESULT STDMETHODCALLTYPE OnDataUnit(
/* [in] */ INSSBuffer *pDataUnit)
{
return S_OK;
}
 
HRESULT STDMETHODCALLTYPE OnEndWriting( void)
{
return S_OK;
}
// QueryInterface
STDMETHODIMP QueryInterface(REFIID refiid, void **ppv)
{
if(1 || refiid == IID_IUnknown)
{
*ppv = static_cast(this);
static_cast(this)->AddRef();
return S_OK;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
 
// AddRef
STDMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement((PLONG)&refCount_);
}
 
// Release
STDMETHODIMP_(ULONG) Release()
{
ULONG ul = 0;
if((ul = InterlockedDecrement((PLONG)&refCount_)) == 0)
{
delete this;
}
 
return ul;
}
 
ULONG refCount_;
};
--
 

to add the sink to the writer:
--
CMySink *pMySink = new CMySink;
IWMWriterSink *pSinkBase = NULL;
hr = pMySink->QueryInterface(IID_IWMWriterSink, ( void** ) &pSinkBase);
 
hr = pIWriter_->QueryInterface(IID_IWMWriterAdvanced, ( void** ) &pIWriterAdvanced_);
if (SUCCEEDED(hr))
{
pIWriterAdvanced_->AddSink(pSinkBase);
}
--
 
unluckily the program always crashes when calling the AddSink Frown | :-( . using
an interanl sink like IWriterSinkNetwork, it works fine...but i need my
custom sink *g*
 
thanks for any help!!

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 9 Apr 2004
Article Copyright 2004 by Idael Cardoso
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid