Android: Using Microphone and Headphones Simultaneously - java

I have an application that needs to use a high-quality microphone and headphones simultaneously. On my phone, there is only one input for an audio device. How can I connect to and handle in/out data from each?
edit: I dont want to capture two input sources at once. I want to record from a microphone, use it to modify audio which i have already recorded, then output the result to a headphone in real time. I know this is possible, however I dont know how to connect and differentiate between two devices connected to the audio jack via a splitter.

Most (probably all) Android devices with a 3.5mm port support a TRRS connector(https://en.m.wikipedia.org/wiki/Phone_connector_(audio)#TRRS_standards)
So there is a different hardware channel for the microphone and the headphones, and it's not possible to accidentally use the wrong one in software or for that matter manually select what to use the hardware connections for, it's predefined.
But so the point is that you need the right splitter exactly for this, not just a normal audio-splitter but one that specifically splits the input/microphone channel from the output/heaphone channel.
If you use the search term "audio and microphone 3.5mm splitter android", then you should find the correct splitter hardware shopping recommendations:
https://www.google.com/search?q=audio+and+microphone+3.5mm+splitter+android&tbm=shop
Here is an example picture:

Related

Is it possible to open 2 microphones in Android at same time with Oboe library?

I'm trying to open 2 microphone streams with google's Oboe library like this, for each microphone:
oboe::AudioStreamBuilder builder;
builder.setChannelCount(channelCount)
->setDirection(isInput ? oboe::Direction::Input : oboe::Direction::Output)
->setSharingMode((oboe::SharingMode) sharingMode)
->setPerformanceMode((oboe::PerformanceMode) performanceMode)
->setInputPreset((oboe::InputPreset)inputPreset)
->setDeviceId(deviceId)
->setSessionId((oboe::SessionId) sessionId)
->setSampleRate(sampleRate)
->setFormat((oboe::AudioFormat) format)
->setChannelConversionAllowed(channelConversionAllowed)
->setFormatConversionAllowed(formatConversionAllowed)
->setSampleRateConversionQuality((oboe::SampleRateConversionQuality) rateConversionQuality)
;
oboe::AudioStream *oboeStream = nullptr;
oboe::Result result = builder.openStream(&oboeStream);
As you can see, the deviceId is passed to the builder. This is the microphone ID that I get with some java methods. I pass 7 and 9 as ids, for built-in microphone and telephone microphone. The problem is when I try to start the 2 streams:
oboeStream.requestStart()
I get this error for the second stream:
E/AudioRecord: start() status -38
but if I try to open the first one only, and then the second one only, in 2 different builds, everything works. So is it true that I cannot open 2 microphone streams with Oboe? It looks like a powerful library, it shouldbe possible.
Android doesn't allow you to capture audio from more than one thread most of the time. It doesn't matter how many input sources your phone has or which library do you use. You can't open two audio streams at the same time. Even two separate ordinary applications don't have access to the input sources simultaneously and if you want to start recording while a stream source captured by another process an error would be returned. From Android 10 some changes occurred. According to the doc:
Android 10 (API level 29) and higher imposes a priority scheme that
can switch the input audio stream between apps while they are running.
In most cases, if a new app acquires the audio input, the previously
capturing app continues to run, but receives silence. In some cases
the system can continue to deliver audio to both apps.
Two streams mean two thread which is like two different apps. In some scenarios, two processes can capture audio at the same time like so:
Assistant + ordinary app
Accessibility service + ordinary app
Voice call + ordinary app
For more details please read this page at the Android doc.
in fact even if you have two microphones, from what is stated in the docs it is not possible to have more than one stream at the same time, ONLY IF we are talking about internal microphones since they are represented by the same channel, if instead we are talking about external devices then there are two input-output channels and you can have two different streams.

How to capture an Infrared signal pattern & frequency for later use?

I'm wanting to create an Android app that will send IR signals, but I don't know how to find the signal patterns or the frequencies from the original transmitter.
I purchased a small USB IR receiver (not Microsoft, but uses the Microsoft EHome drivers) and I can see the patterns from WinLIRC, but they are barely consistent, and trying to use any of them doesn't work on the receiver. I also am not sure what frequency to transmit on. I have my app sending back the signals and I can see them in LIRC, and they're accurate, but the receiver from the original remote doesn't respond to it.
How can I get the info from the original transmitter, accurately, without spending tons of money on something like an oscilloscope?

How should I manage Bluetooth connections in Android?

Q. What are your best practices in managing bluetooth connectivity?
I've read the android bluetooth guide & many bluetooth connectivity tutorials. Not helpful with encapsulation-design nor best practices.
When should I open/close the connection?
Is the "connection" with a single bluetooth device called a "socket" connection?
Can a single connection send data while listening? (...or between listening states).
I've never coded connectivity with external devices before. It took two weeks for me to wrap my head around the code that scans for near-by bluetooth devices and throw them into a ListView. Listeners, Broadcasts, and Adapters!
My project will be printing 1-40 receipts every 15 minutes on a bluetooth receipt printer. At the moment, security is not an issue. On the same connection, it will also be receiving data (sending & receiving simultaneously does not appear to be necessary but would be useful). I'm not yet sure how the devices are configured on this single dongle device but I would guess the devices are connected via USB controller to the dongle.
So far, I have 1 object to manage a single I/O connection. Staticly I open an activity to select a connection (to later save the label, mac, and pin in the database). Based on tutorials, I have "open", "listen", "send", and "close" methods. What confuses me is "how" to use these functions. Can I leave a connection open all day (10hrs) and use it every 3mins? Should I open/close the connection when sending or requesting data? Where would I detect the need to reconnect?
sorry for the short answer, but from my practice with the Bluetooth API, I have found that this video describe the things very good (totally personal opinion...)
Video 1
In addition this is useful when you do NOT have any previous experience
Tutorial
And as last check out this question in stackoverflow it has a bunch of good references and examples!!
Again sorry for the shortage, but I believe that if you check these out at least most of your questions and concerns will become answered!
:)
EDIT
So, let me be a bit more descriptive and share some of my experience.
I have written an App that communicates with BLE device that has 3 functions
double sided event driven button (push the button on phone -> event is fired to the device; push the button on the BLE device -> event is fired to the phone)
send request from phone -> BLE device answers with current battery percentage
continuously reading strength signal (as aprox. distance) between the phone and the BLE device
So far so good, now the things is that the basic approach is:
Search for BLE devices (bluetooth search or "discovery" of nearby bluetooth devices)
Here you will need android permissions!
Choose the device you want to connect to
To differ the devices (maybe there are a lot around you :) ) you can use BLE device's name or UUID or ... best - use the name ;)
After both devices connect to each other you can then start the Gatt communication. The approach with state machine is a little too much overkill for me. But anyway the communication is done through bytes (in my case...)
In one of the videos/resources there was something specific and VERY HELPFUL at least for me! To be honest I don't remember it exactly, but the idea was that before any communication it's RECOMMENDED to read/get all the options from the BLE device or something similar...
Maybe it was something like discoverOptions() or something like that
Great thing will be to know your device "communication codes" or at least I call them that way.
Check this link for example: Link
** Now you can see there are tables with the USEFUL INFO! E.g. if you want to read the battery level you navigate to this page and find that in order to read the battery, the service name is UUID XXXXX and you need to send 0x01 to the BLE device and it will "answer" to your call with some data which is again in bytes.
I really hope that this is somehow helpful!
PLEASE NOTE
This is strictly coming from my experience and there could be some mismatches or wrong terms, but that's how I personally see the things and because my project was long ago, I don't remember most of the things exactly.
IMPORTANT:
This is only a summery of STUCI's provided links above. He has since updated his answer and I have not updated/edited this summery. Topics in my summery are not explanatory but provided for reference and help in generating specific questions.
Original Post...
Thank you Stuci! Some of that was helpful:- some not. I thought it best to collect my thoughts and see what has been explained and if anything hasn't.
(I can't post this much in a comment tho, sorry)
PLEASE CALL ME ON ANYTHING THAT IS INCORRECT.
Video of Bluetooth LE
(Covers a bunch of random things)
While I "dont-like" videos of code:- I watched it because it was recommended ... and I am glad I did. While not very helpful it did introduce some concepts I was unaware of. Since I am targeting old android devices (v8+) the LE features are inconsequential.
Pushing Data: [Depending on the source feature-set], one does not need to continually pull data (ex. with a temperature sensor) but some devices can "push" it to the device on change. Seems to use the 'advertisement" design concept.
UUIDs define Services and/or Characteristics of the connected device.
Possibility to write configuration on (to) connected devices.
Characteristics which seem to be simply "settings" that can be assigned over bluetooth. Not sure if this (~19mins) applies to non-gatt connectoins but seems similar to the state-machine that controls
Advertisements which seem to be the "metadata" regarding the devices current state or config (~24mins). Again, not sure if this even applies to non LE Bluetooth.
Leaving Connections Open
Bluetooth connections can indeed remain open; starting at the point which the "startActivityForResult(...) method is successfully called.
Two basic things affect whether or not one would want to maintain an open connection:
Understand the power consumption.
Having the adapter active simply consumes additional power. If one can keep the adapter shut-off while it is not "absolutely-needed" will mearly save battery power.
Accidental disconnects are managed.
Other than leaving the connection continually connected, one could disconnect & reconnect regularly at specified intervals to ensure a connection is up.
In the thread(s) used for I/O, one could check for a disconnect and reconnect (possibly starting a new thread).
I/O Streams pr Connection
A single connection can indeed "have" simultaneous Input & Output streams. I
Since it was suggested, I re-read Android's Bluetooth Guide and under "managing a connection" (talking about a single socket) I noticed this...
Get the InputStream and OutputStream that handle transmissions through the socket, via getInputStream() and getOutputStream(), respectively.
Read and write data to the streams with read(byte[]) and write(byte[]).
...but continues with noting that read & write block each other. Something I still need to look further into. It seems like you cant I/O simultaneously on the same socket???
Max Connections
I also looked into the max connection issue Stuci added and found no documentation on the Android-side. It might exist, I cant find it. However, most people seem to agree that there is a limitation (that could be as low as 4) imposed by whatever hardware you are coding for.
Some notable links:
- How many devices we can pair via Bluetooth of BLE to Android?
- How many maximum device can we pair via Bluetooth to android device at a time?
- https://groups.google.com/forum/#!topic/android-developers/adeBD275u30

Tracking audio (level of intensity) - android/iphone

Is it possible to retrieve the characteristics of the audio output signal dedicated to headphones during audio playback? I don't want to record the signal per se (that is, I don't want to record the radio with a tape player to make an 80s style mixtape), but instead I only want to know the strength, in decibels, of the signal for medical research purposes.
I was thinking this could maybe be accomplished in the same manner a visualizer does?
If you're writing an Android app, I think you're looking for the AudioManager, through which you can query the volume of the different audio streams.
Calling getStreamVolume should get you the data you want.

