Страницы

Поиск по вопросам

Показаны сообщения с ярлыком аудио. Показать все сообщения
Показаны сообщения с ярлыком аудио. Показать все сообщения

понедельник, 13 апреля 2020 г.

Как программно измененить громкость звука в Windows?

#c #windows #winapi #windows_7 #аудио

                    
Как программно измененить громкость звука в Windows?

Можете написать пример?
Желательно, чтобы скомпилился  на minGW.  
    


Ответы

Ответ 1



Нашел хороший пример на MSDN: How to Use Wave Audio Volume Control APIs, есть как получение громкости, так и установка. Данный пример дает нужный результат на версиях WIndows ниже Vista. В Windows Vista и 7 были представлены новые API для работы с аудио, для изменения громкости глобально нужно использовать интерфейс IAudioEndpointVolume. Небольшой пример использования есть также в MSDN и на CodeProject:

Ответ 2



Анимированое изменение звука системы Win7 C++ visual studio 10 #include #include #include #pragma comment(lib, "ole32.lib") //extern bool ChangeVolume(double nVolume,bool bScalar) { HRESULT hr=NULL; bool decibels = false; bool scalar = false; double newVolume=nVolume; CoInitialize(NULL); IMMDeviceEnumerator *deviceEnumerator = NULL; hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator); IMMDevice *defaultDevice = NULL; hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice); deviceEnumerator->Release(); deviceEnumerator = NULL; IAudioEndpointVolume *endpointVolume = NULL; hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume); defaultDevice->Release(); defaultDevice = NULL; // ------------------------- float currentVolume = 0; endpointVolume->GetMasterVolumeLevel(¤tVolume); //printf("Current volume in dB is: %f\n", currentVolume); hr = endpointVolume->GetMasterVolumeLevelScalar(¤tVolume); //CString strCur=L""; //strCur.Format(L"%f",currentVolume); //AfxMessageBox(strCur); // printf("Current volume as a scalar is: %f\n", currentVolume); if (bScalar==false) { hr = endpointVolume->SetMasterVolumeLevel((float)newVolume, NULL); } else if (bScalar==true) { hr = endpointVolume->SetMasterVolumeLevelScalar((float)newVolume, NULL); } endpointVolume->Release(); CoUninitialize(); return FALSE; } float i = 0; int main() { float volume = 0; while(1) { i+=0.01; volume = (sin(i)+1)/2; ChangeVolume(volume,1); std::cout< #include #include #pragma comment(lib, "ole32.lib") //extern //Управление звуком class VolumeOS { public: HRESULT hr; bool decibels; bool scalar; double Volume; VolumeOS() { hr=NULL; decibels = false; scalar = false; CoInitialize(NULL); //newVolume=nVolume; } bool VolumeSET(double nVolume,bool bScalar) { double newVolume = nVolume; Volume = newVolume; IMMDeviceEnumerator *deviceEnumerator = NULL; hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator); IMMDevice *defaultDevice = NULL; hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice); deviceEnumerator->Release(); deviceEnumerator = NULL; IAudioEndpointVolume *endpointVolume = NULL; hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume); defaultDevice->Release(); defaultDevice = NULL; // ------------------------- float currentVolume = 0; endpointVolume->GetMasterVolumeLevel(¤tVolume); //printf("Current volume in dB is: %f\n", currentVolume); hr = endpointVolume->GetMasterVolumeLevelScalar(¤tVolume); //CString strCur=L""; //strCur.Format(L"%f",currentVolume); //AfxMessageBox(strCur); // printf("Current volume as a scalar is: %f\n", currentVolume); if (bScalar==false) { hr = endpointVolume->SetMasterVolumeLevel((float)newVolume, NULL); } else if (bScalar==true) { hr = endpointVolume->SetMasterVolumeLevelScalar((float)newVolume, NULL); } endpointVolume->Release(); return FALSE; } ~VolumeOS() { CoUninitialize(); } }; float i = 0; int main() { VolumeOS A; float volume = 0; while(1) { i+=0.01; volume = (sin(i)+1)/2; A.VolumeSET(volume,true); std::cout<

вторник, 31 марта 2020 г.

Математические правила для генерирования звука плавно нарастающей частоты

#математика #аудио


Я пишу программу, которая генерирует WAV-файл, который содержит плавно меняющийся
звук от частоты seq1 до seq2, частотой дискретизации sampleRate = 44100 и длинной n
секунд. Необходимо найти формулу, по которой вычислять частоту текущего отрезка длинной
в одно полное колебание звука, а так же общее количество отрезков frame.  

Текущая частота - seq = k1 * x + seq1, где k1 - скорость роста частоты, x - порядковый
номер отрезка в одно полное колебание;  

Число семплов на отрезок - spt = sampleRate/seq = sampleRate/(k1*x+b);  

P.S. В принципе, можно упростить, отбросив начальную частоту, и считать по формуле
spt=(sampleRate/k1)/x  

Насколько я понимаю, количество отрезков и прирост частоты от отрезка к отрезку должно
выводиться из уравнения



Но я точно не уверен.  

Пожалуйста, помогите извлечь количество отрезков и скорость прироста частоты.

