Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.01.2012, 17:38   #1
cactus628
 
Регистрация: 04.01.2012
Сообщений: 8
Вопрос Трансляция звука по локальной сети (UDP и BASS.DLL)

Получилась программа, которая передает звук с микрофона в сеть и принимает его. Теперь надо сделать такую же передачу, но не с микрофона, а из файла (не весь файл, а по принципу радио). Исходники прикреплены (прием, думаю, останется такой же, на до сделать передачу). Как нарезать и с нужной скоростью передать звуковой файл?
Вложения
Тип файла: rar send_mic.rar (302.6 Кб, 405 просмотров)
Тип файла: rar get.rar (299.2 Кб, 310 просмотров)
cactus628 вне форума Ответить с цитированием
Старый 10.02.2012, 23:23   #2
MC-Sergey
 
Регистрация: 02.02.2012
Сообщений: 4
По умолчанию

Идея хорошая.
Сам давно хотел сделать что-то подобное.
Но есть одна проблема.
Если с буфером еще понятно решение, то что делать с щелчками при воспроизведении принятых пакетов?
Ты(или не ты), вроде где то писал что решил эту проблему. Не поделишься секретом?
Не обязательно код. Хотя бы принцип.
Спасибо.
MC-Sergey вне форума Ответить с цитированием
Старый 14.02.2012, 15:27   #3
cactus628
 
Регистрация: 04.01.2012
Сообщений: 8
По умолчанию

нет. я, к сожалению, так и не решил эту проблему. все мои наработки со звуком и UDP прикреплены
cactus628 вне форума Ответить с цитированием
Старый 21.02.2012, 18:32   #4
MC-Sergey
 
Регистрация: 02.02.2012
Сообщений: 4
Лампочка

Цитата:
Сообщение от cactus628 Посмотреть сообщение
нет. я, к сожалению, так и не решил эту проблему. все мои наработки со звуком и UDP прикреплены
рассматривал ли ты работу по TCP протоколу? почему UDP?
может есть смысл перейти на TCP с использованием буфера...
MC-Sergey вне форума Ответить с цитированием
Старый 22.02.2012, 09:17   #5
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Если хочешь транслировать звуковой файл Wav по сети, просто открывай и отправляй его, но этот пример для малых по размеру файлов
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
 f : File;
 I, Length: integer;
 FileName: String;
  Buffer: Pointer;
begin
if OpenDialog1.Execute then
begin
FileName:= OpenDialog1.FileName;
  {$I-}
   AssignFile(f, FileName);
   FileMode := fmOpenReadWrite;
   Reset (f, 1);
   {$I+}
   i:=IOResult;
   if i > 0 then
   begin
   Showmessage(Format('Ошибка: Неудалось открыть файл %s',[FileName]));
   exit;
   end;
  //Определяем размер всего файла
  length:=filesize(f);
  if length=0 then
  begin
  Showmessage(Format('Ошибка: Неудалось открыть файл %s т.к. размер %d',[FileName, Length]));
   exit;
  end;
  //создаем буфер
 getmem(Buffer, length);
 //Читаем файл и записываем в буфер данные
 BlockRead(f, Buffer^, length);
 //Закрываем файл
 CloseFile(f);
 //отправляем файл данные которого уже в буфере
if IdUDPClient1.Active then
 IdUDPClient1.SendBuffer(buffer^,length);
 //Уничтожаем буфер
 freeMem(Buffer);
 end;
end;
открывать в программе приемник можно так:
Код:
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var
  Buffer: Pointer;
  Size: integer;
chan:    HSTREAM;	// playback channel
begin
Size:=AData.Size;
GetMem(Buffer, Size);
AData.Position:=0;
AData.Read(Buffer^, Size);
chan:=BASS_StreamCreateFile(true, Buffer, 0, AData.Size, 0);
BASS.BASS_ChannelPlay(chan,false);
end;

Насчет mp3 почитай здесь http://www.programmersforum.ru/showthread.php?t=184813 там же и рассуждение про трансляцию по сети музыки
Я думаю что бы использовать законно mp3 по сети нужно создать сервер который будет отвечать запросам BASS_StreamCreateURL.

Последний раз редактировалось Aliens_wolfs; 22.02.2012 в 21:34.
Aliens_wolfs вне форума Ответить с цитированием
Старый 22.02.2012, 11:47   #6
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Посмотрел ваш проект по работе с микрофоном и сделал свой вариант по передаче звука по сети, можно воспроизводить по сети Wav файлы большого размера, файл будет играть на обоих компах

Должно быть объявленно в отправителе и в получателе.
Код:
type
  TWAVHDR = packed record
    riff:			array[0..3] of Char;
    len:			DWord;
    cWavFmt:		array[0..7] of Char;
    dwHdrLen:		DWord;
    wFormat:		Word;
    wNumChannels:	Word;
    dwSampleRate:	DWord;
    dwBytesPerSec:	DWord;
    wBlockAlign:	Word;
    wBitsPerSample:	Word;
    cData:			array[0..3] of Char;
    dwDataLen:		DWord;
  end;

