using 2 microphones

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
edf
Reply | Threaded
Open this post in threaded view
|

using 2 microphones

edf
Hi
I am trying to use 2 usb microphones writting to a file (on windows 11 home 64 bits).
each of the microphones work one at a time, but when you try to use both it does not work.

Error is

as soon as use 2 usb mics   /not enough controller resources. usb
the record stop  seems ok.
on application halt
gives raised exception class 'External: ACCESS VIOLATION' with message Access violation reading from address $FFFFFFFFFFF.

The directory of the file is
20/11/2023  11:31 AM                46 rec23_11_20_11_31_03.wav
46 bytes (46 bytes)
it  wont play

The code is based on the example simple recorder. My appologies if I have not understood the use of uos.
Using 1 PlayerIndex and uos_AddIntoFile(PlayerIndex1, PChar(FileSaveOutoutName), -1, -1, -1, 4096, outformat);
code snip (InDev1 =1, InDev2=2, which are devices found by devinfo.) Both work 1 at a time.

   PlayerIndex1 := 0;
    // PlayerIndex : from 0 to what your computer can do ! (depends of ram, cpu, ...)
    // If PlayerIndex exists already, it will be overwritten...

    uos_CreatePlayer(PlayerIndex1);
    //// Create the player.
    //// PlayerIndex : from 0 to what your computer can do !
    //// If PlayerIndex exists already, it will be overwriten...

    //uos_AddIntoFileFromMem(PlayerIndex1, Pchar(edit3.Text));
    //// add Output into wav file (save record) from TMemoryStream  with default parameters
    bwav := true; // make it simple
    wantSpeakerOut := False ; // no speaker . make it simple
    if bwav then
     begin
    outformatst := '.wav';
    outformat := 0;
    end else
    begin
    outformatst := '.ogg';
    outformat := 3;
    end;
    FileSaveOutoutName := FileSaveBaseName + 'rec' +  UTF8Decode(formatdatetime('YY_MM_DD_HH_mm_ss', now)) + outformatst ;


     // saving in a file using a File-Stream:

     uos_AddIntoFile(PlayerIndex1, PChar(FileSaveOutoutName), -1, -1, -1, 4096, outformat);

 //   function uos_AddIntoFile(PlayerIndex: cint32; Filename: PChar; SampleRate: cint32;
 // Channels: cint32; SampleFormat: cint32 ; FramesCount: cint32 ; FileFormat: cint32): cint32;
