Обсуждаем контроллеры компании Atmel.
Ответить

Re: Ардуино - запись звука

Чт авг 31, 2023 18:31:22

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

Re: Ардуино - запись звука

Чт авг 31, 2023 18:56:24

Роман, как закрыть файл по таймауту, если поток юдп прекратился

замечательный вопрос)) никогда такой фигнёй не занимался... ))

наверное нужен флаг окончания потока...
:roll:

1- таймер у нас есть.
2- запись файла у нас есть.
3- флаги... сделаем)).

static int flag_Thread = 0;
static int st_Thread = 0;
...


открываем файл и начинаем писать...
:roll:
перед кажной новой записью создаём новый файл... как это делается мы уже знаем))

// при записи файла надо следить чтоб файл не вышел за допустимые границы... в нашем случае диска D:\
// писать будем по кругу... допустим 0-1500 байт...
// максимальная длина файла ограничена размером буфера... E_int[]... допустим 1500 байт...
///////////////////////////////////////// запись файла EEPROM:
while(flag_Thread) // писать будем до тех пор пока не сбросится флаг прекращения потока юдп...
{

//курсор
E_raf.seek(0);

for (xE=0; xE<1500; xE++) {
E_raf.writeByte(E_int[xE]); // запись из буфера E_int[] в файл
};

}
///////////////////////////////////////// закрываем файл EEPROM:
//закрываем файл
E_raf.close();
}catch(IOException e){
EEPROM_error = 1; //EEPROM_error int -начальное 0
EEPROM_String += e.getMessage(); //e.getMessage() > EEPROM_String
}
/////////////////////////////////////////// TX EEPROM END
:roll:


потом наверное добавляем в таймер счётчик потока...
st_Thread ++;
...
и если счётчик переполнится... то флаг потока сбросится ))
if (st_Thread > 100){
st_Thread = 0; // сброс флага потока
flag_Thread = 0; // сброс счётчик потока
};


ну и наверное надо сбрасывать счётчик потока в приёмнике юдп...
:roll:

DatagramPacket reply = new DatagramPacket(RX_byte, RX_byte.length);
while(true)
{
//////////////////////////////////////////////////////// RX: Eth:

try
{
socket.receive(reply); // UDP: MIN=18; MAX=1472.
}catch(IOException e)
{

}

flag_Thread = 1; // установить флаг потока
st_Thread = 0; // сброс счётчик потока

}// while(true)
:roll:


итого:
1- прилетели пакеты - сработал флаг записи потока.
2- сработал флаг записи потока - включилась запись потока.
3- перед записью нового потока - создали новый файл (как это делается мы уже знаем).
4- прекратили прилетать пакеты - счётчик потока переполнился.
5- переполнился счётчик потока - прекратилась запись в файл.
6- прекратилась запись в файл - файл закрылся))
7- ждём пока прилетит очередной пакет UDP...
8- прилетел очередной пакет UDP - автоматом сработала новая запись в новый файл.
и так по кругу))

примерно как-то так наверное...
в общих чертах))
лишнее можно убрать))
и всё переделать))
:tea:

Re: Ардуино - запись звука

Пт сен 01, 2023 00:43:07

OK, вот что у меня получилось

Первый делом нужно включить обработку исключения таймаута:
Для установки тайм-аута для socket.receive(packet), вы можете использовать метод setSoTimeout(int timeout) на вашем сокете DatagramSocket. Этот метод указывает, сколько времени сокет будет ожидать получение данных перед тем, как выбросит исключение SocketTimeoutException, если данные не были получены за указанный период времени.


final DatagramSocket socket = new DatagramSocket(4210);
socket.setSoTimeout(5000);
socket.setReceiveBufferSize(10000); // размер буфера RX Ethernet

теперь начнуть работать исключения при прекращении потока и можно будет "бегать" по циклам

2. добавим сообщение, что Поток остановился в исключения и установим флага UdpStoped=1

Код:
   socket.receive(reply);            // UDP: MIN=18; MAX=1472.
    System.out.println("UDP-поток начался2.");
    long endTime = System.currentTimeMillis();
    UdpStoped = 0;
   
    long elapsedTime = endTime - startTime;
    ////////////////////////////////////////////////////// RX: IP, port, len: 
    TX_IP = "" + reply.getAddress();  // IP String
    RX_port = reply.getPort();        // port int
    RX_len = reply.getLength();       // len int
  }catch(Exception e)
  {
     System.out.println("Поток остановился по таймауту " );
     UdpStoped = 1;
  }



