Recent

Author Topic: [SOLVED] Operation with array of bytes  (Read 12331 times)

Fred vS

  • Hero Member
  • *****
  • Posts: 3939
    • StrumPract is the musicians best friend
Re: Operation with array of bytes
« Reply #15 on: November 16, 2012, 01:16:02 pm »
Ciao Amici.

I continue my fight...

What is wrong in that (audio) code ?

Code: [Select]

TUOSThread = class(TThread)
  private

  protected
    procedure Execute; override;
  public
   constructor Create(CreateSuspended: boolean);

  end;   
type
    TStreaminfo= record
   ///////////  here only few part of Tstreaminfo needed for example
    handle            : pointer;         
    thread : TUOSThread;
    SFoutbuf          : array [0..2047]  of byte  ;   
    volume           : double;
    BufFrames         : cardinal;   //// this for Windows 32 bit other systems need longint     
    OutFrames         : cardinal;   //// this for Windows 32 bit other systems need longint   
//////
end;         

var                ///// var outside the loop.

 UOSSTREAM            : array   of  Tstreaminfo;   

procedure TUOSThread.Execute;

  VAR
  x , x2  : integer  ;
    ValByte: Byte;  ////// to be sure the result is well in byte (only for debug)
  begin
 
 ////////////////////// init before the loop....
 
  x := 1 ;  ////for examlpe   

///////////////

  repeat        ///// The loop...

 if  (UOSSTREAM[x].handle <> nil)  then begin

    UOSSTREAM[x].OutFrames:=sf_read_short(UOSSTREAM[x].handle, @UOSSTREAM[x].SFoutbuf[0], UOSSTREAM[x].BufFrames  ) ;
   
///////////////////////////////////////// HERE THE PART OF PROBLEM
    if UOSSTREAM[x].volume <> 1 then
    begin
      x2 := 0 ;
   while (x2 < ( Length(UOSSTREAM[x].SFoutbuf) ) )  do begin

///////////////////// i use Valbyte to be sure that integer is well translated in byte by compiler (i know i do not have to, but it is for showing that my updated array is in byte....

     ValByte := round(UOSSTREAM[x].SFoutbuf[x2]*UOSSTREAM[x].volume);
  UOSSTREAM[x].SFoutbuf[x2]  := valbyte;

   inc(x2) ;
  end;
   end;