// Add a Output into audio wav file with custom parameters from TFileStream
// PlayerIndex : Index of a existing Player
// FileName : filename of saved audio wav file
// SampleRate : delault : -1 (44100)
// Channels : delault : -1 (2:stereo) (1:mono, 2:stereo, ...)
// SampleFormat : default : -1 (2:Int16) (1:Int32, 2:Int16)
// FramesCount : default : -1 (= 65536)
// FileFormat : default : -1 (wav) (0:wav, 1:pcm, 2:custom, 3:ogg);

    //// add Output into wav or ogg file (save record) from TFileStream

    // saving in a Memory-Buffer:
    // SetLength(thebuffer, 0);
    // uos_AddIntoMemoryBuffer(PlayerIndex1, @thebuffer);

    // saving in a Memory-Stream:
    // if thememorystream = nil then thememorystream := tmemorystream.create;
    // uos_AddIntoMemoryStream(PlayerIndex1, (thememorystream),-1,-1,-1,-1);

    // saving in a file using a Menory-Stream:
    // uos_AddIntoFileFromMem(PlayerIndex1, Pchar(filenameEdit4.filename));
    //// add Output into wav file (save record)  with default parameters

      {$if defined(cpuarm) or defined(cpuaarch64)}  // need a lower latency
    out1index := uos_AddIntoDevOut(PlayerIndex1, -1, 0.8, -1, -1, -1, -1) ;
       {$else}
    out1index := uos_AddIntoDevOut(PlayerIndex1);
       {$endif}

    uos_outputsetenable(PlayerIndex1, out1index, wantSpeakerOut);

     // uos_AddIntoDevOut(PlayerIndex1, -1, -1, 8000, -1, -1,65536, -1);   //// add a Output into device with custom parameters
    //////////// PlayerIndex : Index of a existing Player
    //////////// Device ( -1 is default Output device )
    //////////// Latency  ( -1 is latency suggested ) )
    //////////// SampleRate : delault : -1 (44100)
    //////////// Channels : delault : -1 (2:stereo) (0: no channels, 1:mono, 2:stereo, ...)
    //////////// SampleFormat : -1 default : Int16 : (0: Float32, 1:Int32, 2:Int16)
    //////////// FramesCount : -1 default : 65536
    // ChunkCount : default : -1 (= 512)
 // these are global variables setup in ini file
 // InDev1:               Integer;
 // InDev2:               Integer;

   useInDevDefault  := true; //default
   useInDev1 := (CheckBoxChan1.Checked) ;
   useInDev2 := (CheckBoxChan2.Checked) ;
   if ( useInDev1) then   useInDevDefault := false;
   if ( useInDev2) then   useInDevDefault := false;

   // we want useInDevDefault or one or both of   useInDev1  useInDev2
   if (useInDevDefault) then
   begin
        In1IndexD := uos_AddFromDevIn(PlayerIndex1);       // default
   end;

   if (useInDev1) then
   begin
         EditCh1.Text :=  InDev1.ToString;
         In1Index1 := uos_AddFromDevIn(PlayerIndex1, InDev1,-1,-1,-1,-1,-1,-1);
   end;
     if (useInDev2) then
   begin
         EditCh2.Text :=  InDev2.ToString;
         In1Index2 := uos_AddFromDevIn(PlayerIndex1, InDev2,-1,-1,-1,-1,-1,-1);
   end;

    //// add input from mic with custom parameters
    //////////// PlayerIndex : Index of a existing Player
    //////////// Device ( -1 is default Input device )
    //////////// Latency  ( -1 is latency suggested ) )
    //////////// SampleRate : delault : -1 (44100)
    //////////// OutputIndex : OutputIndex of existing Output // -1 : all output, -2: no output, other integer : existing output)
    //////////// SampleFormat : -1 default : Int16 : (0: Float32, 1:Int32, 2:Int16)
    //////////// FramesCount : -1 default : 4096   ( > = safer, < =  better latency )

    ////////// VolLeft : Left volume
    ////////// VolRight : Right volume
    volLeft  := 1.0;
    volRight := 1.0;

    if (useInDevDefault) then
   begin
        uos_InputAddDSPVolume(PlayerIndex1, In1IndexD, 1, 1);
         uos_InputSetDSPVolume(PlayerIndex1,  In1IndexD, volLeft,volRight, True); /// Set volume
   end;
   if (useInDev1) then
   begin
        uos_InputAddDSPVolume(PlayerIndex1, In1Index1, 1, 1);
         uos_InputSetDSPVolume(PlayerIndex1,  In1Index1, volLeft,volRight, True); /// Set volume
   end;
   if (useInDev2) then
   begin
        uos_InputAddDSPVolume(PlayerIndex1, In1Index2, 1, 1);
         uos_InputSetDSPVolume(PlayerIndex1,  In1Index2, volLeft,volRight, True); /// Set volume
   end;

    ///// DSP Volume changer
    //////////// PlayerIndex : Index of a existing Player
    ////////// In1Index : InputIndex of a existing input
    ////////// VolLeft : Left volume
    ////////// VolRight : Right volume



    uos_Play(PlayerIndex1);  /////// everything is ready to play...
    ButtonStart.Enabled:= false ;  // wait till stop
    ButtonStop.Enabled:= true ;  // allow stop
end;

Reply | Threaded
Open this post in threaded view
|

Re: using 2 microphones

fredvs
Administrator
Hello edf.

Welcome to uos forum.

Hum, I am a bit lost with your code.

Are you able to make 1 usb microphone work with uos, following the uos simplerecorder demo?

What happens when you declare 2 microphones based on the simplerecorder demo?
For example:
OutputIndex1 := uos_AddFromDevIn(0,0,-1,-1,-1,-1,-1);
OutputIndex2 := uos_AddFromDevIn(0,1,-1,-1,-1,-1,-1);

What is the result of the demo deviceinfos when you connect both mic, what device is assigned for the mics?

Sorry but I am out of computer for the moment and can not try your code.
Also i never try to record 2 mic at the same time, it should work but I never try.

Fred

edf
Reply | Threaded
Open this post in threaded view
|

Re: using 2 microphones

edf
thanks Fred.
re
Are you able to make 1 usb microphone work with uos, following the uos simplerecorder demo? YES

What happens when you declare 2 microphones based on the simplerecorder demo? GIVES ERROR
 (see first post)

if you look at following code
//<start of code>
 if (useInDev1) then
   begin
         
         In1Index1 := uos_AddFromDevIn(PlayerIndex1, InDev1,-1,-1,-1,-1,-1,-1);
   end;
 if (useInDev2) then
   begin
       
         In1Index2 := uos_AddFromDevIn(PlayerIndex1, InDev2,-1,-1,-1,-1,-1,-1);
   end;

//<end of code>

example
 where
InDev1 := 1; // a valid mic (actually a USB Mic)
InDev2 := 2; // another valid mic (actually another USB Mic)
one at a time works OK.

So if useInDev1 = true and useInDev2 = false then works fine

So if useInDev1 = false and useInDev2 = true then works fine

BUT if useInDev1 = true and useInDev2 = true then  BOMBs

Just in case I have not made it clear, BOTH mics are connected into the PC.
Just adding the 2 uos_AddFromDevIn makes it BOMB.
 It gives the error and the file produced is empty no matter how long the recorder runs.
 The file is not closed when you  uos_Stop(PlayerIndex1)

thanks for looking at it.
Reply | Threaded
Open this post in threaded view
|

Re: using 2 microphones

fredvs
Administrator
This post was updated on .
Hello.