3. Нарисовалась проблема. Если включить плейер раньше чем источник Udp пакетов, то это тоже ислкючение!
поэтому добавляем try в цикле и заводим еще один цикл while в который возвращаемся по break; что бы заново запустить обработку пакетов если они все же появятся.


Код:
         while (true){
         while (true){
         try
         {
DatagramPacket reply = new DatagramPacket(RX_byte, RX_byte.length);
System.out.println("Ожидание UDP-потока...");
socket.receive(reply);   

///здесь остальная
///логика программы

}// while(true)   
         } //try
catch(SocketTimeoutException  e)
{
   //Нарисовалась проблема. Если включить плейер раньше чем источник Udp пакетов, то это тоже ислкючение!
     System.out.println("поток не начался...." );
     break;
   
}
         } // while
         } // while




4. Теперь есть флаг которым можно управлять записью файлов
если UdpStoped=0 (Обычная логика записи файлов)

Код:
if (UdpStoped==1){
      
      timeStamp = new SimpleDateFormat("yyyyMMdd_HHmm").format(Calendar.getInstance().getTime());
      
      
      }


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


кот прилагаю.

Добавлено after 2 minutes 7 seconds:
но работает хорошо, то что мне нужно.
Вложения
Udp сервер с сохранением файлов по времени.txt
(45.69 KiB) Скачиваний: 40

Re: Ардуино - запись звука

Пт сен 01, 2023 13:15:13

ух...
setSoTimeout(int timeout)
это я знаю)) от этого я отказался в первый день ))
передёргивать сокеты... это не нормальный режим работы.
так никто не делает)) нормальные программисты открывают сокет один раз при запуске программы и больше их не трогают...
:roll:
но с другой стороны... у тебя же тут всё не стандартно...
тогда ладно))
:tea:

Добавлено after 1 hour 36 minutes 31 second:
но работает хорошо, то что мне нужно.

не любишь ты ходить через парадный вход... вечно тебя тянет через задний проход))
:))
у тебя есть стройная красивая программа... со стройной логической цепочкой... со всеми необходимыми блоками...
:tea:

1- блок записи файлов (вынесли в отдельную функцию чтоб можно было вызывать из любого места)
public static void TX_EEPROM() {
RandomAccessFile E_raf = new RandomAccessFile("D:/EEPROM.txt", "rw");
}

2- главный поток
public static void main(String[] args) throws Exception
{
}

3- в главном потоке есть таймер
Time_0.schedule(new TimerTask() { //start Time_0
},0,1000);//delay, period

4- в главном потоке есть приёмник
DatagramPacket reply = new DatagramPacket(RX_byte, RX_byte.length);
while(true)
{
}// while(true)

всё что нужно - есть.
:tea:

Re: Ардуино - запись звука

Пт сен 01, 2023 13:15:56

я думал про флаг записи потока. Но , к сожалению, не смог прокачать эту тему. Не допетрил как это можно сделать

Меня смутило то что когда поток отсутсвует цикл останавливается и я не могу вообще влиять ни на что. Так же еще и не работали и исключения. Ну то есть невозможно было подобраться к процессу никак и тем более повлиять на него


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

Re: Ардуино - запись звука

Пт сен 01, 2023 14:11:02

далее...

все пакеты прилетают в приёмник и складываются в приёмный буфер.

1- блок записи файлов (вынесли в отдельную функцию чтоб можно было вызывать из любого места)
public static void TX_EEPROM() {
RandomAccessFile E_raf = new RandomAccessFile("D:/EEPROM.txt", "rw");
}

2- главный поток
public static void main(String[] args) throws Exception
{
}

3- в главном потоке есть таймер
Time_0.schedule(new TimerTask() { //start Time_0
},0,1000);//delay, period

4- в главном потоке есть приёмник
DatagramPacket reply = new DatagramPacket(RX_byte, RX_byte.length);
while(true)
{
RX_int[xRX] = RX_byte[xRX];
}// while(true)
:tea:

Добавлено after 6 minutes 19 seconds:
далее...
если мы хотим записать прилетевшие пакеты на диск то просто вызываем функцию записи в приёмнике.

1- блок записи файлов (вынесли в отдельную функцию чтоб можно было вызывать из любого места)
public static void TX_EEPROM() {
RandomAccessFile E_raf = new RandomAccessFile("D:/EEPROM.txt", "rw");
EEPROM_len = E_raf.length();
E_raf.seek(EEPROM_len);
E_raf.close();
}

2- главный поток
public static void main(String[] args) throws Exception
{
}

