i'm able to produce 2 tones through one playerindex variable (& one inindex variable), via left & right channels...but i need more than 2 tones at once.
i turned playerindex & inindex into arrays [0..15]. each of these 16 voices work normally in itself, but as soon as i ask to sound a second one, the previous one turns silent. how can i get more than 1 of these 16 voices to sound at once? (thank you!) |
Administrator
|
Hello and welcome to uos forum.
Not sure to understand, It would be easier if you could give the code that you used. To play more than 2 tones at once you may create a player for each tone, assign with uos_AddFromSynth for each player and then play all the players together. Something like this: // Create the players: uos_CreatePlayer(PlayerIndex1); inindex1 := uos_AddFromSynth(PlayerIndex1, -1, -1, -1, 420, 420, -1, -1, -1, -1, -1, 0, -1, -1, -1); uos_AddIntoDevOut(PlayerIndex1, -1, -1, -1, -1, 0, -1, -1) uos_CreatePlayer(PlayerIndex2); inindex2 := uos_AddFromSynth(PlayerIndex2, -1, -1, -1, 600, 600, -1, -1, -1, -1, -1, 0, -1, -1, -1); uos_AddIntoDevOut(PlayerIndex2, -1, -1, -1, -1, 0, -1, -1) uos_CreatePlayer(PlayerIndex3); inindex3 := uos_AddFromSynth(PlayerIndex3, -1, -1, -1, 800, 800, -1, -1, -1, -1, -1, 0, -1, -1, -1); uos_AddIntoDevOut(PlayerIndex3, -1, -1, -1, -1, 0, -1, -1) // Play all the players together: uos_Play(PlayerIndex1); uos_Play(PlayerIndex2); uos_Play(PlayerIndex3); --------------------------- You may try the consolesynth.pas as demo ( but it is for only one sound). Fre;D |
Administrator
|
Re-hello.
It depends of your sound card but it is possible that, if you use lot of players, to have some distortion. If it is the case, try to use a lower sample rate at creating each player, for example 10025 (in place of default 44100) and so the value for example A/La =440/4 = 110. |
well, i tried to conform better to your example. now i only get sound for the first 4 tones in the series--the remaining 12 are silent.
here is the source (adapted from 1 of the examples): _____ program synth2morevoices; {$mode objfpc}{$H+} {$DEFINE UseCThreads} uses {$IFDEF UNIX} cthreads, {$ENDIF} Classes, SysUtils, CustApp, uos_flat; type TuosConsole = class (TCustomApplication) private procedure ConsolePlay; protected procedure doRun; override; public constructor Create (TheOwner: TComponent); override; end; var i, res : integer; ordir, opath, PA_FileName: string; PlayerIndex, inindex : array [0..15] of integer; freq, freqinc : real; {TuosConsole} procedure TuosConsole.ConsolePlay; begin ordir := IncludeTrailingBackslash (ExtractFilePath (ParamStr (0))); {$IFDEF Windows} {$if defined(cpu64)} PA_FileName := ordir + 'lib\Windows\64bit\LibPortaudio-64.dll'; {$else} PA_FileName := ordir + 'lib\Windows\32bit\LibPortaudio-32.dll'; {$endif} {$ENDIF} {$if defined (CPUAMD64) and defined (linux )} PA_FileName := ordir + 'lib/Linux/64bit/LibPortaudio-64.so'; {$ENDIF} {$if defined (cpu86 ) and defined (linux )} PA_FileName := ordir + 'lib/Linux/32bit/LibPortaudio-32.so'; {$ENDIF} {$if defined (linux ) and defined (cpuarm )} PA_FileName := ordir + 'lib/Linux/arm_raspberrypi/libportaudio-arm.so'; {$ENDIF} {$if defined (linux ) and defined (cpuaarch64)} PA_FileName := ordir + 'lib/Linux/aarch64_raspberrypi/libportaudio_aarch64.so'; {$ENDIF} {$IFDEF freebsd} {$if defined(cpu64)} PA_FileName := ordir + 'lib/FreeBSD/64bit/libportaudio-64.so'; {$else} PA_FileName := ordir + 'lib/FreeBSD/32bit/libportaudio-32.so'; {$endif} {$ENDIF} {$IFDEF Darwin} {$IFDEF CPU32} opath := ordir; opath := copy(opath, 1, Pos('/UOS', opath) - 1); PA_FileName := opath + '/lib/Mac/32bit/LibPortaudio-32.dylib'; {$ENDIF} {$IFDEF CPU64} opath := ordir; opath := copy(opath, 1, Pos('/UOS', opath) - 1); PA_FileName := opath + '/lib/Mac/64bit/LibPortaudio-64.dylib'; {$ENDIF} {$ENDIF} // Load the libraries (here only portaudio is needed) // function uos_loadlib (PortAudioFileName, SndFileFileName, Mpg123FileName, Mp4ffFileName, FaadFileName, opusfilefilename:: PChar): LongInt; res := uos_LoadLib (PChar (PA_FileName), nil, nil, nil, nil, nil); writeln ('Result of loading (if 0 => ok ): ' + IntToStr (res)); writeln ((uos_getinfolibraries ())); if res = 0 then begin //// Create the player. //// PlayerIndex: from 0 to what your computer can do! //// If PlayerIndex exists already, it will be overwriten... for i := 0 to 15 do begin PlayerIndex [i] := 0; inindex [i] := -1; if uos_CreatePlayer (PlayerIndex [i]) then inindex [i] := uos_AddFromSynth (PlayerIndex [i], -1, -1, -1, 0.00001, 0.00001, -1, -1, -1, -1, -1, 0, -1, -1, -1); {function uos_AddFromSynth (PlayerIndex : cint32; Channels, WaveTypeL, WaveTypeR : integer; FrequencyL, FrequencyR, VolumeL, VolumeR : float; duration, NbHarmonics, EvenHarmonics, OutputIndex, SampleFormat, SampleRate, FramesCount: cint32): cint32; // Add a input from Synthesizer with custom parameters // Channels : default: -1 (2) (1 = mono, 2 = stereo) // WaveTypeL : default: -1 (0) (0 = sine-wave, 1 = square-wave, used for mono & stereo) // WaveTypeR : default: -1 (0) (0 = sine-wave, 1 = square-wave, used for stereo, ignored for mono) // FrequencyL : default: -1 (440 Hz) (Left frequency, used for mono) // FrequencyR : default: -1 (440 Hz) (Right frequency, used for stereo, ignored for mono) // VolumeL : default: -1 (= 1) (from 0 to 1) => volume left // VolumeR : default: -1 (= 1) (from 0 to 1) => volume right (ignored for mono) // Duration : default: -1 (= 1000) => duration in msec (0 = endless) // NbHarmonics : default: -1 (= 0) Number of Harmonics // EvenHarmonics: default: -1 (= 0) (0 = all harmonics, 1 = Only even harmonics) // OutputIndex : Output index of used output // -1: all output, -2: no output, other cint32 refer to // a existing OutputIndex // (if multi-output then OutName = name of each output separated by ';') // SampleFormat : default: -1 (0: Float32) (0: Float32, 1: Int32, 2: Int16) // SampleRate : delault: -1 (44100) // FramesCount : -1 default: 1024 // result : Input Index in array -1 = error} {$if defined(cpuarm) or defined(cpuaarch64)} // need a lower latency if uos_AddIntoDevOut (PlayerIndex [i], -1, 0.3, -1, -1, 0, -1, -1) > -1 then {$else} if uos_AddIntoDevOut (PlayerIndex [i], -1, -1 , -1, -1, 0, -1, -1) > -1 then {$endif} //// add a Output into device with custom parameters //////////// PlayerIndex: Index of a existing Player // result: -1 nothing created, otherwise Output Index in array begin /////// everything is ready, here we are, lets play it... uos_Play (PlayerIndex [i]); // uos_InputSetSynth (PlayerIndex [i], inindex [i], -1, -1, 0.00001, 0.00001, -1, -1, 0, -1, -1, True); {procedure InputSetSynth (InputIndex : cint32; WaveTypeL, WaveTypeR : integer; FrequencyL, FrequencyR, VolumeL, VolumeR: float; duration, NbHarmonic, EvenHarmonics : cint32; Enable : boolean); // InputIndex : one existing input index // WaveTypeL : do not change: -1 (0 = sine-wave, 1 = square-wave, used for mono & stereo) // WaveTypeR : do not change: -1 (0 = sine-wave, 1 = square-wave, used for stereo, ignored for mono) // FrequencyL : do not change: -1 (Left frequency, used for mono) // FrequencyR : do not change: -1 (440 Hz) (Right frequency, used for stereo, ignored for mono) // VolumeL : do not change: -1 (= 1) (from 0 to 1) => volume left // VolumeR : do not change: -1 (from 0 to 1) => volume rigth (ignored for mono) // Duration : in msec (-1 = do not change) // NbHarmonic : Number of Harmonics (-1 not change) // EvenHarmonics: default: -1 (= 0) (0 = all harmonics, 1 = only even harmonics) // Enable : true or false} end; end; freq := 220; {A3} freqinc := freq; for i := 0 to 15 do begin writeln (i:2); uos_InputSetSynth (PlayerIndex [i], inindex [i], -1, -1, freq, freq, -1, -1, 1000, -1, -1, True); sleep (300); freq := freq + freqinc; end; sleep (600); for i := 0 to 15 do uos_stop (PlayerIndex [i]); writeln (IntToStr (GetCPUCount ())); sleep (900); end; end; procedure TuosConsole.doRun; begin ConsolePlay; uos_free; Terminate; end; constructor TuosConsole.Create (TheOwner: TComponent); begin inherited Create (TheOwner); StopOnException := True; end; var Application: TUOSConsole; begin Application := TUOSConsole.Create (nil); Application.Title := 'Console Synthesizer'; Application.Run; Application.Free; end. |
In reply to this post by fredvs
p.s. i'm on a pretty new lenovo laptop, running windows 11 (in case that helps re. sound card)
|
Administrator
|
Hello.
Try with this: program synth2morevoices; {$mode objfpc}{$H+} {$DEFINE UseCThreads} uses {$IFDEF UNIX} cthreads, {$ENDIF} Classes, SysUtils, CustApp, uos_flat; type TuosConsole = class (TCustomApplication) private procedure ConsolePlay; protected procedure doRun; override; public constructor Create (TheOwner: TComponent); override; end; var i, res : integer; ordir, opath, PA_FileName: string; PlayerIndex, inindex : array [0..15] of integer; freq, freqinc : real; {TuosConsole} procedure TuosConsole.ConsolePlay; begin ordir := IncludeTrailingBackslash (ExtractFilePath (ParamStr (0))); {$IFDEF Windows} {$if defined(cpu64)} PA_FileName := ordir + 'lib\Windows\64bit\LibPortaudio-64.dll'; {$else} PA_FileName := ordir + 'lib\Windows\32bit\LibPortaudio-32.dll'; {$endif} {$ENDIF} {$if defined (CPUAMD64) and defined (linux )} PA_FileName := ordir + 'lib/Linux/64bit/LibPortaudio-64.so'; {$ENDIF} {$if defined (cpu86 ) and defined (linux )} PA_FileName := ordir + 'lib/Linux/32bit/LibPortaudio-32.so'; {$ENDIF} {$if defined (linux ) and defined (cpuarm )} PA_FileName := ordir + 'lib/Linux/arm_raspberrypi/libportaudio-arm.so'; {$ENDIF} {$if defined (linux ) and defined (cpuaarch64)} PA_FileName := ordir + 'lib/Linux/aarch64_raspberrypi/libportaudio_aarch64.so'; {$ENDIF} {$IFDEF freebsd} {$if defined(cpu64)} PA_FileName := ordir + 'lib/FreeBSD/64bit/libportaudio-64.so'; {$else} PA_FileName := ordir + 'lib/FreeBSD/32bit/libportaudio-32.so'; {$endif} {$ENDIF} {$IFDEF Darwin} {$IFDEF CPU32} opath := ordir; opath := copy(opath, 1, Pos('/UOS', opath) - 1); PA_FileName := opath + '/lib/Mac/32bit/LibPortaudio-32.dylib'; {$ENDIF} {$IFDEF CPU64} opath := ordir; opath := copy(opath, 1, Pos('/UOS', opath) - 1); PA_FileName := opath + '/lib/Mac/64bit/LibPortaudio-64.dylib'; {$ENDIF} {$ENDIF} // Load the libraries (here only portaudio is needed) // function uos_loadlib (PortAudioFileName, SndFileFileName, Mpg123FileName, Mp4ffFileName, FaadFileName, opusfilefilename:: PChar): LongInt; res := uos_LoadLib (PChar (PA_FileName), nil, nil, nil, nil, nil); writeln ('Result of loading (if 0 => ok ): ' + IntToStr (res)); writeln ((uos_getinfolibraries ())); if res = 0 then begin //// Create the player. //// PlayerIndex: from 0 to what your computer can do! //// If PlayerIndex exists already, it will be overwriten... for i := 0 to 15 do begin if uos_CreatePlayer (i) then inindex [i] := uos_AddFromSynth (i, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1); {function uos_AddFromSynth (PlayerIndex : cint32; Channels, WaveTypeL, WaveTypeR : integer; FrequencyL, FrequencyR, VolumeL, VolumeR : float; duration, NbHarmonics, EvenHarmonics, OutputIndex, SampleFormat, SampleRate, FramesCount: cint32): cint32; // Add a input from Synthesizer with custom parameters // Channels : default: -1 (2) (1 = mono, 2 = stereo) // WaveTypeL : default: -1 (0) (0 = sine-wave, 1 = square-wave, used for mono & stereo) // WaveTypeR : default: -1 (0) (0 = sine-wave, 1 = square-wave, used for stereo, ignored for mono) // FrequencyL : default: -1 (440 Hz) (Left frequency, used for mono) // FrequencyR : default: -1 (440 Hz) (Right frequency, used for stereo, ignored for mono) // VolumeL : default: -1 (= 1) (from 0 to 1) => volume left // VolumeR : default: -1 (= 1) (from 0 to 1) => volume right (ignored for mono) // Duration : default: -1 (= 1000) => duration in msec (0 = endless) // NbHarmonics : default: -1 (= 0) Number of Harmonics // EvenHarmonics: default: -1 (= 0) (0 = all harmonics, 1 = Only even harmonics) // OutputIndex : Output index of used output // -1: all output, -2: no output, other cint32 refer to // a existing OutputIndex // (if multi-output then OutName = name of each output separated by ';') // SampleFormat : default: -1 (0: Float32) (0: Float32, 1: Int32, 2: Int16) // SampleRate : delault: -1 (44100) // FramesCount : -1 default: 1024 // result : Input Index in array -1 = error} {$if defined(cpuarm) or defined(cpuaarch64)} // need a lower latency uos_AddIntoDevOut (i, -1, 0.3, -1, -1, 0, -1, -1) ; {$else} uos_AddIntoDevOut (i, -1, 0.3 , -1, -1, 0, -1, -1) ; {$endif} end; freq := 220; {A3} freqinc := freq; for i := 0 to 15 do begin uos_InputSetSynth (i, 0, -1, -1, freq, freq, -1, -1, -1, -1, -1, True); sleep (300); writeln(i); uos_Play (i); freq := freq + freqinc; end; sleep (600); for i := 0 to 15 do uos_stop (i); writeln (IntToStr (GetCPUCount ())); sleep (900); end; end; procedure TuosConsole.doRun; begin ConsolePlay; uos_free; Terminate; end; constructor TuosConsole.Create (TheOwner: TComponent); begin inherited Create (TheOwner); StopOnException := True; end; var Application: TUOSConsole; begin Application := TUOSConsole.Create (nil); Application.Title := 'Console Synthesizer'; Application.Run; Application.Free; end. |
Administrator
|
In reply to this post by fredvs
Re-hello.
If you wan that all the players play together set the duration to 0 in uos_InputSetSynth, like this: uos_InputSetSynth (i, 0, -1, -1, freq, freq, -1, -1, 0, -1, -1, True); |
oh, lovely! that's beautiful!
now, at the end, the program doesn't exit |
wait, i'm wrong! it exited fine.
sir, thank you so much (for everything)! |
Free forum by Nabble | Edit this page |