Recent

Author Topic: [SOLVED] UOS: play from TMemoryStream  (Read 14635 times)

Phoenix

  • Jr. Member
  • **
  • Posts: 87
[SOLVED] UOS: play from TMemoryStream
« on: February 28, 2017, 01:40:59 pm »
With UOS there a way to run a sound directly from a TMemoryStream without using the net or going to save a file.
I only saw
uos_AddFromFile (PlayerIndex1, (pchar (SoundFilename)));
but a function of the type
ms: TMemoryStream
uos_AddFromMStream (PlayerIndex1, ms);
or by passing the file extension if needed
uos_AddFromMStream (PlayerIndex1, ms, ext);
it's possible

Thanks, any help is appreciated  :)
« Last Edit: March 12, 2017, 10:59:45 am by Phoenix »

Fred vS

  • Hero Member
  • *****
  • Posts: 3158
    • StrumPract is the musicians best friend
Re: UOS: play from TMemoryStream
« Reply #1 on: February 28, 2017, 10:52:32 pm »
Hello.

It is possible to first load file into memory with uos_AddFromFile().

Then you may use  uos_PlayNoFree(), it will keep the file into memory even after uos_Stop().

Please, ask it to uos forum (http://uos.2369694.n4.nabble.com), you will receive more infos.

Fre;D
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: UOS: play from TMemoryStream
« Reply #2 on: March 01, 2017, 04:31:34 am »
@Fred vS
The answer to Phoenix's question is no.

You can not create a sound 'in memory' and then play it with UOS. You are always required to store it to disk first and then load it again using uos_AddFromFile().

TS probably want to do this, f.e. creating a in memory wav file, then play that. In that situation it seems a bit redundant to store things to disk first.

I only had a quick glance over the sources of UOS but hypothetically speaking does UOS not offer the possibility to (in the end) supply the data using a Pascal stream (whether it be a filestream or a memorystream) ?

Phoenix

  • Jr. Member
  • **
  • Posts: 87
Re: UOS: play from TMemoryStream
« Reply #3 on: March 01, 2017, 10:13:42 am »
@molly exactly, I have an encrypted data structure where I fetch the files and decode them. Everything happens in memory. So to me it is fundamental the use of TMemoryStream without writing anything. uos_AddFromFile () I can not use it. I saw that in "uos_libsndfile.pas" in addition to "sf_open ()" there is also "sf_open_virtual" I do not understand how to exploit it  %).
However also I follow the advice of Fred vS for the forum.
Thank you!!  :)

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: UOS: play from TMemoryStream
« Reply #4 on: March 01, 2017, 10:37:12 am »
@Phoenix:
Well spotted  :)

See here for the api call documentation:
Quote
Code: [Select]
SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) ;
Opens a soundfile from a virtual file I/O context which is provided by the caller. This is usually used to interface libsndfile to a stream or buffer based system. Apart from the sfvirtual and the user_data parameters this function behaves like sf_open.

With a lot of details added in the original documentation. Problem is, i also have no idea (*) how to exploit it (nor do i currently have the time to look into it).

(*) well the function itself opens up some possible scenario's but any implementation should also fit/match Fred's original work.

edit:
In the mean while you could perhaps have a look at the virtualio test example that accompanies libsndfile.
« Last Edit: March 01, 2017, 10:56:14 am by molly »

Phoenix

  • Jr. Member
  • **
  • Posts: 87
Re: UOS: play from TMemoryStream
« Reply #5 on: March 01, 2017, 11:03:21 am »
@molly thanks, I already posted on the forum Fred. Maybe it can find it interesting as a starting point for a new library functionality. For now I hope to find a solution  O:-)

(sorry for my English)

Phoenix

  • Jr. Member
  • **
  • Posts: 87
Re: UOS: play from TMemoryStream
« Reply #6 on: March 01, 2017, 11:36:16 am »
@molly I saw the sample file and it is a good starting point.
Thank you!!  :)

Fred vS

  • Hero Member
  • *****
  • Posts: 3158
    • StrumPract is the musicians best friend
Re: UOS: play from TMemoryStream
« Reply #7 on: March 01, 2017, 07:00:28 pm »
Quote
You can not create a sound 'in memory' and then play it with UOS.

