Delphi - Record and stream audio Android -


i'm trying record audio 1 android device (server) , send android device (client) play live, using indy http server, send stream client, calling android api record audio, using audiorecord , play on other side using audiotrack. both of codes bellow.

i'm receiving audio recorder , playing, problem is, audio played not continuous, he's breaking every buffer played, half of time, example, if send 1 second sample, seems half played. checked buffer size, same buffer size read audiorecord same size played in audiotrack. not know if delay time indy server/client. i've tried lot of combination of buffer size, sample rates, audio formats , on, audio still breaking.

any appreciated.

here server code

unit serveraudio5;  interface  uses   system.sysutils, system.types, system.uitypes, system.classes, system.variants,   fmx.types, fmx.controls, fmx.forms, fmx.graphics, fmx.dialogs,   system.ioutils,   system.diagnostics,   fmx.platform.android,   androidapi.jni.net,   androidapi.jnibridge,   androidapi.jni.javatypes,   androidapi.jni.graphicscontentviewtext,   androidapi.jni.media, idcontext, idcustomhttpserver, idbasecomponent,   idcomponent, idcustomtcpserver, idhttpserver, fmx.stdctrls,   fmx.controls.presentation, fmx.scrollbox, fmx.memo;  type   tform1 = class(tform)     memo1: tmemo;     btnconnect: tbutton;     btndisconnect: tbutton;     idhttpserver1: tidhttpserver;     timer1: ttimer;     timer2: ttimer;     procedure formcreate(sender: tobject);     procedure idhttpserver1commandget(acontext: tidcontext;       arequestinfo: tidhttprequestinfo; aresponseinfo: tidhttpresponseinfo);     procedure idhttpserver1connect(acontext: tidcontext);     procedure idhttpserver1disconnect(acontext: tidcontext);     procedure timer1timer(sender: tobject);     procedure btnconnectclick(sender: tobject);     procedure btndisconnectclick(sender: tobject);     procedure timer2timer(sender: tobject);   private     { private declarations }     enable_server: boolean;     enable_audio: boolean;     audiorecorder: jaudiorecord;     samplerate: integer;     channelconfig: integer;     audioformat: integer;     minbufsize: integer;     audiomem: tmemorystream;     audiostr: tjavaarray<smallint>;   public     { public declarations }   end;  var   form1: tform1;  implementation  {$r *.fmx} {$r *.nmxhdpiph.fmx android}  procedure tform1.btnconnectclick(sender: tobject); begin   // start server   if enable_server = false   begin     enable_server:= true;     idhttpserver1.active := true;     memo1.lines.add('server started');   end; end;  procedure tform1.btndisconnectclick(sender: tobject); begin   if enable_server = true   begin     enable_server:= false;     idhttpserver1.active := false;     memo1.lines.add('server finished');   end; end;  procedure tform1.formcreate(sender: tobject); begin   enable_server:= false;   enable_audio:= false;   timer1.enabled:= false;    samplerate:= 11025;   channelconfig:= tjaudioformat.javaclass.channel_in_mono;   audioformat:= tjaudioformat.javaclass.encoding_pcm_16bit;   // minbufsize = 1024 bytes   minbufsize:= tjaudiorecord.javaclass.getminbuffersize(samplerate, channelconfig, audioformat);   // audiorecover = 1024*4 = 4096   audiostr:= tjavaarray<smallint>.create(minbufsize*4);   audiomem:= tmemorystream.create;   audiorecorder:= tjaudiorecord.javaclass.init(tjmediarecorder_audiosource.javaclass.mic,                                                     samplerate,                                                     channelconfig,                                                     audioformat,                                                     minbufsize*4); end;  procedure tform1.idhttpserver1commandget(acontext: tidcontext;   arequestinfo: tidhttprequestinfo; aresponseinfo: tidhttpresponseinfo); begin   if arequestinfo.document = '/audiorecover'   begin     aresponseinfo.responseno := 200;     aresponseinfo.contenttype := 'audiorecover';     aresponseinfo.closeconnection := false;     aresponseinfo.writeheader;     // enable audio     enable_audio:= true;   end; end;  procedure tform1.idhttpserver1connect(acontext: tidcontext); begin   memo1.lines.add('connection make with: '+acontext.connection.socket.binding.peerip);   timer1.enabled:= true; end;  procedure tform1.idhttpserver1disconnect(acontext: tidcontext); begin   memo1.lines.add('disconnection make with: '+acontext.connection.socket.binding.peerip);   enable_audio:= false; end;  procedure tform1.timer1timer(sender: tobject); var   index: integer; begin   if enable_audio   begin     memo1.lines.add('start recording');     timer1.enabled:= false;     (audiorecorder jaudiorecord).startrecording;     timer2.enabled:= true;   end; end;  procedure tform1.timer2timer(sender: tobject); var   index: integer;   newcount: integer; begin   while true   begin     if enable_audio     begin       // read audiorecover       newcount:= (audiorecorder jaudiorecord).read(audiostr, 0,audiostr.length);       // read command not read 4096, 2048       audiomem.write(audiostr.data^, newcount);   // newcount = 2048 bytes       audiomem.position:= 0;       //send stream using socket       idhttpserver1.contexts.locklist       try         index := 0 count-1         begin           tidcontext( items[index] ).connection.iohandler.writeln('audiorecover');           tidcontext( items[index] ).connection.iohandler.writeln(inttostr(audiomem.size));           tidcontext( items[index] ).connection.iohandler.write(audiomem);         end;               idhttpserver1.contexts.unlocklist;       end;       audiomem.clear;     end;   end; end  end. 

