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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 25.08.2014, 01:58   #1
tromani
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 23
По умолчанию Запись нескольких звуковых дорожек

Доброго времени.

Помогите пожалуйста со следующей задачей:

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

Надо вот этот весь результат запихать в wav, т.е. наложить все 10 дорожек друг на друга в разной громкости и записать... причем пользователь может выбрать с какой секунды каждая стартует и если запись дошла в моменте до конца файла файл стартует по новой

Гугль не помог, пишу тут, даже с чего начать не знаю

Заранее спасибо
tromani вне форума Ответить с цитированием
Старый 26.08.2014, 08:39   #2
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Используйте Аудиоредактор
Дельфи приплетать сюда - дороже выйдет ( по времени так уж гарантированно).
phomm вне форума Ответить с цитированием
Старый 26.08.2014, 14:35   #3
tromani
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 23
По умолчанию

да если б так можно было не заморачивался бы поверьте) там на разных треках громкость регулируется согласно определенной функции, и весь результат надо записать
tromani вне форума Ответить с цитированием
Старый 26.08.2014, 23:37   #4
blackstrip
Форумчанин
 
Аватар для blackstrip
 
Регистрация: 21.01.2012
Сообщений: 240
По умолчанию

10 дорожек - это тоже WAV-файлы?

Если отбросить моменты загрузки исходных дорожек/сохранения конечного результата, то задача решается так:

1) Выбираем длительность конечного результата, например, T = 10 секунд.
2) Выбираем частоту дискретизации конечного результата (11025, 22050, 44100 Гц или любая другая частота дискретизации), например, Fдискр = 44100 Гц.
3) Выбираем разрядность конечного результата. Если 8 бит - то каждый отсчет звука будет числом от -128 до 127, а если 16 бит - то числом от -32768 до 32767. Например, B = 16 бит.
4) Выбираем количество каналов (моно или стерео) конечного результата. Например, моно, это 1 канал.

Длина (количество элементов, отсчетов) массива конечного результата, состоящего из одного 16 битного канала с частотой дискретизации 44100 Гц будет равна:
N = T / период_дискретизации = T * Fдискр
где период_дискретизации - время, которое занимает один отсчет при проигрывании.

Т.е. 1 секунда звука при Fдискр = 44100 Гц будет занимать 44100 отсчетов. Мы хотели 10 секунд записать, это будет 10 * 44100 = 441000 отсчетов (элементов массива).

Размер каждого элемента массива зависит от битности. Из хелпа дельфи:
Shortint -128..127 signed 8-bit
Smallint -32768..32767 signed 16-bit

По хорошему, для 8-битного звука используем массив типа shortint, а для 16-битного - smallint. Но можно сделать просто integer, потому что потом будут ньюансы.

Делаем динамический массив integer размером 441000 элементов. Первую дорожку тупо записываем в этот массив, чтобы инициализировать его первый раз. Пробегаемся for i := 0 to 440999 do по всем элементам массива конечного результата. Причем пишем что a[i] := b[i mod length(b)], чтоб зацикливать массив дорожки b в массиве конечного результата a.

Остальные дорожки приплюсовываем также в том же цикле, получаем:

Код:
for i := 0 to length(a)-1 do
begin
a[i] := b[i mod length(b)];
a[i] := a[i] + c[i mod length(c)];
a[i] := a[i] + d[i mod length(d)];
a[i] := a[i] + e[i mod length(e)];
a[i] := a[i] + f[i mod length(f)];
//и т.д. для всех 10 дорожек
end;
И потом, в самом конце, перед записью этих значений - придется их обрезать, чтоб умять в 8-битные или 16-битные значения. Пробегаемся в цикле по всем элементам массива конечного результата a. Все что ниже -128/-32768 станет равным -128/-32768 (через слеш пишу для 8 и 16 бит, соответственно). А все что выше 127/32767 станет равным 127/32767.

Для 16 бит:
Код:
for i := 0 to length(a)-1 do
begin
a[i] := b[i mod length(b)];
a[i] := a[i] + c[i mod length(c)];
a[i] := a[i] + d[i mod length(d)];
a[i] := a[i] + e[i mod length(e)];
a[i] := a[i] + f[i mod length(f)];
//и т.д. для всех 10 дорожек
if a[i]<-32768 then a[i]:=-32768;
if a[i]>32767 then a[i]:=32767;
end;
После этого массив конечного результата a готов к записи в WAV-файл результата.
blackstrip вне форума Ответить с цитированием
Старый 26.08.2014, 23:47   #5
blackstrip
Форумчанин
 
Аватар для blackstrip
 
Регистрация: 21.01.2012
Сообщений: 240
По умолчанию

Это я ситуацию описал для всех дорожек с первого отсчета. А если пользователь выбирает стартовое время для каждой дорожки, то:

1) считаем номер отсчета N1 для старта 1 дорожки: N1 = Tстарта1 * Fдискр.
2) считаем номер отсчета N2 для старта 2 дорожки: N2 = Tстарта2 * Fдискр.
3) считаем номер отсчета N3 для старта 3 дорожки: N3 = Tстарта3 * Fдискр.
и т.д. для каждой из 10 дорожек.

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

А чтоб дорожки начинались со своих N1,N2,N3 отсчетов с первого отсчета дорожки - вводим доп.смещение по отсчетам и условие суммирования только по достижении N1,N2,N3 отсчета, соответственно:
if i>=N1 then a[i] := a[i] + b[(i-N1) mod length(b)];