int main() {
    ofstream out("test.wav", ios::binary);

    int time = 30;
    waveHeaderInit(2, 44100, 16, time);
    waveData = new char[waveHeader.subchunk2Size];
    int sequence = 100;
    volatile float phase;
    volatile int16_t sample;

    int maxAmplitude = pow(2, waveHeader.bitsPerSample - 1) - 1;

    for (int i = 0; i < time * waveHeader.sampleRate; i++) {
        int spt = waveHeader.sampleRate / sequence;
        phase = (i % spt) / float(spt);
        sample = sin(PI*phase)*maxAmplitude;
        for (int channel = 0; channel < waveHeader.numChannels; channel++) {
            ((int16_t*)waveData)[i*waveHeader.numChannels + channel] = sample;
        }
    }

    out.write((char*)&waveHeader, sizeof(waveHeader));
    out.write(waveData, waveHeader.subchunk2Size);
    out.close();
    return 0;
}

    


Ответы

Ответ 1



Увеличивайте частоту медленно с экспоненциальной скоростью. Монотонный звук это A*sin(2Pi*B*t). Заменяем константу B на экспонету B:=C*Exp[D*t]. C*Exp[D*t0]==seq0 C*Exp[D*t1]==seq1 --- D=Ln[seq1/seq0]/(t1-t0) C=seq0*((seq0/seq1)^(t0/(t1-t0))) Получаем A*sin(2Pi*C*Exp[D*t]*t). Упрощаем t0=0, t1=T.Результат: A*sin(2Pi*seq0*((seq1/seq0)^(t/T))*t)

Открыть и закрыть аудио файл. Ошибка: “wave.Error: file does not start with RIFF id”

#python #python_3x #аудио


Есть функция загрузки аудио:

async def upload_audio_message(api, multipart_data, peer_id):
    """Upload audio file `multipart_data` and return Attachment for sending to user
with id `peer_id`(possibly)"""

    sender = api.get_default_sender("docs.getMessagesUploadServer")
    client = api.get_current_sender("docs.getMessagesUploadServer", sender=sender)

    data = aiohttp.FormData()
    data.add_field('file', multipart_data, filename="message.mp3", content_type='multipart/form-data')

    values = {'type': "audio_message", 'peer_id': peer_id}

    if client.group_id:
        values['group_id'] = client.group_id

    response = await api(sender=sender).docs.getMessagesUploadServer(**values)

    if not response or not response.get('upload_url'):
        return None

    upload_url = response['upload_url']

    async with aiohttp.ClientSession() as sess:
        async with sess.post(upload_url, data=data) as resp:
            result = json.loads(await resp.text())

    if not result:
        return None

    data = dict(file=result['file'])
    result = (await api(sender=sender).docs.save(**data))[0]

    return Attachment.from_upload_result(result, "doc")


Пытаюсь открыть аудио файл что бы загрузить его но что-то я делаю не так помогите
пожалуйста:

answer_file = wave.open(self.get_path("winer.mp3"), "rb")
audio = await upload_audio_message(self.api, answer_file, msg.user_id)
answer_file.close()



  raise Error('file does not start with RIFF id')
  wave.Error: file does not start with RIFF id

    


Ответы

Ответ 1



Ошибка: wave.Error: file does not start with RIFF id Используемый модуль wave умеет работать только с форматом WAV, поэтому в этом коде возникает та ошибка: answer_file = wave.open(self.get_path("winer.mp3"), "rb")

пятница, 13 марта 2020 г.

Как управлять audio autoplay?

#php #javascript #html5 #аудио


У меня на сайте используется тег audio с autoplay. Как сделать чтобы autoplay срабатывал
только при первоначальной загрузке страницы, а при переходе обратно с внутренней или
при перезагрузке audio не повторялось?
    


Ответы

Ответ 1



'; }else{ setcookie('audio',1); echo ''; } ?>

Ответ 2