///////////////////////////////////////////////
 
    Pa_WriteStream(UOSSTREAM[x].Stream,@UOSSTREAM[x].SFoutbuf[0] ,Length(UOSstream[x].SFoutbuf) div 2) ; //////////////// here perfect if no volume change, otherwise noise and garbage...

 until  UOSSTREAM[x].Status = 0;

     end;

  end;
                         


 :-[
« Last Edit: November 16, 2012, 01:21:29 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

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Operation with array of bytes
« Reply #16 on: November 16, 2012, 01:35:30 pm »
BTW, if I omit the header, are you sure that the data are bytes ? More common is 16-bits-signed (smallint). It can also cause the problem ...
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Fred vS

  • Hero Member
  • *****
  • Posts: 3939
    • StrumPract is the musicians best friend
Re: Operation with array of bytes
« Reply #17 on: November 16, 2012, 01:44:52 pm »
Quote
BTW, if I omit the header, are you sure that the data are bytes ? More common is 16-bits-signed (smallint).

From SndFile Header :

Code: [Select]

type
  Psf_count_t  = ^Tsf_count_t;
  Tsf_count_t = off_t;     

var  sf_readf_short: function(sndfile : TSNDFILE_HANDLE; ptr : ctypes.pcshort; frames  : Tsf_count_t) : Tsf_count_t ; cdecl;

Pointer(sf_read_short):=DynLibs.GetProcedureAddress(sf_Handle,PChar('sf_read_short'));

« Last Edit: November 16, 2012, 01:48:32 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

Fred vS

  • Hero Member
  • *****
  • Posts: 3939
    • StrumPract is the musicians best friend
Re: Operation with array of bytes
« Reply #18 on: November 16, 2012, 01:56:19 pm »
After googling a while finded a example in C (but i do not speak C very well  :-X) and it seems to be the same idea...

Code: [Select]
if (fReduceVolume) {
int i;
int * out_ch1_ptr = (int*)out;
for (i = 0;i < (outputBytes / sizeof(float));++i) {
fptr[i] = (int)(fptr[i]*0.5);
}
}

SndFile is maybe the best audio openlib but it is also the most stingy for procedures and documentation...  :-X
« Last Edit: November 16, 2012, 02:14:36 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

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Operation with array of bytes
« Reply #19 on: November 16, 2012, 01:59:52 pm »
Firstly sound is unlikely to be in 8 bit.
And also I believe sound is Little Endian.

Here is some example code I've done that appears to work.

Code: [Select]
procedure TUOS_Stream.Play;
var
  frames,wantframes,framesize:integer;
  l:integer;
type
  TShortIntArray = array[0..$ffff] of Int16;
  PShortIntArray = ^TShortIntArray;
var
  pp:PShortIntArray;
begin
  framesize := 2 * fSndInfo.Channels;
  Pa_StartStream(stream) ;
  repeat
    wantframes := length(streambuf) div framesize;
    frames := sf_readf_short(fsndInfo.handle, @streamBuf[0], wantframes ) ;
    pp := @StreamBuf[0];
    for l := 0 to (frames*fSndInfo.Channels)-1 do // div fSndInfo.Channels do
      pp^[l] := NtoLE(round(LEtoN(pp^[l])*0.5));
    if frames > 0 then Pa_WriteStream(stream,@streamBuf[0], frames) ;
  until frames < wantframes;
end;


« Last Edit: November 16, 2012, 02:01:59 pm by KpjComp »

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Operation with array of bytes
« Reply #20 on: November 16, 2012, 02:07:58 pm »
@ From SndFile Header :
.....................

No, no, I'm talking about sound data. Consider this (lets talk in decimals):
You have value -1000 (as smallint, a signed 16-bit integer). So you need -500 after modifying volume.
But if you interpret is as two bytes, i.e. 11111100 & 00011000 then you after modifying volume obtain 01111110 & 00001100 which is 32268.
-500 and 32268 is that difference that may cause riot.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Fred vS

  • Hero Member
  • *****
  • Posts: 3939
    • StrumPract is the musicians best friend
Re: Operation with array of bytes
« Reply #21 on: November 16, 2012, 02:19:46 pm »
@ KpjComp, many thanks for your example.

But i do not see how you do to change the volume....
Ooops, ok, i see, you are still my hero...

May i use your code in U_OS and place you in first in the list of creator of U_OS ?


@ Blaazen.

OK, i see (more of less). I gonna work on that way, see you later...
« Last Edit: November 16, 2012, 02:24:33 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

Fred vS

  • Hero Member
  • *****
  • Posts: 3939
    • StrumPract is the musicians best friend
Re: Operation with array of bytes
« Reply #22 on: November 16, 2012, 02:39:07 pm »
@ Blaazen.

It seems also, if we see at KpjComp example, that the big guilty was the management of pointer  >:D...

Maaaaany thanks for the lights.

@ KpjComp : you are very impressive  :P

@ Blaazen : you as well  :P
« Last Edit: November 16, 2012, 03:00:01 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

Fred vS

  • Hero Member
  • *****
  • Posts: 3939
    • StrumPract is the musicians best friend
Re: [SOLVED] Operation with array of bytes
« Reply #23 on: November 16, 2012, 03:52:24 pm »
Quote
@ KpjComp : May i use your code in U_OS and place you in first in the list of creator of U_OS ?

Qui ne dit mot consent... (Silence is consent...).

Ok, many, many thanks and you are the brain of U_OS, claro.
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

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Operation with array of bytes
« Reply #24 on: November 16, 2012, 04:19:44 pm »
May i use your code in U_OS and place you in first in the list of creator of U_OS ?

Yes, sure.  Anything I post in forums anybody can use freely.

A mention in your list would be nice, but of course make sure your first in the list.  After all your doing most the work, I'm just helping here and there. 

I've also been playing with your lazdyn_* file's and looking at your U_OS.pas file to create a more OOP version I once mentioned to you.  I'm also using IInterface types, so that cross DLL/Development can be done easy.  eg, been able to call from say C#/Delphi/VB etc.  Once I've got to a stage that I believe is flexible, would you like to continue the project?

For an example of the code looks from an OOP pov->
Code: [Select]
  S1 := UOS.NewStream;
  S1.FileName := 'wav1.wav';
  S1.Play;

If say you then wanted to play a stream in the background, it would look like->
Code: [Select]
  S1 := UOS.NewStream;
  S1.FileName := 'music.ogg';
  S1.PlayMode := pmThreaded; //don't block
  S1.Play;

And because it's using IInterface it will also look after memory for you.  eg, in the above if there was no more reference to S1 and the file had finished playing, it would know to free itself.

For cross DLL boundary exception handling, I've also implemented an Exception Callback mechanism.  eg. If say the caller of the DLL did UOS.setExceptionHandlerCallback(self);  exception handling would then behave as expected, basically I've made sure all interface methods get wrapped into some like safecall logic, but better than safe call.  Rather than getting a SafeCall exception that's no use to anybody.

Fred vS

  • Hero Member
  • *****
  • Posts: 3939
    • StrumPract is the musicians best friend
Re: [SOLVED] Operation with array of bytes
« Reply #25 on: November 16, 2012, 09:59:03 pm »
Yeeeeep, i get you in the basket.  ;D

Quote
After all your doing most the work, I'm just helping here and there.

You have find ALL the solutions, without you that project is nothing.

Quote
looking at your U_OS.pas file to create a more OOP version I once mentioned to you

Whaaouw, with greatest pleasure...

Quote
would you like to continue the project?

This would be a great honor for me  :-[


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

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: [SOLVED] Operation with array of bytes
« Reply #26 on: November 17, 2012, 10:44:00 pm »
Quote
This would be a great honor for me

Great stuff, I believe I can hopefully create a nice framework to start from.  But I know I won't have a lot of time to maintain & enhance.

Having somebody like yourself with passion for this area will be great.  I'll see if I can get a nice framework up an running by the end of the week.

Also remember your U_OS.pas & lazdyn_*  has also been a good reference & resource for me too work from too, so the help is already working both ways.  IOW: without your lazdyn_* there would be no project, and I think a good sound library that can do OGG/MPG etc and enhanced things like DSP processing will be great for Lazarus.

Fred vS

  • Hero Member
  • *****
  • Posts: 3939
    • StrumPract is the musicians best friend
Re: [SOLVED] Operation with array of bytes
« Reply #27 on: November 17, 2012, 10:58:09 pm »
Quote
DSP processing

I gonna say the truth : i start that project to, finally, have access to this marvelous world : DSP. (Im musician)
Sadly, it seams to be the land of Gurus, only for C speakers.

It exists other Libraries like Bass, but the DSP section is very hard to understand.

Im wrong if i think that your procedure for adjust volume is a kind of DSP ?

If well, i get a foot in that world... ;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

Fred vS

  • Hero Member
  • *****
  • Posts: 3939
    • StrumPract is the musicians best friend
Re: [SOLVED] Operation with array of bytes
« Reply #28 on: November 19, 2012, 02:39:09 am »
Quote
And also I believe sound is Little Endian.

For those (like me  :-[ ) who are a little confused about "Little Endian" here a clear explanation :

http://support.sas.com/documentation/cdl/en/leforinforref/63324/HTML/default/viewer.htm#p11zyf4zlzyjxen1irusv289xrrb.htm
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

 

TinyPortal © 2005-2018