Т.е. если текущий отсчет больше или равен стартовому отсчету - то плюсуем дорожку к результату. Когда i=N1 - то плюсуем первый элемент массива дорожки, т.к. (i-N1) = 0. Когда i=N1+1 - то плюсуем второй элемент массива дорожки, т.к. (i-N1) = (N1+1-N1) = 1. И т.д.

Получаем:

Код:
for i := 0 to length(a)-1 do
begin
a[i] := 0;
if i>=N1 then a[i] := a[i] + b[(i-N1) mod length(b)];
if i>=N2 then a[i] := a[i] + c[(i-N2) mod length(c)];
if i>=N3 then a[i] := a[i] + d[(i-N3) mod length(d)];
if i>=N4 then a[i] := a[i] + e[(i-N4) mod length(e)];
if i>=N5 then a[i] := a[i] + f[(i-N5) mod length(f)];
//и т.д. для всех 10 дорожек
if a[i]<-32768 then a[i]:=-32768;
if a[i]>32767 then a[i]:=32767;
end;

Последний раз редактировалось blackstrip; 26.08.2014 в 23:52.
blackstrip вне форума Ответить с цитированием
Старый 27.08.2014, 10:47   #6
tromani
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 23
По умолчанию

Спасибо, теперь бы еще понять как как исходные дорожки попали в массивы b,c,d... и что надо менять в b,c,d чтоб регулировать % от исходной громкости соответствующих b,c,d
tromani вне форума Ответить с цитированием
Старый 27.08.2014, 12:52   #7
blackstrip
Форумчанин
 
Аватар для blackstrip
 
Регистрация: 21.01.2012
Сообщений: 240
По умолчанию

А откуда в задаче берутся дорожки? Из WAV файлов или еще откуда? И еще вопрос - исходные дорожки и результат имеют одинаковые параметры: частоту дискретизации, разрядность и количество каналов? Если отличаются, то придется их сперва привести к параметрам результата, а потом уже проводить суммирование всех дорожек.

А громкость легко регулировать вот так:
Пусть громкость первой дорожки это V1 от 0 до 1 (float число, 0 - это нулевая громкость, 1 - это 100% громкость), громкость второй дорожки это V2 от 0 до 1 (тоже float) и т.д. Цифры в массивах дорожек это амплитуда колебаний. Громкость - это тоже амплитуда. Соответственно, 50% громкость - это все элементы массива дорожки поделить на 2. 10% громкость - это все элементы дорожки поделить на 10. Следовательно, в цикл добавляются эти громкости, на них просто домножаются все элементы массивов дорожек:

Код:
for i := 0 to length(a)-1 do
begin
a[i] := 0;
if i>=N1 then a[i] := a[i] + b[(i-N1) mod length(b)] * V1;
if i>=N2 then a[i] := a[i] + c[(i-N2) mod length(c)] * V2;
if i>=N3 then a[i] := a[i] + d[(i-N3) mod length(d)] * V3;
if i>=N4 then a[i] := a[i] + e[(i-N4) mod length(e)] * V4;
if i>=N5 then a[i] := a[i] + f[(i-N5) mod length(f)] * V5;
//и т.д. для всех 10 дорожек
if a[i]<-32768 then a[i]:=-32768;
if a[i]>32767 then a[i]:=32767;
end;
blackstrip вне форума Ответить с цитированием
Старый 04.09.2014, 17:47   #8
tromani
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 23
По умолчанию

Да спасибо, попробовал, все хорошо, все ок, даже получилось распихать дорожки по разным каналам, для общего развития хорошо, но если честно не совсем то что мне нужно:

Нужно вот что
у пользователя есть возможность выбрать 10 файлов звуковых и 1 кнопка плэй, возле каждого из 10 есть свой трэкбар (регулятор громкости)
при нажатии на плэй начинается одновременное воспроизведение всех 10 дорожек, зацикленно
время проигрывания понятно неизвестно заранее. пока не нажмет "стоп"
в течении воспроизведения пользователь может менять громкость любой дорожки.
есть еще кнопка запись - при ее нажатии начинает это все записываться ну и функционал тотже даже во время записи можно менять громкость...

вот, буду благодарен за помощь, ну или хотябы направление в котором двигаться...
я так сам думал может использовать какойто из готовых плееров (медиаплеер стандартный врядли так может) который умеет записывать то что воспроизводит на той громкости которую задает пользователь и повесить 10 таких плееров на форму а потом уже по указанному выше способу объединить все 10 полученных файлов...
tromani вне форума Ответить с цитированием
Старый 04.09.2014, 21:39   #9
tromani
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 23
По умолчанию

из всего нарытого в интернете наверно bass.dll мне в помощь, осталось понять как с ее помощью все это замиксить
tromani вне форума Ответить с цитированием
Старый 13.09.2014, 08:12   #10
Alteranin
Новичок
Джуниор
 
Регистрация: 13.09.2014
Сообщений: 1
По умолчанию

мне она тоже помогла, спс всем за подсказку Dj TFK-VIK
Dj TFK-VIK
Alteranin вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
StringGrid чтение из одного файла нескольких таблиц и запись Senya23 Компоненты Delphi 10 09.10.2013 22:31
Чтение и запись нескольких Memo в txt flouwjke Помощь студентам 2 29.04.2012 16:54
Форматы звуковых файлов JohannPalich Мультимедиа в Delphi 6 13.02.2012 23:00
Соединение звуковых файлов tonatas Мультимедиа в Delphi 5 04.02.2011 23:32
Запись в несколько таблиц нескольких записей Лубышев SQL, базы данных 8 09.04.2010 17:42