Можно сделать без php if(localStorage.getItem("Auth") != "yes"){ var audio = new Audio(); audio.src = 'sounds/music.mp3'; audio.autoplay = true; localStorage.setItem("Auth", "yes"); // запоминаем пользователя }

Передача данных с минимальной задержкой

#c_sharp #cpp #алгоритм #сеть #аудио


Есть потребность в программе, которая позволит джемовать музыкантам по сети, и есть
желание ее написать. Для этого требуется, чтобы доставка аудио (массивов байтов, размером
около 1 кб) осуществлялась с минимальной задержкой (не больше 10 мс). Возможно ли добиться
такого? Если да, то как? (Протокол передачи, сжатие, тип сети (p2p или сервер-клиент)
и т.д.)  Писать хотелось бы на C# или C++.

UPD: интересует еще такой момент. Для уменьшения задержки думаю запаковывать данные
в GZip. Скажите, пожалуйста, имеет ли это смысл? Я имею в виду, что не быстрее ли будет
просто отсылать незапакованные данные, чем сначала запаковывать, отсылать, а потом
распаковывать?
    


Ответы

Ответ 1



Сначала отвечу на вопросы, потом с позволения выскажу свое мнение по поводу затеи. Добиться задержек в 10 мс можно например при подключении точка-точка или в простой локальной сети. Но в вашем случае это почти не реально. Например, прямо сейчас у меня пинг до шлюза 75-80 мс. Кроме того что пакеты будут теряться, так еще они и доставляться будут с непостоянным временем, то есть будет джитер. Транспортный протокол однозначно UDP. Хотя есть еще CSTP, но у него ограниченная поддержка со стороны провайдеров, велика вероятность, что найдется узел который будет резать все что не UDP и не TCP. А в Виндоуз он вообще бедный родственник. По прикладному уровню рекомендую ознакомится с RTP. P2P как в битторенте, вам не поможет в случае если городская сеть жестко централизованна, что часто бывает в небольших городах. То есть если у провайдера один шлюз на всех и к нему централизованно сходятся все каналы от обывателей. Получится, что между участниками будет по одному каналу и битторент будет скорее проигрывать т.к. у него свои накладные тоже есть. Битторент нуждается в избыточных каналах тогда появляется возможность параллельной передачи, в чем и состоит его суть. Можно попробовать организовать P2P как в скайпе. Например, если среди трех участников окажется что 2 выгоднее быть посредником между 1 и 3, то можно назначить 2 сервером для 1 и 3. Тогда он должен будет передавать для 1: себя и 3, а для 2: себя и 1. Для большего количества участников понадобится подбирать посредников для каждого канала. То есть это задача на максимальный поток. Сжимать однозначно надо пробовать, но только не зипом, а аудио-кодеком. Велика вероятность что сжатие\разжатие можно будет делать аппаратно. Теперь мнение про затею. Почему вы вообще решили что задержки в 10 мс будет достаточно, музыка это тонкая вещь. Большим оркестром обычно управляет дирижер потому что музыканты просто не слышат друг-друга. Рекомендую вам присмотреться к радио.

Ответ 2



Я конечно может не до конца разобрался в вопросе! Но тобы отправить данные которые не помещаются в один пакет UDP(TCP) c минимальными задержками и минимальной нагрузкой на сеть можно воспользоваться технологией отправки пула пакетов (SendQueue), реализованной в WinPcap(LibPcap). Вот здесь все популярно объяснено и с примерами на C# https://pcapdotnet.codeplex.com (раздел https://pcapdotnet.codeplex.com/SourceControl/latest#PcapDotNet.DevelopersPack/src/SendingPacketsUsingSendBuffer/Program.cs).

воскресенье, 8 марта 2020 г.

Запись радиоэфира с пропуском тишины в Linux

#linux #аудио


Доброго времени суток. Имеется трансивер, подключённый к линейному входу ПК под управлением
убунты. Задача - вести запись вызывной частоты. Подскажите, какой программой можно
захватывать линейный вход с пропуском тишины так, чтобы записи сохранялись в разные
файлы с названием равным времени, в которое была сделана запись. Ещё лучше, если есть
возможность писать всё в один файл, если тишина длилась, например, не более минуты.
(Чтобы в один файл попадал, например, общий вызов и все отклики на него. А как только
тишина длится более минуты - то следующая запись пойдёт в новый файл.)
    


Ответы

Ответ 1



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

суббота, 7 марта 2020 г.

Не могу получить популярные аудиозаписи VK

#android #vkontakte_api #аудио


получаю токен юзера и сразу пытаюсь получить 

VKRequest audios = VKApi.audio().getPopular();


И получаю error 15 :( Читал, что сторонние разработчики не могут работать с аудио
но как же тогда работает это  

Что я не так делаю? И вообще почему для получения популярных аудиозаписей нужен токен?
Мне их надо получать даже если пользователь не залогинился.
    


Ответы

Ответ 1



PROFIT! Я это сделал! Декомпилировал одно приложение и узнал какой сейчас используется хак. main.xml MainActivity.java public class MainActivity extends Activity { public class VkontakteWebViewClient extends WebViewClient { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); MainActivity.this.parseUrl(url); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); WebView kateWV = (WebView)findViewById(R.id.kateWebView); kateWV.getSettings().setJavaScriptEnabled(true); kateWV.clearCache(true); kateWV.setWebViewClient(new VkontakteWebViewClient()); CookieSyncManager.createInstance(this); CookieManager.getInstance().removeAllCookie(); kateWV.loadUrl(Auth.getUrl("2685278", Auth.getSettings())); } public void parseUrl(String url){ if (url != null) { try { if (url.startsWith(Auth.redirect_url)) { if (!url.contains("error=")) { String[] auth = Auth.parseRedirectUrl(url); saveTokenToSharedPreferences(getApplicationContext(), Auth.VK_SDK_ACCESS, "scope=groups,audio,offline&https_required=1&expires_in=0&access_token=" + auth[0] + "&user_id=" + Long.parseLong(auth[1])); } startActivity(new Intent(MainActivity.this, AudioActivity.class)); finish(); } } catch (Exception e) { e.printStackTrace(); } } } public void saveTokenToSharedPreferences(Context ctx, String tokenKey, String code) { SharedPreferences.Editor edit = PreferenceManager.getDefaultSharedPreferences(ctx).edit(); edit.putString(tokenKey, code); edit.apply(); } } Auth.java public class Auth { public static final String VK_SDK_ACCESS = "VK_SDK_ACCESS_TOKEN_PLEASE_DONT_TOUCH"; public static String redirect_url; static { redirect_url = "https://oauth.vk.com/blank.html"; } public static String getUrl(String api_id, String settings) { return "https://oauth.vk.com/authorize?client_id=" + api_id + "&display=mobile&scope=" + settings + "&redirect_uri=" + URLEncoder.encode(redirect_url) + "&response_type=token" + "&v=" + "5.53"; } public static String getSettings() { return "notify,friends,photos,audio,video,docs,status,notes,pages,wall,groups,messages,offline,notifications"; } public static String[] parseRedirectUrl(String url) throws Exception { String access_token = Utils.extractPattern(url, "access_token=(.*?)&"); String user_id = Utils.extractPattern(url, "user_id=(\\d*)"); if (user_id == null || user_id.length() == 0 || access_token == null || access_token.length() == 0) { throw new Exception("Failed to parse redirect url " + url); } return new String[]{access_token, user_id}; } } В итоге после авторизации через WebView в preferences будет сохранен токен scope=groups,audio,offline&https_required=1&expires_in=0&access_token=тут_токен_юзера&user_id=тут_id_юзера Далее можно работать с API VK. Лично у меня происходит переход в AudioActivity. Примерный код VKRequest request = VkApi.audio().getPopular(); request.executeWithListener(new VKRequest.VKRequestListener() { @Override public void onComplete(VKResponse response) { //выводим json с музыкой в логи Log.d("vkmusic", response.responseString); } @Override public void onError(VKError error){ Log.d("err", error.toString()); } }); request.start(); Ну и все, можно юзать. Результат

Ответ 2



И вот еще класс Utils class Utils { public static String extractPattern(String string, String pattern) { Pattern searchPattern = Pattern.compile(pattern); Matcher matcher = searchPattern.matcher(string); Log.d("pattern found - ", matcher.find() ? ("yes" + matcher.group(1)) : "no"); return matcher.group(1); } }

среда, 4 марта 2020 г.

Написать движок игры на java [закрыт]

#java #аудио #движок #физика #визуализация


        
             
                
                    
                        
                            Закрыт. Данный вопрос необходимо конкретизировать. Ответы
на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он был сосредоточен только на одной проблеме, отредактировав его.
                        
                        Закрыт 2 года назад.
                                                                                
           
                
        
Допустим захотел я написать движок для игр, зная только Java.
Как это возможно реализовать?


Нужно написать отображение картинки ("звуковоиспроведение" / физику).


Реализация:
На ум приходит только создание библиотеки основанной на аплете, или JavaFX, или JavaEE
(в последнем случае логика и отображение получаются сильно (слишком) взаимосвязаны).



Возможно ли это сделать на чистом JavaSE?
    


Ответы

Ответ 1



Разумеется можно, Майнкрафт подтвердит. См. этот список, берите нужный фреймворк и делайте игры. Либо берете фреймворк с открытым кодом и смотрите как все там реализовано. P.S. Проблема может быть с производительностью, если вы планируете сложную графику, все-таки С/С++/Rast и т.п. быстрее работают как числодробилки.

воскресенье, 1 марта 2020 г.

Получение сырых данных Audio в js

#javascript #аудио


Допустим есть некий sampe.mp3. Я хочу с помощью javascript извлечь сырые данные и
нарисовать график этого звука. Как это сделать?
    


Ответы

Ответ 1



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

Ответ 2



Ещё одна реализация рисования осциллограммы, и на этот раз без canvas, а путём программного создания графического рисунка стандартного формата прямо в оперативной памяти, (на примере формата BMP) и передачи его в элемент img в качестве src: Визуализатор

Есть нюансы - для правильного отображения должна быть задана ширина img id=oscillogram, кратная четырём, код работает пока только со стерео-аудиофайлами. Быстро декодируются аудиоданные только маленьких аудиофайлов, одна песня требует около минуты ожидания.

вторник, 25 февраля 2020 г.

Воспроизведение музыки формата Flac в python

#python #аудио


Доброго времени суток.
Хочу воспроизвести музыку формата flac. Пробовал pygame, pydub - не вышло.
Посоветуйте библиотеку для работы с flac.
Заранее спасибо.     


Ответы

Ответ 1



Чтобы просто запустить файл на проигрывание из программы, можно попробовать webbrowser модуль, который попытается использовать приложение по умолчанию в системе для проигрывания .flac файлов: import webbrowser webbrowser.open('example.flac') В более общем случае можно использовать GStreamer, который поддерживает многие форматы и работает на большинстве распространённых систем. Вот минимальный пример, который проигрывает произвольный медиа-файл (аудио, видео), заданный с командной строки: #!/usr/bin/env python """Play a media file using GStreamer.""" import os import sys try: from urllib.parse import urljoin from urllib.request import pathname2url except ImportError: # Python 2 from urlparse import urljoin from urllib import pathname2url from gi.repository import GObject, Gst Gst.init(None) def path2url(path): return urljoin('file:', pathname2url(os.path.abspath(path))) media_uri = path2url(sys.argv[1]) # file:// url to play print(media_uri) player = Gst.ElementFactory.make('playbin', None) player.set_property('uri', media_uri) player.set_state(Gst.State.PLAYING) try: GObject.MainLoop().run() except KeyboardInterrupt: # stop playing on Ctrl-C player.set_state(Gst.State.NULL) Чтобы завершить скрипт, нажми Ctrl-C. Вот более полный пример, который показывает как слушать сообщения от Gstreamer, чтобы, например, выйти из программы по окончанию проигрывания файла или начать играть файл заново. Чтобы установить Gstreamer на Ubuntu: $ sudo apt-get install python-gi python3-gi \ gstreamer1.0-tools \ gir1.2-gstreamer-1.0 \ gir1.2-gst-plugins-base-1.0 \ gstreamer1.0-plugins-good \ gstreamer1.0-plugins-ugly \ gstreamer1.0-plugins-bad \ gstreamer1.0-libav

четверг, 13 февраля 2020 г.

Воспроизвести звук на сайте

#аудио #javascript


Все мы пользователи соц. сети. На примере вконтакте: при получении сообщения мы слышим
характерный звук - щелчок.
Мне оч. понравилась эта идея и я хочу в купе с уведомлениями также воспроизводить файл.
Как это можно сделать кроссбраузерно на js?
Можно ли что-нибудь выжать хорошее из http://vkontakte.ru/js/sound.js?    


Ответы

Ответ 1



SoundManager 2 — прекрасное решение! Примеры данного решения. Как дополнил @org, вот здесь можно найти большое количество разных звуков.

Ответ 2



Все мы пользователи соц. сети. Ой, не надо за всех :-) А проблема звуковых уведомлений в уэб-интерфейсах исчерпала себя с появлением элемента

Преобразование звука

#преобразование #аудио #cpp #linux


Как известно в линукс есть консольные прогарммы aplay и arecord
чтобы проиграть звук с микрофона на колонки нужно ввести:

arecord | aplay

но я хочу добавить эффект дисторшн в эту конструкцию, чтобы было примерно так:
arecord | distort | aplay

Чтобы можно было например на вход подключить электрогитару ну или просто побаловаться.
Так вот мой вопрос вот в чем: Что мне нужно почитать и что изучить, чтобы я мог написать
этот самый distortion?    


Ответы

Ответ 1



Ну, вообще для начала нужно прочитать руководство по командам arecord и aplay. Из него мы узнаем, что по умолчанию они используют формат WAVE. Остается только понять сам формат данных и можно писать утилиту. Также стоит упомянуть, что нужно научиться работать со стандартным вводом и выводом. Но это должно быть достаточно просто.

Ответ 2



#include int main() { int c, i; for ( i = 0; i <= 245; i++) { c = getchar(); printf("%c", c); } while (c != EOF) { c = getchar(); if (c <= 198) printf("%c", 198); else if (c >= 205) printf("%c", 205); else printf("%c", c); } return 0; } это код, который получился у меня. просто сконвертировать файл можно таким образом: ./dist < file1.wav > file2.wav

Воспроизведение потокового аудио .NET

#c_sharp #net #аудио #mp3


Какие для .NET есть библиотека для воспроизведения аудио (mp3) из сети во время его
загрузки, то есть в потоке? NAudio не предлагать - уже второй день с ним парюсь, и
постоянно нахожу какие-то костыли с багами, в виду отсутствия нормальной документации.
    


Ответы

Ответ 1



Если используете WPF, то стандартный класс MediaPlayer https://msdn.microsoft.com/ru-ru/library/system.windows.media.mediaplayer(v=vs.110).aspx MediaPlayer player = new MediaPlayer(); player.Open(new Uri("указываем адрес до аудиозаписи"); player.Play(); Но почему-то недоступно воспроизведение по https https://stackoverflow.com/questions/25081956/how-to-make-a-wpf-mediaelement-play-when-its-source-is-a-https-uri

Ответ 2



Creating the Windows Media Player Control Programmatically Playing a MP3 file in a WinForm application libZPlay irrKlang also: Microsoft.DirectX.AudioVideoPlayback.Audio winmm.dll

Ответ 3



Можно попробовать ещё Bass.NET

суббота, 8 февраля 2020 г.

Получение звука воспроизводимового на колонки

#c_sharp #аудио


Каким образом можно получить звук, который воспроизводится на колонки?


    


Ответы

Ответ 1



Звуковой поток с устройства воспроизведения можно перехватить, например, с помощью: DirectShow; Сторонних библиотек (многие, если не большинство, основаны на том же DirectShow, только работать с ними несколько проще); MS MM API. Средства для работы с DirectShow уже есть в .NET. Стороннюю библиотеку под .NET нужно сперва найти. Про MS MM API в .NET, к сожалению ничего не могу сказать. В любом случае, это три основные направления в которых можно начинать копать.

воскресенье, 2 февраля 2020 г.

Подготовка данных для распознавания речи нейронной сетью

#алгоритм #аудио #нейронные_сети


Разбираюсь с распознаванием речи с помощью нейронных сетей. Нашел довольно много
информации об устройстве самих сетей, а вот с примерами их работы посложнее.

Допустим есть у меня какая-то сеть с N входами и M выходами. И есть звуковой сигнал
с каким-то текстом. Как все это заставить работать вместе?

Получили мы, допустим, с помощью преобразования Фурье спектр. Ну можем как-то нарезать
звуковой сигнал на какие-то мелкие кусочки. Опять же, как их выбрать длину куска? И
что делать дальше? Что подавать на вход сети? И что сеть на выходе обычно дает? Буквы,
соответствующие звукам или еще что-либо? (Допустим, стоит задача получить произнесенное
предложение в текстовом виде)

Мне интересен сам алгоритм, как все это происходит от произнесения фразы человеком
до получения этой фразы в текстовом виде. Информация, которую я находил освещает обычно
либо работу нейронной сети, либо преобразование Фурье. Но как все это работает вместе
- не очень понятно.
    


Ответы

Ответ 1



Тема слишком обширная для краткого ответа - ваш вопрос - это повод для хорошего исследования. Однако, гипотезы выдвигать никто не запрещает. Нейронные сети должны принимать на вход вектор признаков фиксированного размера. Значит нужно как-то нормализовать длину входного вектора. В вопросе вы указали, что есть коэффициенты Фурье после преобразования текста. Тексты бывают очень разной длины и чтобы получить одинаковое количество коэффициентов, длительность сигнала тоже должна быть одинаковой. К тому же найти корпус для обучения по текстам будет проблемой - такой корпус будет иметь монструозные размеры и неприемлимо большое время обучения. Вместо текста можно брать отдельные слова - текст можно разделить на слова, ориентируясь на паузы между словами. Следуя этой логике можно спуститься еще ниже и распознавать отдельные слоги или звуки. Вот пример для слова РОВНО: Здесь изображен сигнал с нормализованной амплитудой + плюс я обрезал паузу в начале записи. Как видно, между слогами очень осязаемая пауза и весь текст можно последовательно нарезать на такие отрезки - на мой взгляд с такими маленькими единицами информации работать легче, чем целиком со словами. Далее эти куски можно выровнять по длительности (по количеству сэмплов), вычислить коэффициенты и обучать или распознавать. Обучение это также отдельный большой вопрос, как и распознавание, а точнее, что делать после распознавания. Например, слово распозналось неверно и его нет в словаре.

пятница, 24 января 2020 г.

Как скачать и сохранить аудио с сервера?

#ios #objective_c #аудио


Хочу сделать музыкальный проигрыватель. Но не знаю как можно скачать файл с облака
и сохранить на устройстве. Помогите пожалуйста с решением этой проблемы.

код:

AudioPlayer.m

#import "AudioPlayer.h"

@implementation AudioPlayer


- (void)initPlayer:(NSString*) audioFile fileExtension:(NSString*)fileExtension
{
NSURL *audioFileLocationURL = [[NSBundle mainBundle] URLForResource:audioFile withExtension:fileExtension];
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileLocationURL
error:&error];
}


- (void)playAudio {
[self.audioPlayer play];
}


- (void)pauseAudio {
[self.audioPlayer pause];
}


- (BOOL)isPlaying {
return [self.audioPlayer isPlaying];
 }


-(NSString*)timeFormat:(float)value{

float minutes = floor(lroundf(value)/60);
float seconds = lroundf(value) - (minutes * 60);

int roundedSeconds = lroundf(seconds);
int roundedMinutes = lroundf(minutes);

NSString *time = [[NSString alloc]
                  initWithFormat:@"%d:%02d",
                  roundedMinutes, roundedSeconds];
return time;
 }

 - (void)setCurrentAudioTime:(float)value {
[self.audioPlayer setCurrentTime:value];
 }


 - (NSTimeInterval)getCurrentAudioTime {
return [self.audioPlayer currentTime];
 }


 - (float)getAudioDuration {
return [self.audioPlayer duration];
 }


 @end


AudioPlayer.h

  #import 
  #import 

  @interface AudioPlayer : UIViewController

  @property (nonatomic, retain) AVAudioPlayer *audioPlayer;

 - (void)initPlayer:(NSString*) audioFile fileExtension:(NSString*)fileExtension;
 - (void)playAudio;
 - (void)pauseAudio;
 - (BOOL)isPlaying;
 - (void)setCurrentAudioTime:(float)value;
 - (float)getAudioDuration;
 - (NSString*)timeFormat:(float)value;
 - (NSTimeInterval)getCurrentAudioTime;


ViewController.m

 #import "ViewController.h"

 @interface ViewController ()

 @end

 @implementation ViewController

 - (void)viewDidLoad
 {
[super viewDidLoad];
self.audioPlayer = [[AudioPlayer alloc] init];
[self setupAudioPlayer:@"gendel-allilujjja-(mp3-crazy.com)"];
    NSString *stringURL = @"https://drive.google.com/uc?export=download&id=0B0EJbcHq3ZALWUo0a05LMWNzeDg";
    NSURL  *url = [NSURL URLWithString:stringURL];
    NSData *urlData = [NSData dataWithContentsOfURL:url];
    if ( urlData )
    {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];

        NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"gendel-allilujjja-(mp3-crazy.com)"];
        [urlData writeToFile:filePath atomically:YES];
    }

 }


 - (BOOL)prefersStatusBarHidden
 {
return NO;
 }


 - (void)setupAudioPlayer:(NSString*)fileName
 {

NSString *fileExtension = @"mp3";

[self.audioPlayer initPlayer:fileName fileExtension:fileExtension];
self.currentTimeSlider.maximumValue = [self.audioPlayer getAudioDuration];


self.timeElapsed.text = @"0:00";

self.duration.text = [NSString stringWithFormat:@"-%@",
                      [self.audioPlayer timeFormat:[self.audioPlayer getAudioDuration]]];

 }


 - (IBAction)playAudioPressed:(id)playButton
 {
[self.timer invalidate];
if (!self.isPaused) {
    [self.playButton setBackgroundImage:[UIImage imageNamed:@"audioplayer_pause.png"]
                               forState:UIControlStateNormal];

    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                  target:self
                                                selector:@selector(updateTime:)
                                                userInfo:nil
                                                 repeats:YES];

    [self.audioPlayer playAudio];
    self.isPaused = TRUE;

} else {
    [self.playButton setBackgroundImage:[UIImage imageNamed:@"audioplayer_play.png"]
                               forState:UIControlStateNormal];

    [self.audioPlayer pauseAudio];
    self.isPaused = FALSE;
  }
 }

 - (void)updateTime:(NSTimer *)timer {
if (!self.scrubbing) {
    self.currentTimeSlider.value = [self.audioPlayer getCurrentAudioTime];
}
self.timeElapsed.text = [NSString stringWithFormat:@"%@",
                         [self.audioPlayer timeFormat:[self.audioPlayer getCurrentAudioTime]]];

self.duration.text = [NSString stringWithFormat:@"-%@",
                      [self.audioPlayer timeFormat:[self.audioPlayer getAudioDuration]
- [self.audioPlayer getCurrentAudioTime]]];

if (![self.audioPlayer isPlaying]) {
    [self.playButton setBackgroundImage:[UIImage imageNamed:@"audioplayer_play.png"]
                               forState:UIControlStateNormal];
    [self.audioPlayer pauseAudio];
    self.isPaused = FALSE;
 }
 }

 - (IBAction)setCurrentTime:(id)scrubber {
[NSTimer scheduledTimerWithTimeInterval:0.01
                                 target:self
                               selector:@selector(updateTime:)
                               userInfo:nil
                                repeats:NO];

[self.audioPlayer setCurrentAudioTime:self.currentTimeSlider.value];
self.scrubbing = FALSE;
 }


 - (IBAction)userIsScrubbing:(id)sender {
self.scrubbing = TRUE;
 }


 - (void)didReceiveMemoryWarning
 {
[super didReceiveMemoryWarning];
 }

 @end