3- в главном потоке есть таймер
Time_0.schedule(new TimerTask() { //start Time_0
},0,1000);//delay, period

4- в главном потоке есть приёмник
DatagramPacket reply = new DatagramPacket(RX_byte, RX_byte.length);
while(true)
{
RX_int[xRX] = RX_byte[xRX];
TX_EEPROM();
}// while(true)

функция записи работает так:
-открывает файл "D:/EEPROM.txt"
-определяет длину файла EEPROM_len = E_raf.length();
-передвигает курсор E_raf.seek(EEPROM_len); в конец файла и записывает данные в конец файла.
-закрывает файл.
:tea:

теперь всё что прилетает в приёмник будет дописываться в конец файла "D:/EEPROM.txt"
:tea:

Добавлено after 34 minutes 45 seconds:
далее...
если мы хотим писать каждый новый поток в новый файл то просто надо:
-определить когда заканчивается старый поток и начинается новый поток...
-указать функции записи куда писать - в старый файл или создать новый файл и писать в новый файл...
всё))

чтоб определить где заканчивается старый поток и начинается новый поток надо измерить время между прилетающими пакетами...
для этого нам поможет простой счётчик st и таймер !

static int st = 0; // простой счётчик времени (в миллисекундах)
static String s = "D:/EEPROM_.txt"; // имя файла
static int x = 0; // номером файла "x"

1- блок записи файлов (вынесли в отдельную функцию чтоб можно было вызывать из любого места)
public static void TX_EEPROM() {

if (st > 1000){
x++; if (x > 100){ x = 100; }; // ограничитель x
s = "D:/EEPROM_" + x + ".txt"}; // простой счётчик времени (в миллисекундах) больше 1 секунды > создать новый файл > "D:/EEPROM_x.txt" с номером "x"


RandomAccessFile E_raf = new RandomAccessFile( s , "rw");
EEPROM_len = E_raf.length();
E_raf.seek(EEPROM_len);
E_raf.close();
}

2- главный поток
public static void main(String[] args) throws Exception
{
}

3- в главном потоке есть таймер
Time_0.schedule(new TimerTask() { //start Time_0
st ++; // простой счётчик времени (в миллисекундах)
if (st > 2000){ st = 2000; }; // ограничитель простой счётчик времени (в миллисекундах)
},0,1);//period = 1 миллисекунда

4- в главном потоке есть приёмник
DatagramPacket reply = new DatagramPacket(RX_byte, RX_byte.length);
while(true)
{
RX_int[xRX] = RX_byte[xRX];
TX_EEPROM();
st = 0; // сброс простой счётчик времени (в миллисекундах)
}// while(true)
:tea:

все прилетевшие пакеты (с межпакетным интервалом меньше 1 секунды) будут записаны в существующий файл "D:/EEPROM.txt"

все прилетевшие пакеты (с межпакетным интервалом больше 1 секунды) будут записаны в новый файл "D:/EEPROM_x.txt" с номером "x"

:tea:

Re: Ардуино - запись звука

Пт сен 01, 2023 17:01:57

Ладно, ок.
Теперь мне нужно еще как минимум 2 вещи

1. Дополнить сырые данные до полноценного wav файла
2. Запускать эту программу как службу

Re: Ардуино - запись звука

Пт сен 01, 2023 19:16:33

olegue писал(а):1. Дополнить сырые данные до полноценного wav файла

при записи нового файла сдвинь курсор на 44 байта и допиши в начало нового файла "заголовок" wav файла...
format_wav.txt
(2.6 KiB) Скачиваний: 25

будет полноценный wav файл... который можно слушать на любом проигрывателе))

Re: Ардуино - запись звука

Пт сен 01, 2023 21:44:48

не нашел ничего более разумного чем если размер файла 0 всадить туда вот этот кусок

Код:
RandomAccessFile E_raf = new RandomAccessFile("d:/JAVA/Jv"+ timeStamp +".wav", "rw");