Const
BufSize = 2048; //Размер буфера для отправления и получения звукрвых данных
 
Type
FFTData = array[0..BufSize] of byte; // Массив для получения данных 
chan:    HSTREAM;

var
FData: FFTDATA;
Код отправителя
Код:
//Открываем файл и воспроизводим при этом извлекаем данные и отправляем
procedure TForm1.Button1Click(Sender: TObject);
var
 f : File;
 I, Length: integer;
 FileName: String;
WHdr: TWAVHDR;
begin
if OpenDialog1.Execute then
begin
FileName:= OpenDialog1.FileName;
  {$I-}
   AssignFile(f, FileName);
   FileMode := fmOpenReadWrite;
   Reset (f, 1);
   {$I+}
   i:=IOResult;
   if i > 0 then
   begin
   Showmessage(Format('Ошибка: Неудалось открыть файл %s',[FileName]));
   exit;
   end;
  //Определяем размер всего файла
  length:=filesize(f);
  if length=0 then
  begin
  Showmessage(Format('Ошибка: Неудалось открыть файл %s т.к. размер %d',[FileName, Length]));
   exit;
  end;
 //Читаем файл и записываем в буфер данные заголовка
 BlockRead(f, WHdr, SizeOf(TWAVHDR));
 //Закрываем файл
 CloseFile(f);
//отправляем заголовок файла
if IdUDPClient1.Active then
 IdUDPClient1.SendBuffer(WHdr, SizeOf(TWAVHDR));

//Освобождаем канал для нового файла
BASS_StreamFree(chan);
//Создаем канал
Chan:= BASS_StreamCreateFile(false, PChar(FileName), 0, 0, 0);
Timer1.Interval:=100;
Timer1.Enabled:=true;
//Воспроизводим файл
bass_channelplay(Chan, false);
 end;
end;

//Следим за состояним канала и отправляем данные если воспроизведение
procedure TForm1.Timer1Timer(Sender: TObject);
var
iActiv: Dword;
begin
//Статус Трэка
iActiv:= BASS_ChannelIsActive(Chan);
Case iActiv of
//Если файл играет то отправляем данные по BufSize байт
 BASS_ACTIVE_PLAYING:
if IdUDPClient1.Active then
begin
 BASS_ChannelGetData(Chan, @FData, BufSize);
 IdUDPClient1.SendBuffer(FData, BufSize);
 end;
 end;
end;
Код получателя
Код:
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var
WHdr: TWAVHDR;
Flag: DWORD;
begin
// Сначала получаем заголовок чтобы узнать параметры звука
AData.Position:=0;
AData.Read(WHdr, SizeOf(TWAVHDR));
//Проверяем заголовок или данные
If WHdr.riff='RIFF' then
begin
//Освобождаем канал для нового файла
BASS_StreamFree(chan);
//Создаем канал с параметрами из заголовка файла
Flag:=0;
if WHdr.wBitsPerSample=8 then
Flag:= BASS_DEVICE_8BITS;
if WHdr.wNumChannels=1 then
Flag:=Flag or BASS_DEVICE_MONO;
Chan:=  BASS_StreamCreate(WHdr.dwSampleRate, WHdr.wNumChannels, Flag, STREAMPROC_PUSH, nil);
end
else
begin
//Работаем с каналом
AData.Position:=0;
AData.Read(FData, BufSize);
BASS_StreamPutData(chan,@FData, BufSize);
BASS_ChannelPlay(chan, False);
end;
end;
Проверил работает), легко можно переделать для TCP

Последний раз редактировалось Aliens_wolfs; 23.02.2012 в 00:22.
Aliens_wolfs вне форума Ответить с цитированием
Старый 22.02.2012, 23:52   #7
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

А вот придумал код универсальный, воспроизводит WAV и MP3 файлы по сети

Должно быть объявленно в передатчике и в приемнике.
Код:
type
 TWAVHDR = packed record
 VER:		   	array[0..3] of Char;
 INFO:      BASS_CHANNELINFO;
 end;
 
var
  chan:  HSTREAM;
  Form1: TForm1;

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
if (not BASS_Init(-1, 44100, 0, Handle, nil)) then
	begin
		BASS_Free();
		MessageDlg('Cannot start default device!', mtError, [mbOk], 0);
		Halt;
	end;
end;
Код передатчика
Код:
Const
BufSize = 32; //Размер буфера для отправления и получения звуковых данных

Type
FFTData = array[0..BufSize] of byte; // Массив для получения данных

var
  FData: FFTDATA;
 zPos: integer;

procedure TForm1.Button1Click(Sender: TObject);
var
 FileName: String;
 WHdr: TWAVHDR;
begin
//Открываем файл с помощью диалога
if OpenDialog1.Execute then
begin
FileName:= OpenDialog1.FileName;