ViewController.h

#import 
#import "AudioPlayer.h"

@interface ViewController : UIViewController

@property (nonatomic, strong) AudioPlayer *audioPlayer;

@property (weak, nonatomic) IBOutlet UISlider *currentTimeSlider;
@property (weak, nonatomic) IBOutlet UIButton *playButton;
@property (weak, nonatomic) IBOutlet UILabel *duration;
@property (weak, nonatomic) IBOutlet UILabel *timeElapsed;


@property BOOL isPaused;
@property BOOL scrubbing;

@property NSTimer *timer;

@end

    


Ответы

Ответ 1



Ну допустим скачать можно вот так NSString *stringURL = @"http://www.cloud.com/music.mp3"; NSURL *url = [NSURL URLWithString:stringURL]; NSData *urlData = [NSData dataWithContentsOfURL:url]; if ( urlData ) { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"music.mp3"]; [urlData writeToFile:filePath atomically:YES]; } Загрузить, и начать играть NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"music.mp3"]; self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:filePath] error:nil]; [self.player play];

БПФ звукового сигнала (C++ и SFML)

#cpp #алгоритм #аудио #sfml #fft


У меня вопрос по БПФ звукового сигнала. Я хочу нарисовать график на основе звукового
сигнала. Но я не силен в этой теме. Хочу совета у опытных товарищей с чего начать.