if (E_raf.length()==0){

        E_raf.writeByte(0x52);E_raf.writeByte(0x49);E_raf.writeByte(0x46);E_raf.writeByte(0x46);// > write() // HEX 
        E_raf.writeByte(0x24);E_raf.writeByte(0xED);E_raf.writeByte(0x01);E_raf.writeByte(0x00);
        E_raf.writeByte(0x57);E_raf.writeByte(0x41);E_raf.writeByte(0x56);E_raf.writeByte(0x45);
        E_raf.writeByte(0x66);E_raf.writeByte(0x6D);E_raf.writeByte(0x74);E_raf.writeByte(0x20);
        E_raf.writeByte(0x10);E_raf.writeByte(0x00);E_raf.writeByte(0x00);E_raf.writeByte(0x00);// > write() // HEX 
        E_raf.writeByte(0x01);E_raf.writeByte(0x00);E_raf.writeByte(0x01);E_raf.writeByte(0x00);
        E_raf.writeByte(0x40);E_raf.writeByte(0x1f);E_raf.writeByte(0x00);E_raf.writeByte(0x00);
        E_raf.writeByte(0x40);E_raf.writeByte(0x1f);E_raf.writeByte(0x00);E_raf.writeByte(0x00);
      
       
        E_raf.writeByte(0x01);E_raf.writeByte(0x00);E_raf.writeByte(0x08);E_raf.writeByte(0x00);
        E_raf.writeByte(0x64);E_raf.writeByte(0x61);E_raf.writeByte(0x74);E_raf.writeByte(0x61);
       
        E_raf.writeByte(0x00);E_raf.writeByte(0xED);E_raf.writeByte(0x01);E_raf.writeByte(0x00);   
       
      };
   


получившийся результат проигрывается хорошо.
Вложения
Jv20230901_2236.zip
(244.63 KiB) Скачиваний: 31

Re: Ардуино - запись звука

Пт сен 01, 2023 22:34:37

да пойдёт))
только посторонние щелчки на записи...
Screenshot_1.jpg
(102.08 KiB) Скачиваний: 29

использую высококачественные аудиофайлы... для проверки... а не разговор по телефону))
:music:

Добавлено after 1 minute 57 seconds:
у меня задачка посложней... андроид подключаю к компу))
:roll:
какие андроиды тупые и тормознутые)) ужас...
:tea:

Re: Ардуино - запись звука

Пт сен 01, 2023 23:39:49

да щелчки есть, я тоже заметил, но это пока для меня не сильно критично. Буду разбираться отдельно с ними уже потом как нибуть.

Меня другое беспокоит
в заголовке нужно указать размер файла?
если запись непрерывна и заранее поделена по 1м,то тут более менее ясно

А вот если поток прерывается в любой момент , что писать какой размер?

Добавлено after 2 minutes 1 second:
ставить 1мегабайт и посмотреть как на это будет реагировать плейер?

Добавлено after 19 minutes 13 seconds:
Короче , плейер видит мои файлы размером 1мб как 15секунд хотя реально это не меньше 2х минут

Добавлено after 11 minutes 39 seconds:
что то я не понял
1 мб это всегг 15 сек

Изображение

что-то тут не то


Длительность = 15 секунд
Битрейт = 8000 байт/сек (8 кГц * 1 байт/сэмпл)
Подставив значения в формулу:

Размер WAV-файла = 15 сек * 8000 байт/сек = 120,000 байт

Re: Ардуино - запись звука

Сб сен 02, 2023 00:36:53

щелчки обычно появляются в случае потери байт...
похоже у тебя опять теряются байты... по дороге))
:tea:

