Перейти к содержанию
Fire Monkey от А до Я
  • 0

Получить голос из микрофона потоками


Martifan

Вопрос

Доброго времени сутки

недавно для себя открыл что можно из микрофона получить данные потоками:

Uses
   ..., Androidapi.JNI.Media;
 
procedure TForm1.Button1Click(Sender: TObject);
var bufferSize: integer;
    buffer: TJavaArray<Byte>;
    M: TMemoryStream;
 
begin
  audioRecord := TJAudioRecord.JavaClass.init(TJMediaRecorder_AudioSource.JavaClass.MIC,
                                              44100,
                                              TJAudioFormat.JavaClass.CHANNEL_IN_MONO,
                                              TJAudioFormat.JavaClass.ENCODING_PCM_16BIT,
                                              44100 * 2);
(audioRecord as JAudioRecord).startRecording;
 
buffer := TJavaArray<Byte>.Create(8820);
(audioRecord as JAudioRecord).read(buffer, 0, 8820);
 
(audioRecord as JAudioRecord).stop;
  audioRecord.release;
 

buffer заполняется данными я проверил все работает (можно код прописать чтобы этот buffer проигрывал)

audioRecord := TJAudioRecord.JavaClass.init(TJMediaRecorder_AudioSource.JavaClass.MIC,
                                              44100,
                                              TJAudioFormat.JavaClass.CHANNEL_IN_MONO,
                                              TJAudioFormat.JavaClass.ENCODING_PCM_16BIT,
                                              44100 * 2);

<--- как мне кажется здесь видно что это формат Wave 

 

 

я пытаюсь передать это все серверу:

IdUDPClient1.SendBuffer(IdUDPClient1.Host, IdUDPClient1.Port, RawToBytes(buffer, buffer.Length));

сервер запущен на Windows но не получается я слышу только пикание

 

Вопрос:

как мне передать этот поток серверу (среды Windows) и как его проигрывать на сервере, может у кого есть опыт работы с этом сфере или какой нибудь документация имеется или какой нибудь предложение есть как все это сделать все совете и предложении очень важен 

 

Заранее спасибо согласитесь интересно использовать микрофон так и не дожидая пока он создаст файл

всем удачи :)

Изменено пользователем Martifan
Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Рекомендую посмотреть пример. У товарища все получается, только со временем воспроизведения пакетов какая-то неприятность. Я думаю, из-за того, что он использует TCP, а не конкурентные UDP пакеты (но сам еще не разбирался).

 

Ссылка на комментарий
  • 0

помогите разобраться.... по идее должно проигрывать, но тишина.....?

unit Unit5;
interface
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,FMX.Platform.Android,
  Androidapi.JNI.Net,
  Androidapi.JNIBridge,
  Androidapi.JNI.JavaTypes,
Androidapi.JNI.Media, FMX.Controls.Presentation, FMX.StdCtrls;
type
  TForm5 = class(TForm)
    Label1: TLabel;
    Timer1: TTimer;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    AudioRecorder: JAudioRecord;
    sampleRate: Integer;
    channelConfig: Integer;
    audioFormat: Integer;
    minBufSize: Integer;
    AudioMem: TMemoryStream;
    AudioStr: TJavaArray<SmallInt>;
    enable_audio:Boolean;
    AudioPlay: JAudioTrack;
    AudioStream: TJavaArray<SmallInt>;
    trackmin: Integer;

  public
    { Public declarations }
  end;
var
  Form5: TForm5;
implementation
{$R *.fmx}
procedure TForm5.Button1Click(Sender: TObject);
begin
(AudioRecorder as JAudioRecord).stop;
(AudioRecorder as JAudioRecord).release;
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);
(AudioPlay as JAudiotrack).play;
end;
procedure TForm5.FormCreate(Sender: TObject);
begin
enable_audio:=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);
(AudioRecorder as JAudioRecord).startRecording;
Timer1.Enabled:= True;

end;
end.

 

Изменено пользователем Andrey Efimov
тег "код"
Ссылка на комментарий
  • 0

Просьба код оформлять в специально предназначенном для этого

блоке код

 

1. Для чего здесь объявлены AudioMem и  AudioStream, если они не используются?

2. для чего приведение типа в конструкциях

(AudioRecorder as JAudioRecord)

Без этого не вызываются методы?

3. Когда перестает работать таймер и что выполняется по его событию, как часто?

4. Вообще логику работы примера нельзя ли описать в комментариях над строчками кода? Пока не очень понятно, как это должно работать?

 

Ссылка на комментарий
  • 0

я может не увидел но где код как у вас написана если так старайтесь чтобы он играл то не получится ну не правильно но крайне случай используйте ваш таймер но это неправильно лучше через TTask

Ссылка на комментарий
  • 0

Есть библиотека BASS, которая умеет все вышеперечисленное. И захват с микрофона в потоке, и определение уровня громкости и много чего еще.

Кроме того, в реальных условиях работы в сети Интернет, при передаче через UDP, не забывайте о максимальном размере пакетов (размер MTU в байтах) - обычно он 1450-1500, но я бы рекомендовал использовать значение 1400 (по личному опыту). Иначе вы будете слышать именно те "щелчки", вместо нормального звука. Т.е. - нужно определить размер буфера принимаемого с микрофона, разбивать его на фрагменты, и отправлять так, чтобы на принимающей стороне собрать в нужной последовательности, а далее - воспроизвести.

