PDA

View Full Version : DirectSound from file?



M109uk
20-02-2003, 09:22 PM
Hi all,

i want to be able to read an MP3 or WAV file from with in a custom file which contains many files like a ZIP file, i can load the data ok for both and i can play WAV files using directsound from the data that a get but im not sure how to do this with MP3 files, at the moment i use the following code:



function PlayDirectSound(_Filename: String): Boolean;
var _hr : hResult;
_pPin : IPin;
_wFileName : array[0..(MAX_PATH*2)-1] of char;
_pFilterEnum : IEnumFilters;
_pFilterTemp : IBaseFilter;
_ppFiltersX : array[0..49] of IBaseFilter;
_iFiltCount, _iPos : integer;
_fetched : PULONG;
_llPos : Int64;
begin
// ---------
_pPin := NIL;

// Make sure that this file exists
// if GetFileAttributes(pChar(_filename)) = -1 then exit;

// Get filename in UNICODE
MultiByteToWideChar(CP_ACP, 0, pChar(_filename), -1, @_wFileName,
MAX_PATH);

// Add the new source filter to the graph.
// (Graph can still be running)
_hr := g_pGraphBuilder.AddSourceFilter(@_wFileName, @_wFileName,
g_pSourceNext);

// Get the first output pin of the new source filter. Audio sources
// typically have only one output pin, so for most audio cases
// finding any output pin is sufficient.
if not failed(_hr)
then _hr := g_pSourceNext.FindPin('Output', _pPin);

// Stop the graph
if not failed(_hr) then g_pMediaControl.Stop;

// Break all connections on the filters. You can do this by adding
// and removing each filter in the graph
if not failed(_hr) then
begin
_pFilterEnum := NIL;
_pFilterTemp := NIL;

_hr := g_pGraphBuilder.EnumFilters(_pFilterEnum);

if not failed(_hr) then
begin
_iFiltCount := 0;
_iPos := 0;

// Need to know how many filters. If we add/remove filters
// during the enumeration we'll invalidate the enumerator
while (_pFilterEnum.Skip(1) = S_OK) do inc(_iFiltCount);

// pull out all ...
_pFilterEnum.Reset;
_fetched := Nil;
while (_pFilterEnum.Next(1, _ppFiltersX[_iPos],
_fetched) = S_OK) do inc(_iPos);

if assigned(_pFilterEnum) then _pFilterEnum := NIL;

for _iPos := 0 to _iFiltCount-1 do
begin
g_pGraphBuilder.RemoveFilter(_ppFiltersX[_iPos]);

// Put the filter back, unless it is the old source
if &#40;_ppFiltersX&#91;_iPos&#93; <> g_pSourceCurrent&#41;
then g_pGraphBuilder.AddFilter&#40;_ppFiltersX&#91;_iPos&#93;, NIL&#41;;

if assigned&#40;_ppFiltersX&#91;_iPos&#93;&#41;
then _ppFiltersX&#91;_iPos&#93; &#58;= NIL;
end;
end;
end;

// We have the new ouput pin. Render it
if not failed&#40;_hr&#41; then
begin
_hr &#58;= g_pGraphBuilder.Render&#40;_pPin&#41;;
g_pSourceCurrent &#58;= g_pSourceNext;
g_pSourceNext &#58;= NIL;
end;

if assigned&#40;_pPin&#41; then _pPin &#58;= NIL;
if assigned&#40;g_pSourceNext&#41; then g_pSourceNext &#58;= NIL;

// Re-seek the graph to the beginning
if not failed&#40;_hr&#41; then
begin
_llPos &#58;= 0;
_hr &#58;= g_pMediaSeeking.SetPositions&#40;
_llPos, AM_SEEKING_AbsolutePositioning,
_llPos, AM_SEEKING_NoPositioning&#41;;
end;

// Start the graph
if not failed&#40;_hr&#41; then g_pMediaControl.Run;

// Release the old source filter.
if assigned&#40;g_pSourceCurrent&#41; then g_pSourceCurrent &#58;= NIL;

// All right.
Result &#58;= true;
end;


is their some other procedures/functions that i can use to give DirectSound the data myself or something?!?

Thanx for any help
Nic

Clootie
20-02-2003, 10:14 PM
To play MP3 fileswith DirectX interfaces you are forced to use DirectSHow (like you are doing currently). There is no easy and stright way of streaming custom data from memory instead of file. You have to implement you own source filter.
So probably easiest way for you is to create unzip music to temporary file on HD and play if from were as before.

PS. Way better feedback on DirectShow in Delphi you can get at http://www.progdigy.com.

M109uk
20-02-2003, 10:19 PM
Ok thanks,
i will have another look around :)