DIY Electronic projects
Android Audio I/O routing - Printable Version

+- DIY Electronic projects (https://forum.yu3ma.net)
+-- Forum: Programiranje (https://forum.yu3ma.net/forumdisplay.php?fid=58)
+--- Forum: Mobile (https://forum.yu3ma.net/forumdisplay.php?fid=72)
+--- Thread: Android Audio I/O routing (/showthread.php?tid=2407)



Android Audio I/O routing - mikikg - 05-19-2020

Drustvo,

pre nego sto krenem u pisanje nekog programa za Android, zelim da se konsultujem sa vama oko situacije za malo specificno Audio rutiranje signala.

Da ne objasnjavam previse, sastavio sam jedan block diagram koji bi izgledao ovako:

[Image: attachment.php?aid=33342]

Dakle u pitanju je neki specifican USB uredjaj (RF-Modem) koji ima implmentirano u sebi dve vrste interfejsa, jedan je klasican CDC interface preko kojeg se upravlja modemom (komandni kanal, to mi nije trenutno problem) i drugi interface je USB Audio class kompatibilan koji ima 1 Ulaz i 1 Izlaz, full-duplex, 16bit 8kHz.

---

Prvo pitanje, da li uopste moze da se rutuje audio signal bilo sa internog zvucnika/mikrofona na ovaj USB uredjaj, dakle bukvalno ono sto pricam u mikrofon da se prosledi preko USB Audio spoljnjem uredjaju i naravno obrnuto kada sa tog USB uredjaja nesto stigne u zvucnom zapisu da se to reprodukuje na interni zvucnik?
Bluetoot headset ili TRS 3.5mm su samo varijacije na istu temu.

Drugo pitanje, da li neko moze mi predlozi konkretne programske pristupe, sta/gde da gledam ili da uputi na neku gotovu APK (sa source-code bi bilo lepo) kao primer koja moze ovako nesto da odradi, za primer neka bude samo u jednom smeru, bitno mi je da potvrdim koncept da li uopste funkcionise?


RE: Android Audio I/O routing - nik - 05-19-2020

USB na androidu može da ima ulogu audio izvora:
Omogućiš Developer opcije i u segmentu USB imaš opciju 'Audio source'

Za mikrofon nađoh free app WO Mic koji može da prosledi mono zvuk bilo USB, WiFi, BT itd na spoljni uređaj, oni navode PC

EDIT
Kada je strimovanje muzike u pitanju, iPhone 6, 7 (reparirani se kupuju relativno jeftino) sa svojim 'Lightning' priključkom postaju vrlo ozbiljan internet strimer (Tidal, Deezer, Spotify, AmazonMusic ...)


RE: Android Audio I/O routing - mikikg - 05-19-2020

Hmm, iz nekog razloga imam razne opcije na svom Nokia 6 - Android 9 telefonu, samo tu "Audio source" nemam Sad

U vezi ove WO Mic aplikacije, konceptualno je to OK ali ne potpuno, oni imaju za te potrebe verovatno neki interni TCP server za streaming, zato imaju sa druge strane posebne drajvere.
Caka je u tome sto je tako samo jedna zvucna kartica u igri, u mom slucaju su prakticno dve zvucne kartice!


RE: Android Audio I/O routing - nik - 05-19-2020

Nađoh ovaj link na YT, svež (2020) 'Kako omogućiti USB zvučne kartice na Android uređajima'
Nisam odgledao ali su haš tagovi ispod videa enteresentni Smile
https://www.youtube.com/watch?v=7dE3OaMU6xg


RE: Android Audio I/O routing - nik - 05-19-2020

Odgledao. Kod mene ova opcija (Android 7) postoji. Pade mi napamet, davnih dana kada je Skype bio glavni za besplatnu internet komunikaciju, za fimu sam nabavljao Gembird mono slušalice sa mikrofonom (drugo uvo slobodno za telefon). Gembird zbog jeftinoće, najbolji su bili Plantronics proizvodi. Dakle, mini DAC, audio kartica i mikrofon za smešne novce i ova funkcija trebalo bi da rešava situJaciju.


RE: Android Audio I/O routing - mikikg - 05-19-2020

Specificna je situacija kod mene, verovatno cu morati to da odradim iz mog programa, opet kazem imam u igri dve zvucne kartice, sve sto sam nalazio do sad su bile prakticno samo sa jednom, ili je spoljna ili unutrasnja, nisam jos nasao slucaj za obe ...


RE: Android Audio I/O routing - nik - 05-19-2020

Napisah gore, verovatno smo kuckali u isto vreme. Par tih slušalica imam kući i znam da se na PC prijavljuje bez potrebe dodatnih drajvera. Nađoh sličnu ali stereo varijantu. Crna kutijica je spoljna audio karta tj. i DAC i audio karta, mikrofon.
https://gmb.nl/item.aspx?id=3243

EDIT
Sad se prisećam (pročitao tehničke karakteristike): sa instaliranim softverom, na klik jednog od dugmića snima se poruka, to se beleži na PC-u, pakuje u zip te kao zvučna poruka šalje primaocu na emajl Smile


RE: Android Audio I/O routing - mikikg - 05-19-2020

Opet se ne razumemo.

Vidi ovako, kada se nabode bilo-sta-Audio na Android preko USB-a, Androidova default akcija je da onda iskljuci svoju internu karticu i nadalje je glavna ta spoljna, dakle u tom trenutku imamo samo jednu zvucnu karticu.

Meni trebaju obe, bukvalno da pricam preko internog mikrofona a da se na primer to cuje u slusalicama koje su prikljucene preko USB Audio, kapiras?
Neko-nesto to mora da premosti/preusmeri u Androidu, to mene interesuje!


RE: Android Audio I/O routing - nik - 05-19-2020

Miki, ako si odgledao zadnji video, upravo postoji opcija 'Disable USB audio routing' koja treba da isključi automatsko rutiranje na spoljne USB audio periferije. Po meni je to funkcija koja će ti omogućiti korišćenje i interne zv. kartice u telefonu. Moje mišljenje o upotrebi te opcije.


RE: Android Audio I/O routing - mikikg - 05-19-2020

'Disable USB audio routing' je samo pola problema/resenja.
Na taj nacin ce verovatno ostati obe kartice aktivne i vidljive u sistemu, ALI, ko/sta ce da kaze kako da se stvarno signal rutira? Meni treba izlaz sa prve zvucne da ide na ulaz od druge zvucne i sve to obrnuto za drugi smer.
To mene muci ... Nisam jos nasao primer takve (gotove) aplikacije, meni treba cak i source-code jer imam jos vazdan stvari da odradim pored tog rutiranja ...


RE: Android Audio I/O routing - nik - 05-19-2020

Razumeo potrebu, kao modem komunikacija iliti skype, vajber, vatsap i ostali ali na usb protokolu.


RE: Android Audio I/O routing - me[R]a - 05-19-2020

Mozda da malo "bacis oko" ovde... Mozda ima nesto u vezi sa tvojim potrebama...


RE: Android Audio I/O routing - mikikg - 05-27-2020

Uspeo sam nesto da odradim sa ovim Audio rutingom pod Android.

Pomogla mi je Google-ova "Oboe" biblioteka i konkretno primer "LiveEffect":
https://github.com/google/oboe

Uglavnom je moguce da se to sve rutira po volji iz programa, mora da se spusti na C/C++ nivo, ne moze samo kroz Java.


RE: Android Audio I/O routing - mikikg - 07-03-2020

Samo da javim da je ovo sto sam hteo da odradim na zalost neizvodljivo na Android-u Sad

Ne moze da ima dva Recording end-pointa istovremeno, limitirano je na 1 end-point i tehnicki ne mogu da resim situaciju nikako, radi pojedinacno jedan ili drugi smer ali zajedno ne moze, katastrofa ...

https://stackoverflow.com/questions/53796802/android-oboe-library-2-streams-recording-from-2-recording-devices-possible
https://stackoverflow.com/questions/9715505/android-record-multiple-audio-at-a-time


RE: Android Audio I/O routing - mikikg - 07-03-2020

TYPE_BUILTIN_MIC >> TYPE_USB_DEVICE (IN)
+
TYPE_USB_DEVICE (OUT) >> TYPE_BUILTIN_SPEAKER

To mi je konkretno potrebno rutiranje.

public void bljuc1 () {
    new Thread  (new Runnable() {
        @Override
        public void run() {
            boolean isRecording = true;
            AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            AudioDeviceInfo[] devices1Xins = audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
            AudioDeviceInfo[] devices1Xouts = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);

            int buffersize = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT) ;
            AudioRecord arec1 = new AudioRecord(MediaRecorder.AudioSource.MIC, 16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, buffersize);
            AudioTrack atrack1 = new AudioTrack(AudioManager.STREAM_VOICE_CALL, 16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, buffersize, AudioTrack.MODE_STREAM);
            atrack1.setPlaybackRate(16000);

            for (AudioDeviceInfo deviceX : devices1Xins) {
                if (deviceX.getType() == AudioDeviceInfo.TYPE_BUILTIN_MIC) {
                    arec1.setPreferredDevice(deviceX);
                }
            }
            for (AudioDeviceInfo deviceX : devices1Xouts) {
                if (deviceX.getType() == AudioDeviceInfo.TYPE_USB_DEVICE) {
                    atrack1.setPreferredDevice(deviceX);
                }
            }
            byte[] buffer1 = new byte[buffersize];
            arec1.startRecording();
            atrack1.play();
            while (isRecording) {
                arec1.read(buffer1, 0, buffersize);
                atrack1.write(buffer1, 0, buffer1.length);
            }
        }
    }).start();
}


public void bljuc2 () {
    new Thread(new Runnable() {
        @Override
        public void run() {

            boolean isRecording = true;
            AudioManager audioManager2 = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            AudioDeviceInfo[] devices2Xins = audioManager2.getDevices(AudioManager.GET_DEVICES_INPUTS);
            AudioDeviceInfo[] devices2Xouts = audioManager2.getDevices(AudioManager.GET_DEVICES_OUTPUTS);

            int buffersize2 = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT) ;
            AudioRecord arec2 = new AudioRecord(MediaRecorder.AudioSource.MIC, 16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, buffersize2);
            AudioTrack atrack2 = new AudioTrack(AudioManager.MODE_IN_CALL, 16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, buffersize2, AudioTrack.MODE_STREAM);
            atrack2.setPlaybackRate(16000);

            for (AudioDeviceInfo deviceX : devices2Xins) {
                if (deviceX.getType() == AudioDeviceInfo.TYPE_USB_DEVICE) {
                    arec2.setPreferredDevice(deviceX);
                }
            }
            for (AudioDeviceInfo deviceX : devices2Xouts) {
                if (deviceX.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
                    atrack2.setPreferredDevice(deviceX);
                }
            }
            byte[] buffer2 = new byte[buffersize];

            arec2.startRecording();
            atrack2.play();
            while (isRecording) {
                arec2.read(buffer2, 0, buffersize);
                atrack2.write(buffer2, 0, buffer2.length);
            }

        }
    }).start();
}


Ovo je primer u Java za Android koji radi za jedan ili za drugi smer, kada se puste zajedno ovaj drugi ne proradi, ostane aktivan prvi koji je startovan. To je li limit Androida i telefona, na Linux / Unix je to inace izvodljivo ali ovaj muceni Android pravi problem, znaci ne moze da snima vise razlicitih trackova istovremeno sto je preduslov da ovaj code radi.