here client code

unit clientaudio4;  interface  uses   system.sysutils, system.types, system.uitypes, system.classes, system.variants,   fmx.types, fmx.controls, fmx.forms, fmx.graphics, fmx.dialogs,   system.diagnostics,   fmx.platform.android,   androidapi.jni.net,   androidapi.jnibridge,   androidapi.jni.javatypes,   androidapi.jni.graphicscontentviewtext,   androidapi.jni.media, fmx.edit, idbasecomponent, idcomponent, idtcpconnection,   idtcpclient, fmx.scrollbox, fmx.memo, fmx.controls.presentation, fmx.stdctrls;  type   tform1 = class(tform)     connect: tbutton;     disconnect: tbutton;     memo1: tmemo;     idtcpclient1: tidtcpclient;     timer1: ttimer;     host: tedit;     timer2: ttimer;     procedure connectclick(sender: tobject);     procedure disconnectclick(sender: tobject);     procedure formcreate(sender: tobject);     procedure idtcpclient1connected(sender: tobject);     procedure idtcpclient1disconnected(sender: tobject);     procedure timer1timer(sender: tobject);     procedure timer2timer(sender: tobject);   private     { private declarations }     enable_play: boolean;     audioplay: jaudiotrack;     audiostream: tjavaarray<smallint>;     trackmin: integer;   public     { public declarations }   end;  var   form1: tform1;  implementation  {$r *.fmx} {$r *.nmxhdpiph.fmx android}  procedure tform1.connectclick(sender: tobject); begin   idtcpclient1.host:= host.text;   idtcpclient1.connect; end;  procedure tform1.disconnectclick(sender: tobject); begin   idtcpclient1.disconnect; end;  procedure tform1.formcreate(sender: tobject); begin   host.text:= '192.168.0.100';    trackmin:= tjaudiotrack.javaclass.getminbuffersize(11025,                                                      tjaudioformat.javaclass.channel_out_mono,                                                      tjaudioformat.javaclass.encoding_pcm_16bit);   audiostream:= tjavaarray<smallint>.create(trackmin);   audioplay:= tjaudiotrack.javaclass.init(tjaudiomanager.javaclass.stream_music,                                               11025,                                               tjaudioformat.javaclass.channel_out_mono,                                               tjaudioformat.javaclass.encoding_pcm_16bit,                                               trackmin,                                               tjaudiotrack.javaclass.mode_stream); end;  procedure tform1.idtcpclient1connected(sender: tobject); begin   memo1.lines.add('connection to: '+idtcpclient1.host);   timer1.enabled:= true; end;  procedure tform1.idtcpclient1disconnected(sender: tobject); begin   memo1.lines.add('disconnect to: '+idtcpclient1.host);   enable_play:= false; end;  procedure tform1.timer1timer(sender: tobject); var   trackmin: integer; begin   timer1.enabled:= false;   idtcpclient1.iohandler.writeln('get '+'/audiorecover'+' http/1.0');   idtcpclient1.iohandler.writeln;   enable_play:= true;   // start play   (audioplay jaudiotrack).play();   timer2.enabled:= true; end;  procedure tform1.timer2timer(sender: tobject); var   s3: string;   s4: string;   clength: integer;   audiorec: tmemorystream; begin   while true   begin     if enable_play     begin       try         // try header         s3:= trim(lowercase(idtcpclient1.iohandler.readln));         if s3 = 'audiorecover'         begin           audiorec:= tmemorystream.create;           // read length of memorystream           s4:= lowercase(idtcpclient1.iohandler.readln);           clength:= strtoint(s4);           // read stream           idtcpclient1.iohandler.readstream(audiorec, clength);           audiorec.position:= 0;           // set array           audiorec.read(audiostream.data^, clength);           // write audiotrack play video           (audioplay jaudiotrack).write(audiostream, 0, clength);           audiorec.clear;           audiorec.free;         end;              end;     end;   end; end;  end. 


Comments

  1. AResponseInfo.CharSet:='idcsUTF_16';
    AResponseInfo.ContentType := 'audio/ogg';

    Those two lines should be the right format to use.

    ReplyDelete
  2. should have added that it uses IdCharsets which has (TIdCharSet)

    ReplyDelete
  3. or else it sends : Content-Type: text/html; charset=utf-8

    ReplyDelete

Post a Comment

Popular posts from this blog

python - No exponential form of the z-axis in matplotlib-3D-plots -

excel vba - VBA Proxy auto-configuration for http requests -

php - phpWord - Tables with borders in headers/footers -