давно не занимался записью...
Код:
/////////////////////////////////////////////////////////////// Data = 126.252 -8
///////////////////////// RIFF (4 байт)
wav_int[0]  = 0x52; // R
wav_int[1]  = 0x49; // I
wav_int[2]  = 0x46; // F
wav_int[3]  = 0x46; // F
///////////////////////// Data Size (4 байт) 00 01 ED 24 = 126.244
wav_int[4]  = 0x24; // 
wav_int[5]  = 0xED; //   
wav_int[6]  = 0x01; // 
wav_int[7]  = 0x00; // 
/////////////////////////////////////////////////////////////// Data = 126.244 -32
///////////////////////// WAVE (4 байт)
wav_int[8]  = 0x57; // W 
wav_int[9]  = 0x41; // A
wav_int[10] = 0x56; // V
wav_int[11] = 0x45; // E
///////////////////////// секция формата ("fmt") (4 байт)
wav_int[12] = 0x66; // f
wav_int[13] = 0x6D; // m
wav_int[14] = 0x74; // t 
wav_int[15] = 0x20; // 
///////////////////////// Data Size (4 байт)
wav_int[16] = 0x10; // 
wav_int[17] = 0x00; // 
wav_int[18] = 0x00; // 
wav_int[19] = 0x00; // 
///////////////////////// Код сжатия (Compression Code)   1 - 65,535 (2 байт) 1 = PCM/uncompressed
wav_int[20] = 0x01; // PCM/uncompressed
wav_int[21] = 0x00; // 
///////////////////////// Количество каналов (Number of Channels) 1 - 65,535 (2 байт) 1 моно, 2 стерео
wav_int[22] = 0x01; // 1 mono // 2 стерео
wav_int[23] = 0x00; // 
///////////////////////// Скорость выборок (Sample Rate) 1 - 0xFFFFFFFF (4 байт) 1F 40 = 8000
wav_int[24] = 0x40; //0x40 8000 семпл в секунду
wav_int[25] = 0x1F; //0x1F 8000 семпл в секунду
wav_int[26] = 0x00; // 
wav_int[27] = 0x00; //   
///////////////////////// Среднее количество байт в секунду (Average Bytes Per Second) 1 - 0xFFFFFFFF (4 байт) 3E 80 = 16000
wav_int[28] = 0x40; //0x40 8000  //0x80 16000  байт в секунду
wav_int[29] = 0x1F; //0x1F 8000  //0x3E 16000  байт в секунду
wav_int[30] = 0x00; //   
wav_int[31] = 0x00; //   
///////////////////////// Количество байт на одну выборку (Block Align) 1 - 65,535 (2 байт)
wav_int[32] = 0x01; //0x01 1 bytes/frame  //0x02 2 bytes/frame   
wav_int[33] = 0x00; //   
///////////////////////// Количество бит на выборку (Significant Bits Per Sample) 1 - 65,535 (2 байт)
wav_int[34] = 0x08; //0x08 8 бит на выборку //0x10 16 бит на выборку
wav_int[35] = 0x00; // 
///////////////////////// Секция данных ("data")
wav_int[36] = 0x64; // d
wav_int[37] = 0x61; // a
wav_int[38] = 0x74; // t 
wav_int[39] = 0x61; // a
///////////////////////// dword 01 ED 00 = 126.208
wav_int[40] = 0x00; // 
wav_int[41] = 0xED; //   
wav_int[42] = 0x01; //   
wav_int[43] = 0x00; //   
/////////////////////////////////////////////////////////////// Data = 126.208
///////////////////////// Data...

да... в заголовке надо указывать длину файла...

причём делается это хитро))

длина заголовка (на сколько помню) постоянная = 44 байта.

а внутри куча длин... и считаются они на сколько помню просто:

1.
число 126.252 - в нашем случае это общая длина файла (Data + заголовок) - записываем в первые 4 байта > RIFF (4 байт)
2.
затем отнимаем 8 и получаем число 126.244 - записываем в следующие 4 байта > Data Size (4 байт)
3.
затем отнимаем 32 и получаем число 126.208 - записываем в следующие 4 байта > dword (4 байт)
:roll:
короче... х.з. )) я уже не помню как я это делал)) надо смотреть даташит))
:tea:

Добавлено after 11 minutes 27 seconds:
но смысл ясен...
надо перед тем как закрыть файл ещё раз проверить длину...
E_raf.seek(EEPROM_len);
потом всё посчитать))
...
...
...
потом установить курсор в нужный байт и записать полученные значения в заголовок.
E_raf.seek(EEPROM_len - Data Size);
...
E_raf.seek(EEPROM_len - dword);
...
потом закрыть файл.
E_raf.close();
:tea:
как-то так)) не помню))

к слову примерно так делает компьютер когда пишет файл на диск...
там файловая система типа FAT-32... там заголовок просто пипец))
Screenshot_1.jpg
(84.25 KiB) Скачиваний: 26

и всё это комп делает каждый раз за тебя))
ему ещё сложней))
:))

Re: Ардуино - запись звука

Сб сен 02, 2023 14:48:08

всё таки мы его подключили)) мой старенький андроид))
комп_андроид.jpg
(179.79 KiB) Скачиваний: 31

8)
16 бит * 16000 семплов = 256000 бит/c... по Wi-Fi... полный дуплекс )) и это ещё не предел))

только микрофон в андроиде низкого качества... надо подключать внешнюю гарнитуру...
потом переключаешь андроид в режим STREAM_MUSIC и получаешь удовольствие от высокого качества общения по телефону))
:tea:

надо ещё прогнать во всех режимах... больше всего беспокоит выбег частоты синхронизации... и как с этим бороться))
:roll:

Добавлено after 25 minutes 18 seconds:
что то я не понял
1 мб это всегг 15 сек

а что тут не понятно))
сколько ты указал длину файла в заголовке ?
Код:
E_raf.writeByte(0x00);E_raf.writeByte(0xED);E_raf.writeByte(0x01);E_raf.writeByte(0x00);