Audio programming, Sound Processing and DSP

I was playing with a karaoke application on iPhone and came up with following questions:
The application allowed its users to control the volume of the artist; even mute it. How is this possible?
Does adjusting artist sound/setting equalizer etc. mean performing some transformation of required frequencies? What sort of mathematics is required here(frequency domain transformations)?
The application recorded users voice input via a mic. Assuming that the sound is recorded in some format, the application was able to mix the recording with the karaoke track(with artists voice muted). How can this be done?
Did they play both the track and voice recording simultaneously? Or maybe they inserted additional frequency(channel?) in the original track, maybe replaced it?
What sort of DSP is involved here? Is this possible in Java, Objective C?
I am curious and if you have links to documents or books that can help me understand the mechanism here, please share.
Thanks.
I don't know that particular application, probably it has a voice track recorder separately.
For generic 2-channels stereo sound the easiest voice suppression can be performed assuming that artist's voice is somehow equally balanced between two channels (acoustically it appears in center). So the simplest 'DSP' would be subtract one channel from another. It does not work that well however with modern records since all instruments and voice are recorded separately and then mixed together (meaning that voice will not be necessarily in phase between two channels).
I have written two detailed blogposts on how to get a custom EQ in iOS. But i have no details about how to do the DSP yourself. If you simply want to choose between a wide range of effects and stuff, try this.
First post explains how you build libsox:
http://uberblo.gs/2011/04/iosiphoneos-equalizer-with-libsox-making-it-a-framework
The second explains how to use it:
http://uberblo.gs/2011/04/iosiphoneos-equalizer-with-libsox-doing-effects
please up the answer if it helped you! thanks!

Categories