Hum, all what you have done is ok.

Are those 2 mic equal (same mark, same model) ?

 Did you try with different parameter for uos_AddFromDevIn() ?
( Device: cint32;
  Latency: CDouble;
  SampleRate: CDouble;
  OutputIndex: cint32;
  SampleFormat: cint32;
  FramesCount : cint32;
  ChunkCount: cint32): cint32;

For example with other Latency, SampleFormat, FramesCount and ChunkCount?

> Just adding the 2 uos_AddFromDevIn makes it BOMB.

Do you get any error message from the BOMB?
[EDIT] Ok, in first post you said:
>gives raised exception class 'External: ACCESS VIOLATION' with message Access violation reading from address $FFFFFFFFFFF.

Are you able to debug the program? (I know debug could not work with audio but maybe you can get something)

May I ask you the mark and model of your usb mic (so I can see their specification)?

Fred.
Reply | Threaded
Open this post in threaded view
|

Re: using 2 microphones

fredvs
Administrator
This post was updated on .
Re-hello.

What happen if you use 2 players, one with the first mic and the second with the other mic and play the 2 players together?

edf
Reply | Threaded
Open this post in threaded view
|

Re: using 2 microphones

edf
Thanks Fred
 I wonder if I am just asking too much to use 2 usb mics. (I tried this as it was the easest way to get 2 mics). But see on as well.

I dont want you to waste your time, so i am also trying different ways.

but in case you are interested.

Just going through the faults. It is clear I was a bit vague.
So trying to make it a bit clearer.
Assume you have 2 USB mics and code is
  In1Index1 := uos_AddFromDevIn(PlayerIndex1, InDev1,-1,-1,-1,-1,-1,-1);
  In1Index2 := uos_AddFromDevIn(PlayerIndex1, InDev2,-1,-1,-1,-1,-1,-1);

there is nothing appears wrong till

uos_Play(PlayerIndex1);  /////// everything is ready to play..

at which a message from windows comes up.
Not enough USB Controller resources.
(This is not from Lazarus, or debugger. It displays in the windows notification area on [in my case] very right hand side of windows )
 
not enough USB  controller resources

The  uos_Stop(PlayerIndex1);
  ClosePlayer1;
seems to be ok.

 But the file size is zero.

and when you close the application
the debugger gives the application raised exception class 'External: ACCESS VIOLATION' with message Access violation reading from address $FFFFFFFFFFF.

I put a breakpoint on form .Destroy
and it seemed the error was somewhere in uos_free (my guess)

The usb microphones are anko [from Kmart] keycode 42959540/jlr-74449

So I tried a different way.
1 USB mic and 1 using the 3.5 mm plug.
this gave no errors using 2 at once, but sound was a mess. (not just what you would expect with 2 audio at once. Cracks and etc. some real sound). intereresting that the code faults are not there. and that file has a length.
is this just me not understanding how 2 inputs writting to one file would be ?

What my actual new approch will be.
use 2 3.5 mm connected mics.
use 3.5mm plug to 2 rca plug cables. connect 1 mic to LHS RCA plug, and the other Mic to RHS RCA plug.
So record 1 mic to LHS channel, and other to RHS Channel.

getting back to what you suggested.
a) using 2 different PlayerIndex1 and PlayerIndex2. i tried this first.
producing 2 files. one  mic would work and produced a valid file. other produced zero length file.
(it was a while ago, and i cant remember if it produced access faults.)

b) using different settings. If you could suggest some to try , happy to. (I dont understand the UOS well enough to know what to use.)

But if you think you have wasted too much time on this, donot waste any more.

thanks for your help (and patience)
Ed
Reply | Threaded
Open this post in threaded view
|

Re: using 2 microphones

fredvs
Administrator
Hello Ed.

>So I tried a different way.
>1 USB mic and 1 using the 3.5 mm plug.
>this gave no errors using 2 at once,but sound was a mess.

Ha, that is already a excellent news.
If you get something but the sound is mess it is because of wrong parameters used.
For the input it could be from those:
  Latency: CDouble;
  SampleFormat: cint32;
  FramesCount : cint32;

Also check parameters of output uos_AddIntoDevOut() and uos_AddIntofile():
 Channels : delault : -1 (2:stereo) (1:mono, 2:stereo, ...)
 SampleFormat : default : -1 (2:Int16) (1:Int32, 2:Int16)
 FramesCount : default : -1 (= 65536)

If you get some result (even with bad noise) you will win, it is only a problem of parameters.
But I cannot say witch one (at first view it is about SampleFormat or/and Channels or/and Latency).

>But if you think you have wasted too much time on this, donot waste any more.

No, not at all!  It interest me a lot because I was on plan to create a multi track recorder.
Sadly I am outside for a few weeks without my audio-computer.

> ACCESS VIOLATION' with message Access violation reading from address $FFFFFFFFFFF

Hum, strange, I need to buy a usb mic to try, I only have try with using the 3.5 mm plug or the build in of the computer and it was ok.

Fred