а сколько это байт ?

Data = 00 01 ED 00 = 126.208 байт / 8000 байт/сек = 15,776 сек.

твой плеер будет играть 15,776 сек.
:tea:

Re: Ардуино - запись звука

Вс сен 03, 2023 12:34:47

да, все верно. Спасибо Роман. Не вчитываюсь иногда толком что вы пишите и теряю время на точто бы самому разобраться, что впрочем иногда бывает не лишшним

Заодно понял как работает запись. Оказывается файл пересохраняется при каждой порции байт.
Поэтому я решил не заморчиваться:
1. не стал добавлять заголовок, просто преобразовал к заголовку первый 44 байта. (у меня не студия звукозаписи)
перед закрытием файла просто добавляю этот код:
он преобразует первые 44 байта в заголовок и расчитывает текущие размеры и поправляет их начиная с 4 байта и с 40 байта.

Код:
///////////////////////////////////////// запись файла EEPROM:
//курсор
E_raf.seek(EEPROM_len); //
long startTime = System.currentTimeMillis(); // Засекаем начало записи
for (xE=0; xE<RX_len; xE++) {       
  E_raf.writeByte(RX_int[xE]);// > write() // HEX     
};

// преобразуем в заголовок первый 44 байта

E_raf.seek(0);
  E_raf.writeByte(0x52);E_raf.writeByte(0x49);E_raf.writeByte(0x46);E_raf.writeByte(0x46);// > write() // HEX 
E_raf.writeByte(0x00);E_raf.writeByte(0x00);E_raf.writeByte(0x00);E_raf.writeByte(0x00);
E_raf.writeByte(0x57);E_raf.writeByte(0x41);E_raf.writeByte(0x56);E_raf.writeByte(0x45);
E_raf.writeByte(0x66);E_raf.writeByte(0x6D);E_raf.writeByte(0x74);E_raf.writeByte(0x20);
E_raf.writeByte(0x10);E_raf.writeByte(0x00);E_raf.writeByte(0x00);E_raf.writeByte(0x00);// > write() // HEX 
E_raf.writeByte(0x01);E_raf.writeByte(0x00);E_raf.writeByte(0x01);E_raf.writeByte(0x00);
E_raf.writeByte(0x40);E_raf.writeByte(0x1f);E_raf.writeByte(0x00);E_raf.writeByte(0x00);
E_raf.writeByte(0x40);E_raf.writeByte(0x1f);E_raf.writeByte(0x00);E_raf.writeByte(0x00);


E_raf.writeByte(0x01);E_raf.writeByte(0x00);E_raf.writeByte(0x08);E_raf.writeByte(0x00);
E_raf.writeByte(0x64);E_raf.writeByte(0x61);E_raf.writeByte(0x74);E_raf.writeByte(0x61);

E_raf.writeByte(0x00);E_raf.writeByte(0x00);E_raf.writeByte(0x00);E_raf.writeByte(0x00);   

long endTime = System.currentTimeMillis(); // Засекаем конец записи
///////////////////////////////////////// закрываем файл EEPROM:
//закрываем файл


/// close
long fileSize = E_raf.length();
System.out.println("Файл " + fileSize + ": " + E_raf.length() + " CLOSED");
// Переместитесь к 4-му байту в файле, где начинается поле размера файла
E_raf.seek(4);

// Запишите размер файла в формате little-endian
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putInt((int) fileSize);

//Получите массив байтов из ByteBuffer
byte[] byteArray = buffer.array();

//Преобразуйте массив байтов в строку в шестнадцатеричном формате
StringBuilder hexString = new StringBuilder();
for (byte b : byteArray) {
    hexString.append(String.format("%02X ", b));
}

// Выведите строку в шестнадцатеричном формате
System.out.println(hexString.toString().trim());

E_raf.write(buffer.array());


E_raf.seek(40);

//Запишите размер файла в формате little-endian
ByteBuffer buffer40 = ByteBuffer.allocate(4);
buffer40.order(ByteOrder.LITTLE_ENDIAN);
buffer40.putInt((int) fileSize-44);
E_raf.write(buffer40.array());