Huh, did you try AddFromFileIntoMemory() form last commit 610ed5c..d12dca7 ?
This decodes a audio file and stores the result into a memory buffer.
That memory buffer will be used to play the sound.

Quote
, I have an encrypted data structure where I fetch the files and decode them. Everything happens in memory.
What kind of data ?
PCM already decoded?
Or all the raw audio file?

If PCM is already decoded, uos can do it.
If the file is stored into memory, this is not (AFAIK) something for uos but more a fpc challenge.

By the way, if your audio stream is big, you will need access to disk (virtual ram).

Fre;D
« Last Edit: March 01, 2017, 07:15:30 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: UOS: play from TMemoryStream
« Reply #8 on: March 01, 2017, 07:15:42 pm »
Quote
You can not create a sound 'in memory' and then play it with UOS.

Huh, did you try AddFromFileIntoMemory() form last commit 610ed5c..d12dca7 ?
This decodes a audio file and stores the result into a memory buffer.
That memory buffer will be used to play the sound.
Language barrier, i presume  :)

You can't do it without the (current) absolute necessity of storing your data (that is already a valid wav file in memory) to a file on disk first. The you need to load it again from file in order to play it from memory again.

Can you understand the redundancy better now ?  :)

Quote
If the file is stored into memory, this is not (AFAIK) something for uos but more a fpc challenge.
Challenge accepted and finished  :P

I can load and save to a Free Pascal TMemoryStream using the sf_open_virtual() function from libsndfile.

Now... are you up for the challenge to integrate this functionality in the uos library ?  ;-)

Fred vS

  • Hero Member
  • *****
  • Posts: 3158
    • StrumPract is the musicians best friend
Re: UOS: play from TMemoryStream
« Reply #9 on: March 01, 2017, 07:21:07 pm »
Quote
Can you understand the redundancy better now ?  :)

Huh, not perfectly.  :-[

Quote
I can load and save to a Free Pascal TMemoryStream using the sf_open_virtual() function from libsndfile.
Now... are you up for the challenge to integrate this functionality in the uos library ?  ;-)

Haaaa, that is what I love, constructive comment with solution.
And I will be very happy to integrate your challenge in uos and you in the list of great contributors.

Fre;D
« Last Edit: March 01, 2017, 07:23:15 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: UOS: play from TMemoryStream
« Reply #10 on: March 01, 2017, 07:26:10 pm »
@Fred vS
PM send

