На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
Страницы: (4) 1 2 [3] 4  все  ( Перейти к последнему сообщению )  
> Запись потока с линейного входа , Разделить поток линейного входа на 2 разных в первом только левое моно, а во втором только правое моно
    Прикреплённый файлПрикреплённый файлM.rar (28.33 Кбайт, скачиваний: 210) Вот то, что я накидал..
      Цитата
      подумать над тем как при воспроизведении один (к примеру левый канал) сдублировать на правый(псевдо стерео)...

      Он и так будет псевдостерео, моно потоки по умолчанию в общий микс примешиваются в равных пропорциях в левый и правый каналы. Наоборот, для того, чтобы развести по "ушам" моно, понадобиться изменить баланс соотвествующего потока.
      Допустим, вы создаёте поток для воспроизведения(моно, он же псевдостерео):
      ExpandedWrap disabled
        chan:=BASS_StreamCreate(44100,1,0,STREAMPROC_PUSH,nil);

      Для того, чтобы загнать его полностью в левый канал, надо изменить баланс(панораму) потока:
      ExpandedWrap disabled
        BASS_ChannelSetAttribute(chan,BASS_ATTRIB_PAN,-1); // -1 - левый канал,  +1 - правый канал. 0 - центр.


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

      Я могу только примерно показать, как воспроизвести то, что вы записываете. Структуру программы - это вы сами.
      В StartRecording создайте поток для воспроизведения:
      ExpandedWrap disabled
            chan:=BASS_StreamCreate(44100,1,0,STREAMPROC_PUSH,nil);
            BASS_ChannelSetAttribute(chan,BASS_ATTRIB_PAN,-1); // баланс полностью выкрутить на левый канал
            p:=allocmem(16384);                           // згнать в поток пустой буфер длительностью где-то 0.2 с    
            Bass_StreamPutData(chan,P,16384);             // для того, чтобы звук не рвался
            freemem(p);                                    
            BASS_ChannelPlay(chan,false);          // запустить воспроизведение

      В StopRecording освобождаете:
      ExpandedWrap disabled
        BASS_ChannelStop(chan);
        BASS_StreamFree(chan);


      В RecordingCallback отправьте один из буферов, например, буфер левого канала, в поток воспроизведения:
      ExpandedWrap disabled
        BASS_StreamPutData(chan,buffer_L,length div 2);

      Можете отправить буфер на воспроизведение до изменения уровня сигнала, или после, отправить буфер левого или правого канала.
      На ваш вкус.

      Также в любой момент вы можете менять панораму для выбранного потока (воспроизведения) при помощи BASS_ChannelSetAttribute.

      Добавлено
      Цитата
      вот этот кусок дает мне индикатор, корректно?

      Не могу знать. Не знаю, для каких конкретно данных bass считает этот уровень, в справке не нашёл.
      А так, теоретически, вы получаете пиковый уровень на каком-то отрезке времени.
      Сообщение отредактировано: Prince -
        Цитата
        Вот то, что я накидал..

        Нет, что-то вы не то делаете.
        Файлы создаёте как бы моно. Потоки - стерео(но тоже как бы моно), и зачем-то два(?). И в кэлбеке неправильно выбираете данные канала.
          Попробовал замутить в примере ваши пожелания.
          Пока разбирался, столкнулся в очередной раз с интересной ситуацией. Она возникает, если использовать 2 девайса: с одного записывать, а выводить на другой. Поскольку устройства никак не синхронизированы, частоты их тактовых генераторов отличаются. Если частота тактового генератора(и частота дискретизации) устройства воспроизведения меньше частоты тактового генератора устройства записи, устройство воспроизедения не успевает воспроизводить всё, что ему отдаёт устройство записи, до получения очередной порции данных. Очередь воспроизведения постепенно и неуклонно растёт. Так получилось у меня. Выводил на блютуз нашники, записывал со встроенной карты ноутбука. В результате, за 1с в очереди воспроизведения набегает приблизительно 100 "неуспевших воспроизвестись" семплов. Очередь воспроизведения всё увеличивается, и задержка между тем, что записывается, и тем, что воспроизводится в данный момент, тоже. Оставил программу работать на сколько-то часов, и пока спал, получил вылет в Acces Violation.
          Чтобы это дело контролировать, специально вывел в строку статуса размер очереди воспроизведения каналов. Почитал справку по BASS_StreamPutData и выяснил примерно следущее: при каждом вызове BASS_StreamPutData сколько-то байт отправляется прямо в некий буфер воспроизведения канала(его размер можно регулировать, по умолчанию 500 мс), всё, что не влазит, записывается "в очередь" и учитывается внутри bass как-то отдельно. Поскольку в примере келбек канала записи срабатывает каждые примерно 10-50 мс, и в буфер каналов воспроизведения отсылаются кусочки такой же длительности, поначалу все данные влазят в буфер, и размер очереди(queue) каналов воспроизведения по нулям. Значения L/R_Queue по нулям. Спустя время буфер заполняется, и "хвосты" начинают появляться в queue.
          Если бы частота генератора устройства воспроизведения была больше, чем устройства записи, получилась бы другая картина: через время буфер воспроизведения опустел бы, и канал воспроизведения стал бы рвать звук.
          Чтобы избежать таких ситуаций, при работе с несколькими звуковыми картами придётся изобретать механизм "выравнивания" частот дискретизации, придётся либо прореживать периодически буфер воспроизведения, либо вставлять туда лишние семплы, в зависимости от разницы частот.
          Если записывать и воспроизводить на одном устройстве, таких проблем, в общем случае, не возникает.
          Прикреплённый файлПрикреплённый файлRecord_Playback_Test.rar (6.69 Кбайт, скачиваний: 223)
          Сообщение отредактировано: Prince -
            А ещё, даже связанные при помощи BASS_ChannelSetLink каналы, стартуют неодновременно. При прослушивании(Listen), если баланс каналов выставить по центру, на слух заметно "раздвоение" сигналов.
              Подскажите пожалуйста, что не правильно?
              var
              fTL:longint;
              fVolL:real;
              function RecordingCallbackL(Handle: HRECORD; buffer: Pointer; length: DWORD; user: Pointer): boolean; stdcall;
              var
              buffer_L: Pointer;
              psample: ^smallint;
              psample_L: ^smallint;
              i: cardinal;

              begin
              fTL := fTL + Length;

              buffer_L:=allocmem(length div 2);
              psample:=buffer;
              psample_L:=buffer_L;
              for i:=0 to length div 4-1 do
              Begin
              try
              psample_L^:=round(fVolL*psample^);
              except
              end;
              inc(psample);
              inc(psample_L);
              inc(psample);
              end;

              WaveStreamL.Write(buffer_L^, length div 2);
              freemem(buffer_L);
              Result := True;
              end;

              procedure TfrmMain.StartL;
              var s:string;
              begin
              if rchanL <> 0 then
              BASS_ChannelStop(rchanL);
              fVolL := cxVLeft.Position/100;
              with WaveHdr do
              begin
              wNumChannels := 1;
              wBlockAlign := 2;
              dwBytesPerSec := 88200;
              end;
              WaveStreamL := TFileStream.Create(b.RecLine1+getFileName('1'),fmcreate);
              WaveStreamL.Write(WaveHdr, SizeOf(WAVHDR));

              rchanL := BASS_RecordStart(44100, 2, 0, @RecordingCallbackL,nil);
              end;
              Выбивает ошибку...
              Прикреплённый файлПрикреплённый файлБезымянный.jpg (38.54 Кбайт, скачиваний: 622)
                Цитата
                Выбивает ошибку...

                В каком месте?

                По-человески было бы балансировку громкости и собственно громкость каналов регулировать при помощи функций микшера. Я сделал так как вы просили, т.е., чтобы можно было регулировать уровень звука в потоке, потому что вы спрашивали, как это сделать, и потому что bass, похоже, ничего не знает о выходных линиях микшера(а может, я просто не разобрался). Но в принципе, не проблема добавить управление балансом и уровнем записи, если сам микшер имеет контролы для таких манипуляций. Потому что если поток изначально записан перегруженым, уменьшай-не уменьшай уровень звука в нём, звук всё равно искаженным будет.

                Код в тег не забывайте оборачивать.


                Нет, Bass всё-таки знает про выходные линии микшера записи, они обозначаются у него индексом -1(минус один). А про то, что линии микшера могут иметь индивидуальные регулировки уровня для левого/правого каналов, bass не знает. У него есть только общая регулировка уровня для линии.
                Сообщение отредактировано: Prince -
                  из за того что fTL - время я определил как longint, ну в общем заменил на double перестало...
                  Спасибо вам большое! Без вас бы разбирался оочень долго...
                  Я подробно изучу то, что вы мне отправили, потом отпишусь
                    fTL:longint;
                    fTL := fTL + Length;
                    Поначалу тоже так подумал(что это неплохая идея), а потом прикинул, переполнение наступит через 6 часов записи(для беззнакового целого типа сardinal).

                    Добавлено
                    Цитата
                    из за того что fTL - время я определил как longint,

                    Странно, с чего бы... :scratch:

                    Время можно брать от часов вреального времени, а длину файлового потока из свойства tfilestream.size. Там тип int64, так что и переполнение можно не учитывать на всех вменяемых длительностях записи. Просто сначала надо было проконтролировать длительность кусочков, так и поехало.
                    Сообщение отредактировано: Prince -
                      Здорова! Ты был прав, там совсем не нужно было создавать несколько Rchan... все реализовал в одном...
                      Еще 2 вопроса..
                      1- Как отключить используя bass.dll звук линейного входа (ну к примеру запускаешь прогу на XP, и как подключил телефон через линейный выход, сразу идет вещание на выход)
                      2- Не понимаю почему, ооооч редко, но все же иногда вылетает исключение access violation при записи и одновременном прослушивании
                        Цитата
                        Как отключить используя bass.dll звук линейного входа

                        Для микшера воспроизведения, в типовой комплектации библиотеки такой возможности не нашёл(может, плохо искал).
                        Линии микшера записи можно дергать при помощи BASS_RecordSetInput. Включать, выключать, регулировать уровень сигнала.
                        Цитата
                        Не понимаю почему, ооооч редко, но все же иногда вылетает исключение access violation при записи и одновременном прослушивании

                        :-?
                        Сообщение отредактировано: Prince -
                          Спасибо тебе большое! Выручил! Ошибка выходила из-за ошибок в собственном коде... Все работает!
                            prince, не могу справиться с этой ошибкой... кстати, в том примере который ты скинул она тоже есть.. может из-за того что у меня win8 x64? напиши ко мне amanat_2007@mail.ru, помоги пожалуйста online
                              В каком месте дебагер ошибку показывает?
                                там такая ситуация...

                                ExpandedWrap disabled
                                  form.create:
                                    rchan := BASS_RecordStart(44100, 2,  10 shl 16, @RecordingCallback, nil);
                                   
                                  function RecordingCallback(Handle: HRECORD; buffer: Pointer; length: DWORD; user: Pointer): boolean; stdcall;
                                   
                                  var
                                    buffer_L  :Pointer;
                                    buffer_R  :Pointer;
                                   
                                    psample   :^smallint;
                                    psample_L :^smallint;
                                    psample_R :^smallint;
                                    i:             cardinal;
                                  begin
                                   
                                     buffer_L:=allocmem(length div 2);
                                     buffer_R:=allocmem(length div 2);
                                   
                                     psample:=buffer;
                                     psample_L:=buffer_L;
                                     psample_R:=buffer_R;
                                   
                                   
                                    for i:=0 to length div 4-1 do
                                    Begin
                                    psample_L^:=round(psample^);
                                    inc(psample);
                                   
                                    inc(psample_L);
                                    psample_R^:=round(psample^);
                                    inc(psample);
                                   
                                   
                                    inc(psample_R);
                                    end;
                                    freemem(buffer_L);
                                    freemem(buffer_R);
                                    Result := True;
                                  end;
                                   
                                  timer(200):
                                    TimerAll.Enabled := false;
                                    try
                                      inc(i);
                                      if i>2 then
                                        i:=1;
                                      if i=1 then
                                        begin
                                        cxGK1.Down := true;
                                        cxGK1Click(nil);
                                        end;
                                      if i=2 then
                                        begin
                                        cxGK2.Down := true;
                                        cxGK2Click(nil);
                                        end;
                                    finally
                                      TimerAll.Enabled := true;
                                    end;
                                  cxGK1Click:
                                    if cxGK1.Down then
                                        cxGK2.Down := false;
                                  cxGK2Click:
                                    if cxGK2.Down then
                                        cxGK1.Down := false;

                                Смысла не имеет данная прога... я упрощал по максимуму чтобы найти ошибку...
                                если запустить таймер и закоментировать rchan := BASS_RecordStart(44100, 2, 10 shl 16, @RecordingCallback, nil); ошибок нет
                                если выключить таймер ошибок так же нет
                                я использую компоненты devexspress...
                                у тебя в примере при отладке если нажимать быстро на checkbox listen, та же выходила...
                                но когда я откомпилировал и перенес на комп где win7 x86, ошибок не было

                                если можно взгляни пожалуйста по teamviewer
                                Прикреплённый файлПрикреплённый файлБезымянный.jpg (45.45 Кбайт, скачиваний: 586)
                                Сообщение отредактировано: D[u]fa -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (4) 1 2 [3] 4  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.1064 ]   [ 24 queries used ]   [ Generated: 12.07.26, 19:06 GMT ]