E_raf.close(); 
long elapsedTime = endTime - startTime;
//System.out.println("startTime: " + startTime + " //.");
//System.out.println("endTime: " + endTime + " //.");
//System.out.println("elapsedTime: " + elapsedTime + " //.");
///System.out.println("EEPROM_len: " + EEPROM_len + " //.");
//double writeSpeed = (double) EEPROM_len / (elapsedTime / 1000.0);
//System.out.println("Запись " + EEPROM_len + " байт в файл заняла " + elapsedTime + " мс.");
//System.out.println("Скорость записи: " + writeSpeed + " байт/сек.");
}catch(IOException e){

}
}
/////////////////////////////////////////// TX EEPROM END
} // TX_EEPROM
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////// RX_EEPROM:
public static void RX_EEPROM() {
EEPROM_len = 0;              //сброс EEPROM_len     
////////////////////////////////////////////////////////RX: EEPROM:
// ASCII UTF-8 !!! HEX
try 
{
//"rw" -файл открыт для чтения и записи (если файла нет, то файл будет создан "w").
//"r" -файл открыт для чтения (если файла нет, error).
RandomAccessFile E_raf = new RandomAccessFile("d:/Java.txt", "r");//w
///////////////////////////////////////////проверка файла EEPROM:
//EEPROM_len = E_raf.length();     //Возвращает длину файла EEPROM long
/////////////////////////////////////////курсор EEPROM:
E_raf.seek(0);   
/////////////////////////////////////////читаем файл EEPROM:
for (xE=0; xE<RX_len; xE++) {       
  RX_int[xE] = E_raf.read();          //raf.read() > E_int //возвращает HEX или -1   
};
/////////////////////////////////////////// закрываем файл EEPROM
//закрываем файл


Добавлено after 31 minute 47 seconds:
Роман , вы не пробовали сделать из этого приложения standalone


Изображение


что то у меня не получается.

Re: Ардуино - запись звука

Вс сен 03, 2023 13:50:13

Код:
// преобразуем в заголовок первый 44 байта

E_raf.seek(0);
  E_raf.writeByte(0x52);E_raf.writeByte(0x49);E_raf.writeByte(0x46);E_raf.writeByte(0x46);// > write() // HEX
E_raf.writeByte(0x00);E_raf.writeByte(0x00);E_raf.writeByte(0x00);E_raf.writeByte(0x00);
E_raf.writeByte(0x57);E_raf.writeByte(0x41);E_raf.writeByte(0x56);E_raf.writeByte(0x45);
E_raf.writeByte(0x66);E_raf.writeByte(0x6D);E_raf.writeByte(0x74);E_raf.writeByte(0x20);
E_raf.writeByte(0x10);E_raf.writeByte(0x00);E_raf.writeByte(0x00);E_raf.writeByte(0x00);// > write() // HEX
E_raf.writeByte(0x01);E_raf.writeByte(0x00);E_raf.writeByte(0x01);E_raf.writeByte(0x00);
E_raf.writeByte(0x40);E_raf.writeByte(0x1f);E_raf.writeByte(0x00);E_raf.writeByte(0x00);
E_raf.writeByte(0x40);E_raf.writeByte(0x1f);E_raf.writeByte(0x00);E_raf.writeByte(0x00);

:roll:

я обычно сначала создаю отдельный массив... в нашем случае массив "заголовок"

Код:
// массив "заголовок"
static int [] wav_int = {
/////////////////////////////////////////////////////////////// Data = 126.252 -8
///////////////////////// RIFF (4 байт)
0x52; // R
0x49; // I
0x46; // F
0x46; // F
///////////////////////// Data Size (4 байт) 00 01 ED 24 = 126.244
0x24; //
0xED; //   
0x01; //
0x00; //
/////////////////////////////////////////////////////////////// Data = 126.244 -32
///////////////////////// WAVE (4 байт)
0x57; // W
0x41; // A
0x56; // V
0x45; // E
///////////////////////// секция формата ("fmt") (4 байт)
0x66; // f
0x6D; // m
0x74; // t
0x20; //
///////////////////////// Data Size (4 байт)
0x10; //
0x00; //
0x00; //
0x00; //
///////////////////////// Код сжатия (Compression Code)   1 - 65,535 (2 байт) 1 = PCM/uncompressed
0x01; // PCM/uncompressed
0x00; //
///////////////////////// Количество каналов (Number of Channels) 1 - 65,535 (2 байт) 1 моно, 2 стерео
0x01; // 1 mono // 2 стерео
0x00; //
///////////////////////// Скорость выборок (Sample Rate) 1 - 0xFFFFFFFF (4 байт) 1F 40 = 8000
0x40; //0x40 8000 семпл в секунду
0x1F; //0x1F 8000 семпл в секунду
0x00; //
0x00; //   
///////////////////////// Среднее количество байт в секунду (Average Bytes Per Second) 1 - 0xFFFFFFFF (4 байт) 3E 80 = 16000
0x40; //0x40 8000  //0x80 16000  байт в секунду
0x1F; //0x1F 8000  //0x3E 16000  байт в секунду
0x00; //   
0x00; //   
///////////////////////// Количество байт на одну выборку (Block Align) 1 - 65,535 (2 байт)
0x01; //0x01 1 bytes/frame  //0x02 2 bytes/frame   
0x00; //   
///////////////////////// Количество бит на выборку (Significant Bits Per Sample) 1 - 65,535 (2 байт)
0x08; //0x08 8 бит на выборку //0x10 16 бит на выборку
0x00; //
///////////////////////// Секция данных ("data")
0x64; // d
0x61; // a
0x74; // t
0x61; // a
///////////////////////// dword 01 ED 00 = 126.208
0x00; //
0xED; //   
0x01; //   
0x00; //   
/////////////////////////////////////////////////////////////// Data = 126.208
///////////////////////// Data...
};


потом пеняю в массиве нужные байты...

Код:
wav_int[40] = 0x00; //
wav_int[41] = 0xED; //   
wav_int[42] = 0x01; //   
wav_int[43] = 0x00; //


потом записываю весь массив в файл...

Код:
   
   ///////////////////////////////////////// запись файла EEPROM:
   //курсор
   E_raf.seek(0);   
   for (xE=0; xE<44; xE++) {       
     E_raf.writeByte(wav_int[xE]); //E_int > write() // HEX     
   };


оно мне так кажется более логичным)) чем менять по одному байту в самом файле...
:tea:

