Exists library for android which converts bits to sound? For example, we have number as BigInteger. This number is converted to bytes and then this bytes are presented as short sound with different frequency (the best - ultra sounds). Of course, working in the opposite way would be great. Microphone get sound and converts it to bits.
Did anybody hear something about this kind of library?
Related
I'm trying to stream the audio data recorded on android to a micro-controller for playback. the audio is recorded using the AudioRecord class and is then sent over UDP. on the receiving side, the micro-controller receives the data and plays it using PWM. there are a couple of problems though :
I don't exactly know what format the AudioRecord class uses. i'm using ENCODING_PCM_16BIT but don't even know if its bipolar or not and how to convert it to unipolar if it is.
Due to limited bandwidth, i can't send more than 8 bits per sample. since 8 bit PCM isn't supported on my phone, i've used the 16 bit version but for conversion, i've just used the upper 8 bits. i'm not sure if that's right.
Since i've used a weird Crystal Oscillator for my circuit, the audio has to be sampled at 7.2kHz. my phone supports 8kHz sampling so i just use that and send %90 of the recorded data (using a for loop with a float as variable).
I've hooked up a 2W speaker to the OC2 pin on my ATmega32 using a 220 Ohm resistor and a 100nF capacitor to act as a filter. (Schematic) but again i'm not sure if its the correct way to do it.
So all of this put together produces nothing but noise as output. the only thing that changes when i "make some noise" near the MIC is the volume and the pattern of the output noise. the pattern doesn't make any sense though and is the same for human voice or music.
This is the piece of code i wrote to convert the data before sending it over UDP :
float divider = 8/7.2f;
int index=0;
recorder.read(record_buffer,0,buffer_size);
for(float i=0;i<buffer_size;i+=divider)
{
send_buffer[index++]= (byte) (record_buffer[(int)i] >> 8);
}
I don't know where to go from here. any suggestion is appreciated.
Update:
I took RussSchultz's advice and sent a sine wave over UDP and hooked up the output to my cheap O-Scope. this is what i get:
No Data : http://i.stack.imgur.com/1XYE6.png
No Data Close-up: http://i.stack.imgur.com/ip0ip.png
Sine : http://i.stack.imgur.com/rhtn0.png
Sine Close-up: http://i.stack.imgur.com/12JxZ.png
There are gaps when i start sending the sine wave which could be the result of buffer overflow on the hardware. since the gaps follow a pattern, it can't be UDP data loss.
so after working on this for a month i got it to work.
I don't exactly know what format the AudioRecord class uses. i'm using ENCODING_PCM_16BIT but don't even know if its bipolar or not and how to convert it to unipolar if it is.
Due to limited bandwidth, i can't send more than 8 bits per sample. since 8 bit PCM isn't supported on my phone, i've used the 16 bit version but for conversion, i've just used the upper 8 bits. i'm not sure if that's right.
its was bipolar. i had to convert it to 8 bit by adding half the dynamic range to each sample and taking the upper 8 bits.
Since i've used a weird Crystal Oscillator for my circuit, the audio has to be sampled at 7.2kHz. my phone supports 8kHz sampling so i just use that and send %90 of the recorded data (using a for loop with a float as variable).
even though i have a slight frequency shift, its still acceptable.
I've hooked up a 2W speaker to the OC2 pin on my ATmega32 using a 220 Ohm resistor and a 100nF capacitor to act as a filter. (Schematic) but again i'm not sure if its the correct way to do it.
i changed the filter to an exact 3.6KHz low pass RC one (using one of the many online calculators). the speaker should not be connected directly because it requires a current uC can't provide. you will still get an output but the quality is not good at all. what you should do is drive the speaker using a darlington pair or (as i have) use a simple op-amp circuit.
Preambule: This may sound like a very specific question, but this is actually a go / no go to build an API 16+ Android application using MediaCodec that is compatible with most phone.
I have an application with a h.264 MediaCodec that receives data from a buffer - and not a surface since I'm doing a lot of manipulations on the image. When creating the Encoder, I iterate through the list of possible encoders from the phone to make sure I'm using a proprietary encoder if any. This part is not a problem.
The problem is that each encoder has its color format preference. This may lead to color format conversion before encoding. In my proof-of-concept, for example, I included method to convert to NV12, NV21 and YV12, along with following very strict rules, like placing the start of some planes / interleaved plane at a precise offset in the buffer, etc. Just being able to make an encoded video look good may be a long story.
So, if I was certain that there is a standard in what Android h.264 MediaCodec Encoders are accepting, then that would limit a lot the amount of customization I have to do to get my API 16 MediaCodec proof-of-concept working on all devices.
[EDIT]
Oh. I just saw that it's impossible to create an input surface before Android 18. I will have to rely on detecting proprietary codecs and color formats for each case, random crashes, slow FPS, etc. Bwe... With a bit of chance, in 2017 or 2018, there will be enough devices with relevant API features to write a decent app using MediaCodec.
The really short answer is: No.
From Android 4.3 there is a CTS test that verifies that devices support either 420 planar or 420 semiplanar input - and, most importantly, that it interprets it in the same way as the others.
In practice, most devices from Android 4.1 do support either planar or semiplanar in one form or another, but there's a lot of quirks you need to work around, which are specific to different devices and chipsets. Some encoders (a bunch of Samsung Exynos devices) advertise semiplanar but interpret it with chroma components swapped compared to other devices (and the reference). Some encoders (also Samsung Exynos) advertise planar but interpret it as a proprietary tiled format (or crash). Some encoders (Qualcomm) assume extra alignment between the luma and chroma planes.
See https://code.google.com/p/android/issues/detail?id=37769 for more details on the issues you can encounter. In practice you can probably get it working on a large number of devices, but you'll need to more or less verify it per device and enable different quirk workarounds per device.
everyone, I am new for android. Now, I am making an android app and I will record a file after playing the file and my own voice. However, there could be some noise in my wav file. Are there some library I can use for removing noise for my app ?
There are different kinds of noise, and how you get rid of it depends. There is no "magic bullet".
To filter out certain frequencies, you can apply EQ. Roughly speaking, the parts of the signal necessary for clear understanding of speech fall in the range from 300 Hz - 3000 Hz. You can use EQ to eliminate everything below 300 Hz and above 3000 Hz. There are java libraries for this in JSyn, and processing.
If your speech and noise occupy the same frequency bands, the problem becomes more difficult. There are a variety of techniques, generally under the heading of "broadband noise reduction". I'm not aware of any java library that does this at all, much less well, but you could do it in native code. I've never tried it, but sox offers a "noisered" plugin that you could access from libsox.
I am working a phone recording software (android) which record a conversation between 2 people on a phone call. The output of each phone call is an audio file of which contains the sound from both the caller and callee.
However, most of the time, the voice from the phone that this software run on is clearer than the other. Users request me to make the 2 sound equally clear.
So the problem I have now is: I have a sound file containing voices from 2 sources with different volume, what should I do make the volume of voice from those 2 sources equally regarding the noise should not be increased. Given that this is a phone call so at a specific time there is only one person speaking.
I see at least 1 straight solution for this: making a program analyzing the wave form of the sound file, identifying parts of the sound file coming from the source having smaller voice and increase it to a level seemingly balance with the another. However this will be not an easy one to implement and I also hope that there would be better solution out there. Do you have any suggestion for me?
Thank you.
Well, the first thing to do is to get rid of all of the noise that you do not care about.
The spectrum that you would want to use is: 300 Hz to 3500 Hz
You can cut all of the other frequencies which would substantially cut your noise. You can then apply an autoequalization gain profile or even tap into the DSP profiles available on several devices.
I would also take a look at this whitepaper if you have a chance. (IEEE or ACM membership required).
An Auto-Equalization System Based on DirectShow Technology and Its Application in Audio Broadcast System of Radio Station
http://ieeexplore.ieee.org/xpl/articleDetails.jsp?tp=&arnumber=5384659&contentType=Conference+Publications&searchWithin%3Dp_Authors%3A.QT.Bai+Xinyue.QT.
This is how I have solved this problem:
1. I decode the audio into a series of Integer value thank to the storing WAV format.
The result be [xi] ; 0 < xi < 255
2. Then I have to decide 2 custom value:
- Noise threshold? if xi > threshold => it is not noise (pretty naive!)
- How long should sound be a chunk of human voice?
I myself choose the first value to 5 and the second value to 100ms
3. My algorithm will analyze the [xi] in to [Yi] with each Y is an array of x and each Y represent a chunk of human sound.
After that, I apply k-mean with k=2 and got 2 different cluster of Y, one belongs to the person whose voice is louder and the other belongs to the one with softer voice.
4. What left is pretty straight forward, I have to decide a parameter M, each x belong to a Y of the softer voice will multiply with M and I get the final result.
How can I get the volume of the audio stream coming in through the android microphone?
There may be a simpler way, but a method that I know would work is to use an AudioRecord object that is configured to watch the MediaRecorder.AudioSource.MIC audio source and record in 8-bit (AudioFormat.ENCODING_PCM_8BIT). You would need a thread to run in the background and constantly poll the object for audio with the read() call, which fills a given byte array with audio data from the mic.
Because you are recording in 8-bit, the max range of each audio sample would be -128 to 127 (although I may have this wrong - it could be from 0 to 256). You would have to experiment with taking either the maximum magnitude byte from the returned byte array, or perhaps the RMS average depending on your application's needs. The size of the byte array would also play a part in determining how frequently your application is able to sample the input audio volume.
If you are forced to record in 16-bit PCM, then you would have to look at the value of every other byte because each sample will span two bytes. The trick will be to know which byte to look at - I believe it should be the odd-indexed bytes returned in the byte array. Or if you want higher fidelity you could look at both bytes and you would know the output volume within the range 2^15 rather than just 2^7.
Since the byte type is signed in Java, you could simply look at every buffer[index * 2 + 1] byte and save the largest one. This would give you the max volume detected over the given sample.
As stated in my other answer, you could also take the average of these values, depending on what you are using this number for.