#Android tonegenerator misses
Explore tagged Tumblr posts
posttitta · 3 years ago
Text
Android tonegenerator misses
Tumblr media
ANDROID TONEGENERATOR MISSES ANDROID
ANDROID TONEGENERATOR MISSES PLUS
ANDROID TONEGENERATOR MISSES SERIES
Also it doesn’t make sounds while you’re sliding the slider. You have to settle for 18,342 and be grateful that you got that close, or maybe if you really want push the minus button 342 times to get to your goal frequency. You can also drag the slider but its nearly impossible to set it to 16,000 or 18,000 or 15,500, or anything specific.
ANDROID TONEGENERATOR MISSES PLUS
There’s a plus and minus button that moves up or down one single hz, which is practical at 60 hz, but silly at 16,237. Its almost impossible to choose a specific frequency on the high end. AudioTrack.getMinBufferSize() returns the smallest allowable buffer size in BYTES, and I was using this number as the length of the buffer in tick() - I now use half this number (2 Bytes per sample).I love that it’s simple, but it’s a little bit too simple. I also fixed one bug, but I don't think it has an effect. After this, it starts to get really choppy (sound only changes about every 100Mhz), and after that, it stops responding to slider input at all. I should also note that for about the first 3 seconds of the applications lifecycle, it works fine - a smooth sweep of the slider produces a smooth sweep in the audio output. SO, I know that I don't have any problems producing samples fast enough. So, each filled buffer lasts for ~0.0928 seconds of audio, which is much longer than it takes to create the data (1~6 ms). At 22050Hz, the audioTrack gives me a buffer size of 2048 samples (or 4096 Bytes). I lowered my sample rate to 22050Hz, and ran some empirical tests - I can fill my buffer (via tick()) in approximately 6ms in the worst case. The solution proposed that one must be able to produce samples fast enough for the audioTrack, which makes sense.
ANDROID TONEGENERATOR MISSES ANDROID
I found a similar problem here: Android AudioTrack buffering problems How can I get more gradual changes in frequency? I'm pretty confident that my logic in tick() is sound, as Log.i() verifies that the variables angleIncrement and currentAngle are being updated properly. The audio data is being written like this: _audioTrackOut.write(fromWorker, 0, fromWorker.length) Īny help would be greatly appreciated. _currentAngle = _currentAngle + _angleIncrement _angleIncrement = (float) (2.0f * Math.PI) * _freq / _sampleRate Update angleIncrement, as the frequency may have changed by now OutBuff = (short) (Short.MAX_VALUE * ((float) Math.sin(_currentAngle))) Short outBuff = new short // (buffer size in Bytes) / 2 The worker thread's buffer is being populated (via tick()) as such: public short tick() _audioTrackOut = new AudioTrack(AudioManager.STREAM_MUSIC, _sampleRate, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, _buffSize, AudioTrack.MODE_STREAM) My Audio track is set up as such: _buffSize = AudioTrack.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT)
ANDROID TONEGENERATOR MISSES SERIES
Oddly enough, it seems as if changes to the slider is causing the sine wave to play through intervals in the harmonic series However, I can verify that the frequency variable is NOT snapping to integral multiples of the default frequency. Theoretically, I should be hearing changes as minute as 1Hz, but I'm not. When I adjust the slider, the frequency changes in steps, often as wide as fourths or fifths. The frequency variable does change, as do the intermediate values used during the buffer calculations in the tick() method (verified by Log.i()).įor some reason, I can't seem to get a continuous change in audible frequency. Despite the large buffer size (thanks android), the responsiveness is OK. The slider on the UI simply changes a variable in the worker thread, so that any changes to the frequency (via the slider) will be read by the worker thread's tick() method.Īlmost everything The threads communicate well, there don't seem to be any gaps or clicks in the playback. The reason I am using two threads is because audiotrack.write() blocks, and I want the worker thread to be able to begin processing its data as soon as possible (rather than waiting for the audio track to finish writing). Once the buffer is filled, it alerts the output thread that the data is ready to be written to the audio track. The worker thread simply fills a buffer with the sine wave data every time its tick() method is called. Right now, I'm just playing a sine-tone in real time, with a slider in the UI that changes the tone's frequency as the user adjusts it.īasically, I have two threads - a worker thread and an output thread. I'm building a simple android audio synthesizer. I usually like to find the answer myself (be it through research or trial-and-error), but I'm stumped here.
Tumblr media
1 note · View note
gengreys · 3 years ago
Text
Android tonegenerator misses
Tumblr media
ANDROID TONEGENERATOR MISSES SERIAL
ANDROID TONEGENERATOR MISSES SOFTWARE
ANDROID TONEGENERATOR MISSES PLUS
It should be possible to copy and paste this directly into a sketch and have it work (after straightening out the Serial.print command). Using this it should be very easy to see the relationship between frequency and number of PWM steps available - particularly if a scope is used to view the output.
ANDROID TONEGENERATOR MISSES SERIAL
I built a test circuit and I reworked the code a bit to provide continuous frequency control, to provide a Serial output to see what is going on, and used map commands to keep everything in bounds. I found the original post extremely helpful in moving from the 490 Hz provided by the analog write command to my desired 16 kHz output. Assign values to OCR Registers, which output the PWM duty cycle. Multiply with ICR1 and divide by 1023 to give required percentage Turn read values from the POTs to float for mathematical Pwm2 = analogRead(A0) // read duty from A0 for PWM 1 Pwm1 = analogRead(A2) // read duty from A2 for PWM 2 If (analogRead(A3) 800) ICR1 = 1000 // Default value to 1kHz for A3 = 5V Program that lets different values on A3 choose different values of frequency, e.g. Select mode 8 and select divide by 8 on main clock. TCCR1A = _BV(COM1A1) | _BV(COM1B1) // phase and frequency correct mode. Value read from A0 and A2 to give PWM duty cycle output in terms // of 0-5V Float numbers to calculate duty for PWM 1 and PWM 2
ANDROID TONEGENERATOR MISSES PLUS
Value read from A1, in case plus mode is activated In my program, I had a POT on A3 to adjust the required frequency using ‘if’, and POT on A0 and A2 to adjust the output duty cycle. Now I shall go through the code which I wrote for my program. As discussed earlier, we shall be using mode which divides the main clock by 8.Īll the above tables have been copied from the ATmega328P datasheet. This is done by choosing the right modes from the following table. The last thing to do is to adjust the pre-scalar. Second thing to adjust is PWM, Phase and Frequency correct mode, with the TOP value determined by the ICR1 register, which is what determines the PWM Frequency. The last two options give us non-invert and invert mode respectively. These configurations are done by adjusting Timer1 registers TCCR1A and TCCR1B.įirst thing to adjust is choosing Phase and Frequency correct mode in invert or non-invert mode. To do this, we configure the timer to run in phase and frequency correct mode, and we can set it to either inverting or non-inverting mode. N = pre-scalar (set to 8 in my application)īased on the values of ICR1 from 1 to 65535 we get a frequency range from 15Hz to 1MHz. The output frequency is given by the formula: The number can be any value from 0 – 65535 (size = 16 bits). So in my application, I used Timer1, which is 16bit, and allows for a number to be stored in a register (ICR1), and the frequency is calculated based on that number. He uses Timer2 as an example, and while he explains everything in a great and easy to understand manner, the disadvantage there is that the user has to sacrifice one of the PWM outputs to gain the frequency adjustment on the other. While it is not the easiest read, it is much easier than reading the datasheet, and Ken has managed to bring it down to a few numbers. It is also available on the Arduino website, but over there it misses a few figures, so it is better to go to the original source. The second article which takes this to the next level is Ken Shirriff’s blog: Secrets of Arduino PWM. It also covers the issues you may encounter if you use that approach. This allows the user to use the different PWM signals at the prescaled frequencies without having to go through the ATmega328p datasheet. I found the following link very useful, and as it says, it is a very good cheat sheet: There is a lot of help on adjusting the frequencies. The Arduino offers six PWM outputs, and they are connected to three timers in the circuit in pairs:īeing connected to three different timers means that almost always these are not in sync, despite running off of one main clock, which is 16MHz in the case of the Arduino UNO. However, the challenge that faced me was producing a product that gave me a PWM signal(s) running on a variable frequency between 100Hz – 4kHz.
ANDROID TONEGENERATOR MISSES SOFTWARE
The product offers the user the ability to program in C language, and with a lot of libraries and open source software available, most applications are very easily achieved. The ARDUINO UNO is an amazing product that incorporates an ATmega328P onto a development board with a USB Bootloader.
Tumblr media
0 notes