//Освобождаем канал для нового файла
BASS_StreamFree(chan);
//Создаем канал из файла
Chan:= BASS_StreamCreateFile(false, PChar(FileName), 0, 0, 0);
//отправляем информацию о файле и указываем что это заголовок
WHdr.VER:='VER1';
BASS_ChannelGetInfo(Chan, WHdr.INFO);
if IdUDPClient1.Active then
IdUDPClient1.SendBuffer(WHdr, SizeOf(TWAVHDR));

//включаем таймер состояния канала
zPos:=0;
Timer1.Interval:=10;
Timer1.Enabled:=true;

//Воспроизводим файл
bass_channelplay(Chan, false);
end;
end;

//Следим за состояним канала и отправляем данные если воспроизведение
procedure TForm1.Timer1Timer(Sender: TObject);
var
iActiv: Dword;
iPos: Integer;
begin
//Статус Трэка
iActiv:= BASS_ChannelIsActive(Chan);
Case iActiv of
//Если файл играет то отправляем данные по BufSize байт
 BASS_ACTIVE_PLAYING:
if IdUDPClient1.Active then
begin
 BASS_ChannelGetData(Chan, @FData, BufSize);
  iPos:=BASS_ChannelGetPosition(Chan,0);
 //Проверка позиции воспроизведения и размера буфера
 if iPos > zPos  then
 begin
 zPos:= iPos+BufSize;
 IdUDPClient1.SendBuffer(FData, BufSize);
 end;
 end;
 end;
end;
Код приемника
Код:
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var
WHdr: TWAVHDR;
FData: Pointer;
begin
// Сначала получаем заголовок чтобы узнать параметры звука
AData.Position:=0;
AData.Read(WHdr, SizeOf(TWAVHDR));
//Проверяем заголовок или данные
If WHdr.VER='VER1' then
begin
//Освобождаем канал для нового файла
BASS_StreamFree(chan);
//Создаем канал с параметрами из заголовка файла
Chan:=  BASS_StreamCreate(WHdr.INFO.freq, WHdr.INFO.chans, WHdr.INFO.flags, STREAMPROC_PUSH, nil);
end
else
begin
//Работаем с данными канала и воспроизводим их
getMem(FData, AData.Size);
AData.Position:=0;
AData.Read(FData^, AData.Size);
BASS_StreamPutData(chan, FData, AData.Size);
BASS_ChannelPlay(chan, False);
freeMem(FData);
end;
Если будут прерывания в звуке то можно попробовать настроить BufSize в передатчике, а так же Timer1.interval и желательно использовать TCP соединение.

Последний раз редактировалось Aliens_wolfs; 23.02.2012 в 01:23.
Aliens_wolfs вне форума Ответить с цитированием
Старый 24.02.2012, 18:46   #8
MC-Sergey
 
Регистрация: 02.02.2012
Сообщений: 4
По умолчанию

Aliens_wolfs, сделал в точности как ты описал. В приемнике раздаются только щелчки при воспроизведении файла.
Увелисил BufSize - вроде что то заиграло. Буду дальше разбираться.
Не могу понять. Заикается. Зависит от значения таймера.

Последний раз редактировалось MC-Sergey; 24.02.2012 в 19:09.
MC-Sergey вне форума Ответить с цитированием
Старый 27.02.2012, 08:56   #9
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Вот програмка, в одной папке сервер который воспроизводит полученные данные звука, в другой клиент который воспроизводит и отправляет данные звука на сервер, с mp3 вроде неплохо когда сеть незагружена. Переделал на TCP лучше стала воспроизводить, использовал WinSock. На серверной нажать запустить, а в клиенте нажать подключить и выбрать файл, а так же ввести адрес сервера и выбрать с чем работать, микрофон или файл.
С микрофоном классно работает без прерывания сразу трансляция по сети.
Вложения
Тип файла: rar Sound_Lan.rar (646.7 Кб, 118 просмотров)

Последний раз редактировалось Aliens_wolfs; 27.02.2012 в 19:11.
Aliens_wolfs вне форума Ответить с цитированием
Старый 28.02.2012, 08:59   #10
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Обновил програмку
Вложения
Тип файла: rar Sound_Lan.rar (654.7 Кб, 438 просмотров)

Последний раз редактировалось Aliens_wolfs; 28.02.2012 в 12:14.
Aliens_wolfs вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
bass.dll аварийное завершение загрузки музыки из сети Mr_F Мультимедиа в Delphi 5 16.08.2013 19:45
Передача звука по сети с использованием UDP и BASS.DLL cactus628 Работа с сетью в Delphi 6 02.02.2012 14:11
Загрузка DLL из локальной сети (+ и -) astecenko Общие вопросы Delphi 3 18.08.2011 11:50
Bass.dll -непрерывное воспроизведение звука werrey Мультимедиа в Delphi 9 13.06.2011 15:23
Требование к воспроизведению звука по нажатию клавиши клавиатуры в Bass.dll Fluffy123 Мультимедиа в Delphi 8 15.05.2010 21:48