Huh, not perfectly.  :-[
No worries,. i try again.

Sometimes you have some mix (e.g. multiple channels mixed into one wav file that is created on the fly into memory) that you created yourself.

It is really an very inefficient method to first store that memory data to disk in a file and, then directly load it again (remember the perfect valid wav data is still in memory, because i just saved it to disk), then clear the memory that my wav data just used in order to make room, then load it from the file that i just saved to disk..... which delivers me the same wav data in memory again (the memory that i just cleared).

And, who knows (i am not that familiar with uos)... Perhaps it is possible to implement support for never ending streams this way, e.g. using buffered memory streams with a backend that create music on the fly (as said i have no idea if the libraries used in uos can handle such implementation)

edit:
Hmz, since there seem to be a language barrier, the above wouldn't help much either i guess. Maybe it helps with showing some code ?

Code: Pascal  [Select][+][-]
  1. program silly;
  2.  
  3. {$MODE OBJFPC}{$H+}
  4.  
  5. uses
  6.   Classes;
  7.  
  8. var
  9.   A : String = 'This is some data i would like to use';
  10.  
  11. Procedure OldAndPointless;
  12. var
  13.   S : TMemoryStream;
  14.   T : String;
  15. begin
  16.   S := TMemoryStream.Create;
  17.   S.WriteAnsiString(A);
  18.   S.SaveToFile('pointless.txt');
  19.   S.Free;
  20.  
  21.   S := TMemoryStream.Create;
  22.   S.LoadFromFile('pointless.txt');
  23.   S.Position := 0;
  24.   T := S.ReadAnsiString;
  25.   S.Free;
  26.  
  27.   WriteLn(T);  
  28. end;
  29.  
  30. procedure NewAndEfficient;
  31. var
  32.   S : TMemoryStream;
  33.   T : String;
  34. begin
  35.   S := TMemoryStream.Create;
  36.   S.WriteAnsiString(A);
  37.   S.Position := 0;
  38.   T := S.ReadAnsiString;
  39.   S.Free;
  40.  
  41.   WriteLn(T);  
  42. end;
  43.  
  44. begin
  45.   WriteLn('old:');
  46.   OldAndPointless;
  47.   WriteLn('new:');
  48.   NewAndEfficient;
  49. end.
  50.  

I'm probably quilty of the code above being bit biased but, i do hope yo get the gist of it.
« Last Edit: March 01, 2017, 09:09:45 pm by molly »

Phoenix

  • Jr. Member
  • **
  • Posts: 87
Re: UOS: play from TMemoryStream
« Reply #11 on: March 01, 2017, 10:47:14 pm »
@molly
Thanks for your time !!  :)
@Fred vS
Quote
What kind of data ?
Can be for example a Flac, Ogg, .. (those available through libsndfile)
Quote
PCM already decoded?
Or all the raw audio file?
A source to give the idea for test
Code: Pascal  [Select][+][-]
  1. Const
  2.  ext = '.flac';
  3.  path = 'c:\test'+ext; //!!! ONLY FOR SIMULATE
  4. Var
  5.  ms: TMemoryStream;
  6. begin
  7.  ms:= TMemoryStream.Create;
  8.  try
  9.   ms.LoadFromFile(path);
  10.  
  11.   (*  
  12.        WARNING:
  13.  
  14.        Now forget the const PATH: you have ONLY "ms" and "ext"
  15.        for execute sound
  16.   *)
  17.  
  18.  finally
  19.   ms.Free;
  20.  end;
  21. end;
  22.  

I saw the "AddFromFileIntoMemory ()" method just added but the problem is always the same that I have NO PATH. The audio files are ready to use it only in TMemoryStream.  ;D

As well as in my case, this function may be useful for those who use a game engine and use a unique data structure that contains all the sounds of the game.  :)

Thanks!!  :)

Fred vS

  • Hero Member
  • *****
  • Posts: 3158
    • StrumPract is the musicians best friend
Re: UOS: play from TMemoryStream
« Reply #12 on: March 02, 2017, 12:07:49 am »
Quote
And, who knows (i am not that familiar with uos)... Perhaps it is possible to implement support for never ending streams this way, e.g. using buffered memory streams with a backend that create music on the fly (as said i have no idea if the libraries used in uos can handle such implementation)

This is already implemented in uos.
Take a look at Multi-Input demo.
It gives the tips for a multi-channels layout.

Quote
A source to give the idea for test
Huh, what I see, is something for fpc, so it will be usable not only for flac, ogg or wav but also mp3, opus and custom format.
Something like: 

Code: Pascal  [Select][+][-]
  1. path := ConvertMemoryStreamIntoVirtualFile(ms);

Something more easy should be to store into the memory stream a buffer of float (array of float).
Then, yes uos can deal with it.

Fre;D

« Last Edit: March 02, 2017, 12:19:53 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 3158
    • StrumPract is the musicians best friend
Re: UOS: play from TMemoryStream
« Reply #13 on: March 02, 2017, 01:59:35 pm »
Hello.

Added in last commit d35cb28  AddFromMemory(...) to play from memory stream.

Fre;D
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: UOS: play from TMemoryStream
« Reply #14 on: March 02, 2017, 02:25:07 pm »
Quote
A source to give the idea for test
Huh, what I see, is something for fpc, so it will be usable not only for flac, ogg or wav but also mp3, opus and custom format.
Something like: 

Code: Pascal  [Select][+][-]
  1. path := ConvertMemoryStreamIntoVirtualFile(ms);

Something more easy should be to store into the memory stream a buffer of float (array of float).
Then, yes uos can deal with it.

Fre;D

The virtual file is not a general concept, and probably only applies to UOS or libraries that it uses. As such it doesn't belong in FPC, but in UOS or the header/libraries that it uses.

A different reason for needed memorystreams btw is the case of when the additional media are in resources. (I do that, but for pictures, not audio)

 

TinyPortal © 2005-2018