У меня несколько вопросов:
1) Что такое samples (семплы)? Например при использовании мультимедийной библиотеки
SFML для получения семплов используется следующая конструкция:

sf::Buffer Buffer;
Buffer.loadFromFile("sound.wav");
const sf::Int16 *input = Buffer.getSamples();


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

    typedef short int16;
    int16 *load()
    {
      FILE  *fp;
      if((fp=fopen("sound.wav", "rb"))==NULL) {
        printf("Ошибка при открытии файла.\n");
      }
      fseek(fp, 0, SEEK_END);
      long N = ftell(fp);
      fseek(fp, 0, SEEK_SET);
      int16 *A = new int16[N];
      for(i=0; i


Ответы

Ответ 1



Если речь идет о несжатом звуковом файле, то семпл - это отсчет, полученный при оцифровке сигнала, т.е. просто мгновенное значение амплитуды аналогового сигнала. По этим отсчетам можно построить вашу "синусойду", т.е. представление сигнала во временной области. БПФ же, это быстрое преобразование Фурье, выполнив его мы получаем отображение сигнала в частотной области (разложение сигнала по частотам). Как реализована конкретная библиотека я не знаю, но для алгоритма БПФ необходима кратность 2. Хотя можно и нолики в конце дописать, ну да ладно, это уже ЦОС. Рекомендую вам для начала ознакомится с теоретической стороной вопроса, чтобы четко понимать, что вы делаете. Успехов)

Библиотеки для работы со звуком Java

#java #аудио #поиск_библиотек


Подскажите пожалуйста, как лучше получать сигнал с аудио разъёма пк для последующей
его обработки на java? Есть ли какие - нибудь специальные библиотеки для этой задачи?
    


Ответы

Ответ 1



Думаю в этой статье все детально прописано. Основной код: try { File soundFile = new File("snd.wav"); //Звуковой файл //Получаем AudioInputStream //Вот тут могут полететь IOException и UnsupportedAudioFileException AudioInputStream ais = AudioSystem.getAudioInputStream(soundFile); //Получаем реализацию интерфейса Clip //Может выкинуть LineUnavailableException Clip clip = AudioSystem.getClip(); //Загружаем наш звуковой поток в Clip //Может выкинуть IOException и LineUnavailableException clip.open(ais); clip.setFramePosition(0); //устанавливаем указатель на старт clip.start(); //Поехали!!! //Если не запущено других потоков, то стоит подождать, пока клип не закончится //В GUI-приложениях следующие 3 строчки не понадобятся Thread.sleep(clip.getMicrosecondLength()/1000); clip.stop(); //Останавливаем clip.close(); //Закрываем } catch (IOException | UnsupportedAudioFileException | LineUnavailableException exc) { exc.printStackTrace(); } catch (InterruptedException exc) {}

четверг, 23 января 2020 г.

Дозапись в существующий аудиофайл

#java #android #аудио


У меня есть аудиофайл, который хранится на SD card, я хочу дозаписать аудио в конец
этого файла, способы которые я нашла как это можно сделать - это использование SequenceInputStream
или ffmpeg. Есть ли еще какие-то варианты как это можно сделать?       
    


Ответы

Ответ 1



Если это не закодированный, "сырой" аудиофайл wav, pcm, то дописать можно с помощью AudioRecord из android sdk. Если закодированный, то чтобы дописать надо все раскодировать, дописать и снова закодировать. Если это делать на андройде, то можно воспользоваться MediaCodec api, зависит от кодека, надо смотреть какие поддерживает. Правда в сети мало примеров, и я в свое время не разобрался. Другой вариант, более простой - ffmpeg. Здесь можно бинариник ффмпега засунуть в приложение и работать как из командной строки. Либо воспользоваться библиотекой javaCV. Хороший пример использования RecordActivity.java. Кодирование/декодирование через ффмпег на андройде медленно работает, поэтому в свое время на проекте всякие такие медиа дела я делал через него же, но на сервере.

среда, 22 января 2020 г.

Быстрое преобразование Фурье. Как выделить частоту ноты?

#java #аудио #fft #музыка


Заинтересовался реализацией выделением нот и распознаванием сигналов исходя из нот.
Вот если взять фортепиано, записать звук пары клавиш, после чего применить БПФ, на
выходе мы получим массив комплексных чисел, где амплитудой будет модуль комплексного
числа, а аргумент его фазой. Вот немного не понятно как выделить частоту ноты?
    


Ответы

Ответ 1



Преобразование фурье производится на комплексных числах. На вход для преобразования следует подавать в реальную часть амплитуду(величину сигнала), а в мнимую часть нуль. На выходе мы получим массив комплексных чисел, где амплитудой будет модуль комплексного числа, а аргумент его фазой. Каждый элемент массива представляет из себя одну гармонику, начиная с нулевой и завершая n-ой. Или это называется спектрами? В разных источниках на этот счёт разная информация. Спектры/гармоники отделены друг от друга дискретным шагом равным частотам дискретизации/количество отсчётов. Количество отсчётов равно количеству чисел амплитуд на входе, длине массивов входящих комплексных чисел, количеству длины входного сэмпла. В общем, количеству комплексных чисел на входе. Больше на входе отсчётов, больше разрешение по частоте на выходе. То есть, на выходе получив 1024 значений комплексных получаем 1024 значений амплитуда-фаза. Из этих значений, располагая массив по порядку и амплитуде можно получить нечто вроде визуализации амплитуды звука по частоте. Если дискретизация 44100Гц, а входной массив имеет длину 65536 то шаг между элементами массива на выходе получается 0.672912598 Гц. В целях распознавания человеческой речи подобная точность бессмысленна и избыточна. Путём генетического алгоритма (естественного отбора человеческого вида в условиях среды планеты Земля) оптимальным максимальным будет шаг между частотами от 1 до 9 Гц, то есть на вход желательно подавать максимум 8192 значений амплитуды-времени для частоты дискретизации 44100. Но прежде чем подавать эти данные на распознавание, с ними нужно ещё немного повозиться, но я не знаю как. Там что-то про окошки и что-то с функциями надо делать. Ничего не понял. UPD: Короче, вот код уточнения частоты основанный на смещении фаз в дополнение к фурье на java. /*числа пи*/ public static final double SinglePi = Math.PI; public static final double DoublePi = 2*Math.PI; /** * На вход подаётся два спектра, смещение между ними и частота. * @param spectrum0 * @param spectrum1 * @param shiftPerFrame * @param sampleRate * @return dictionary */ public static HashMap GetJoinedSpectrum( List spectrum0, List spectrum1, double shiftsPerFrame, double sampleRate) { int frameSize = spectrum0.size(); double frameTime = frameSize/sampleRate; double shiftTime = frameTime/shiftsPerFrame; double binToFrequancy = sampleRate/frameSize; HashMap dictionary = new HashMap(){ for (int bin = 0; bin < frameSize; bin++) { double omegaExpected = DoublePi*(bin*binToFrequancy); // ω=2πf double omegaActual = (spectrum1.get(bin).phase() - spectrum0.get(bin).phase())/shiftTime; // ω=∂φ/∂t double omegaDelta = Align(omegaActual - omegaExpected, DoublePi); // Δω=(∂ω + π)%2π - π double binDelta = omegaDelta/(DoublePi*binToFrequancy); double frequancyActual = (bin + binDelta)*binToFrequancy; double magnitude = spectrum1.get(bin).abs()+ spectrum0.get(bin).abs(); dictionary.put(frequancyActual, magnitude*(0.5 + Math.abs(binDelta))); } return dictionary; } public static double Align(double angle, double period) { int qpd = (int) (angle/period); if (qpd >= 0) qpd += qpd & 1; else qpd -= qpd & 1; angle -= period*qpd; return angle; } Ссылки: https://m.habrahabr.ru/post/247385/ http://introcs.cs.princeton.edu/java/32class/Complex.java