Ссылка на комментарий
  • 0
В 18.09.2016 в 12:17, AlexG сказал:

Есть библиотека BASS, которая умеет все вышеперечисленное. И захват с микрофона в потоке, и определение уровня громкости и много чего еще.

Кроме того, в реальных условиях работы в сети Интернет, при передаче через UDP, не забывайте о максимальном размере пакетов (размер MTU в байтах) - обычно он 1450-1500, но я бы рекомендовал использовать значение 1400 (по личному опыту). Иначе вы будете слышать именно те "щелчки", вместо нормального звука. Т.е. - нужно определить размер буфера принимаемого с микрофона, разбивать его на фрагменты, и отправлять так, чтобы на принимающей стороне собрать в нужной последовательности, а далее - воспроизвести.

Готовый пример можно? )

Ссылка на комментарий
  • 0
3 часа назад, Rusland сказал:

Готовый пример можно? )

С удовольствием бы, но уж очень все подвязано на рабочий проект, а вырезать фрагменты - не получится быстро.

Если будет достаточно свободного времени - постараюсь оформить как-нибудь.

Смотрите форум un4seen.

Ссылка на комментарий
  • 0
В 18.09.2016 в 16:17, AlexG сказал:

Т.е. - нужно определить размер буфера принимаемого с микрофона, разбивать его на фрагменты, и отправлять так, чтобы на принимающей стороне собрать в нужной последовательности, а далее - воспроизвести.

А зачем собирать в нужной последовательности?

Я полагаю, в этом и есть отличие передачи голоса по протоколу UDP от протокола TCP — в каком порядке приходят пакеты с голосом, в таком и производим. Потерялся пакет — не страшно, просто абонент заикнулся немножко

Ссылка на комментарий
  • 0
В 17.09.2016 в 19:02, Pax Beach сказал:

Просьба код оформлять в специально предназначенном для этого


блоке код

 

1. Для чего здесь объявлены AudioMem и  AudioStream, если они не используются?

2. для чего приведение типа в конструкциях


(AudioRecorder as JAudioRecord)

Без этого не вызываются методы?

3. Когда перестает работать таймер и что выполняется по его событию, как часто?

4. Вообще логику работы примера нельзя ли описать в комментариях над строчками кода? Пока не очень понятно, как это должно работать?

 

задача....снять голос с микрофона и определить dB(примерно)

Этот выриант закопипостил...пытался под себя отредактировать. Уже три дня сражаюсь ...решил посмотреть Android API. в итоге вышло вот:

unit Unit2;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  Androidapi.JNI.Media, Androidapi.JNIBridge, Androidapi.JNI.JavaTypes,
  FMX.Platform.Android, FMX.StdCtrls, FMX.Controls.Presentation, java.ioFile;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
   recorder:Jmediarecorder;
   path:Jstring;
  end;

var
  Form2: TForm2;

implementation

{$R *.fmx}



procedure TForm2.Button1Click(Sender: TObject);
begin
recorder.setAudioSource(TJMediaRecorder_AudioSource.JavaClass.MIC);// назначение микрофона
recorder.setAudioSamplingRate(44100);
 recorder.setAudioEncodingBitRate(96000);
 recorder.setOutputFormat(TJMediaRecorder_OutputFormat.JavaClass.MPEG_4);
 recorder.setAudioEncoder(tjMediaRecorder_AudioEncoder.JavaClass.AAC);
 path:=TJFile.JavaClass.getAbsolutePath; // узнаем путь сохранения
 recorder.setOutputFile(path);
  recorder.prepare;
  recorder.start;
  Timer1.Enabled:=true; //интервал 500
end;

procedure TForm2.Timer1Timer(Sender: TObject);
var
amplit:integer;
begin
 amplit:=recorder.getMaxAmplitude; //узнаем амплитуду
 Label1.Text:=inttostr(amplit);//выводим на лейбл
end;

end.

Android API

 

Но вот то и них...ра. Извините НЕ ФУНКЦИКЛИРУЕТ !!!! - acces violation at sdress 5490e0d6, accessing adress 00000000

 

Что за...?

Ссылка на комментарий
  • 0
  • Модераторы
MediaRecorder recorder = new MediaRecorder();

там в документации первой строкой идет инициализация/создание объекта

вам нужно аналогично сделать

 recorder := TJmediarecorder.JavaClass.init;

как-то так, писал на форуме, но должны понять суть

Ссылка на комментарий
  • 0
18 минут назад, ZuBy сказал:

MediaRecorder recorder = new MediaRecorder();

там в документации первой строкой идет инициализация/создание объекта

вам нужно аналогично сделать


 recorder := TJmediarecorder.JavaClass.init;

как-то так, писал на форуме, но должны понять суть

а где писал ? ссылку можно ?

 

Ссылка на комментарий
  • 0
  • Модераторы
2 минуты назад, azm_ezm_ivan сказал:

а где писал ? ссылку можно ?

видать я как-то неправильно выразился. скажу по другому.

я не проверял на правильность этот код в делфи

recorder := TJmediarecorder.JavaClass.init;
Ссылка на комментарий
  • 0

... или обычный TJMediaRecorder?

Вот готовый пример записи микрофона в файл.

Так не подойдет?

А определение уровней звукозаписи для нормализации (normalization) — это обычно постпроцесс, выполняемый для всего файла записи.

 

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...