Добавлено after 15 minutes 17 seconds:
жмём "экспорт"
Screenshot_1.jpg
(109.27 KiB) Скачиваний: 19

-выбираем какой проект хотим сохранить - Dom_1
-пишем имя - Dom
-выбираем куда сохранить - D:\Dom.jar
Screenshot_2.jpg
(105 KiB) Скачиваний: 24

проект Dom_1 скомпилирован в файл D:\Dom.jar
Screenshot_3.jpg
(3.45 KiB) Скачиваний: 22

:tea:

Re: Ардуино - запись звука

Вс сен 03, 2023 13:56:03

да, но получившийся проект jar у меня не работает, запускается, черное окно , которое сразу же закрывается

Re: Ардуино - запись звука

Вс сен 03, 2023 14:20:33

у меня всё работает...
:dont_know:
может JRE не та...
для открытия файла D:\Dom.jar используется JRE (у меня jre-8)... которая обычно встроена в JDK (у меня jdk-7)... но можно скачать отдельно JRE...
х.з.))
:dont_know:

Добавлено after 5 minutes 43 seconds:
продолжаем ломать мой старенький андроид))
комп_андроид.jpg
(179.79 KiB) Скачиваний: 25

надо ещё прогнать во всех режимах... больше всего беспокоит выбег частоты синхронизации... и как с этим бороться))

пока проблем не замечено...
:tea:

Добавлено after 5 minutes 47 seconds:
roman.com писал(а):16 бит * 16000 семплов = 256000 бит/c... по Wi-Fi... полный дуплекс )) и это ещё не предел))

а с этим проблема))
:roll:

в режиме воспроизведения андроид поддерживает
8000,11025,16000,22050,44100
16,8 бит
8)

в режиме записи андроид поддерживает только
8000,11025,16000
16 бит
:?

фигово)) а хотелось не только слушать... но и записывать в высоком качестве))
значит в караоке попеть не получится))

говорил же что все андроиды - тупые !!!

другое дело комп - работает в любых режимах и во всех форматах !!!
:tea:

Re: Ардуино - запись звука

Вс сен 03, 2023 17:33:30

да, была проблема, 2 явы стоит, одна лишняя. jar файл получил.
И, что интересно, запустил еге под JAVA 1.8, хотя в эклипсе он под этой средой не хотел запускаться

Re: Ардуино - запись звука

Вс сен 03, 2023 20:55:18

доделываем андроид...
пока всю хорошо))
:roll:

а вообще... тема на называется "Ардуино - запись звука"
когда будем ломать Ардуино ?
:))

Re: Ардуино - запись звука

Пн сен 04, 2023 07:45:25

да, верно, звук идет сейчас c esp8266 по wifi

Изображение

но ситуация снова выводит меня в Андроид. Так отдавать файлы людям небезопасно. И врядли хотя бы один хостер даст мне возможность поставить эту прогу на свой сервер. Так что снова придется пилить приложения для Андроид.
Ответить