The following was taken from an Android app:
public void genTone(int freq){
for(int i = 0; i<numSamples; i++){
samples[i] = Math.pow(-1, (float)(i / (sampleRate/freq)));
}
int idx = 0;
int volume = 32767 * cx/wide;
for (final double dVal : samples) {
final short val = (short) ((dVal+1) * volume);
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
if(isRecording){
toRec.add((byte)(val & 0x00ff));
toRec.add((byte)((val & 0xff00) >>> 8));
}
}
}
The above code is a Java function in an Android app the generate a square wave with a specified frequency. The frequency is determined by an integer 'note' which is the last recorded position of a MotionEvent divided by the height of the screen. The frequency is 440 * 2^(note/12). I've made the program output in text the note and frequency, and it outputs what I want it to, but at certain notes, even though it outputs a different frequency in text, it sounds exactly the same. Is 8000 too low a sampleRate(per second)? Is this a well-known bug? Anything you can help me with?
The primary issue is that you need to leave the period as a float, because 8000/789 and 8000/739 otherwise round to the same integer:
float period = (float)sampleRate / (float)freq;
for(int i = 0; i<numSamples; i++){
samples[i] = ((int)(i/period) % 2)==0 ? 0 : 1;
}
As a secondary stylistic issue, I would also suggest removing the "+1" from the following line and instead requiring that cx/wide (which you should really call "gain") be exclusively in the range [0,1]:
final short val = (short) ((dVal) * volume);
Your original code was effectively generating samples as (0, +2, 0, +2,...) because of the +1, and then multiplying by cx/wide, but this would cause an overflow in your short val if cx/wide were ever greater than 1/2 (because 2*32767*1/2 is the maximum value of a short).
A more common practice would be to specify cx/wide as a gain in the range of (0,1) (where 0=min volume and 1=max volume) and also to enforce that constraint in the function.
A tertiary issue is that you are probably only using half of the dynamic range of the output. If the output is supposed to be 16-bit signed samples (look it up), then you can generate the original samples as ? -1 : 1 instead of 0/1. If the output stream accepts 16-bit unsigned samples, then you'd want to leave the samples as 0/1, but change volume to 65535, and use an int instead of a short for val.
Related
Off Topic: Let me start by saying Java is completely new to me. I've been programming for over 15 years and never have had a need for it beyond modifying others' codebases, so please forgive my ignorance and possibly improper terminology. I'm also not very familiar with RF, so if I'm way left field here, please let me know!
I'm building an SDR (Software Defined Radio) radio transmitter, and while I can successfully transmit on a frequency, when I send the stream (either from the device's microphone or bytes from a tone generator), what is coming through my handheld receiver sounds like static.
I believe this to be due to my receiver being set up to receive NFM (Narrowband Frequency Modulation) and WFM (Wideband Frequency Modulation) while the transmission coming from my SDR is sending raw, unmodulated data.
My question is: how do I modulate audio bytes (i.e. an InputStream) so that the resulting bytes are modulated in FM (Frequency Modulation) or AM (Amplitude Modulation), which I can then transmit through the SDR?
I can't seem to find a class or package that handles modulation (eventually I'm going to have to modulate WFM, FM, AM, SB, LSB, USB, DSB, etc.) despite there being quite a few open-source SDR codebases, but if you know where I can find this, that basically answers this question. Everything I've found so far has been for demodulation.
This is a class I've built around Xarph's Answer here on StackOverflow, it simply returns a byte array containing a simple, unmodulated audio signal, which can then be used to play sound through speakers (or transmit over an SDR, but due to the result not being properly modulated, it doesn't come through correctly on the receiver's end, which is what I'm having trouble figuring out)
public class ToneGenerator {
public static byte[] generateTone() {
return generateTone(60, 1000, 8000);
}
public static byte[] generateTone(double duration) {
return generateTone(duration, 1000, 8000);
}
public static byte[] generateTone(double duration, double freqOfTone) {
return generateTone(duration, freqOfTone, 8000);
}
public static byte[] generateTone(double duration, double freqOfTone, int sampleRate) {
double dnumSamples = duration * sampleRate;
dnumSamples = Math.ceil(dnumSamples);
int numSamples = (int) dnumSamples;
double sample[] = new double[numSamples];
byte generatedSnd[] = new byte[2 * numSamples];
for (int i = 0; i < numSamples; ++i) { // Fill the sample array
sample[i] = Math.sin(freqOfTone * 2 * Math.PI * i / (sampleRate));
}
// convert to 16 bit pcm sound array
// assumes the sample buffer is normalized.
// convert to 16 bit pcm sound array
// assumes the sample buffer is normalised.
int idx = 0;
int i = 0 ;
int ramp = numSamples / 20 ; // Amplitude ramp as a percent of sample count
for (i = 0; i< ramp; ++i) { // Ramp amplitude up (to avoid clicks)
double dVal = sample[i];
// Ramp up to maximum
final short val = (short) ((dVal * 32767 * i/ramp));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
for (i = i; i< numSamples - ramp; ++i) { // Max amplitude for most of the samples
double dVal = sample[i];
// scale to maximum amplitude
final short val = (short) ((dVal * 32767));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
for (i = i; i< numSamples; ++i) { // Ramp amplitude down
double dVal = sample[i];
// Ramp down to zero
final short val = (short) ((dVal * 32767 * (numSamples-i)/ramp ));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
return generatedSnd;
}
}
An answer to this doesn't necessarily need to be code, actually theory and an understanding of how FM or AM modulation works when it comes to processing a byte array and converting it to the proper format would probably be more valuable since I'll have to implement more modes in the future.
There is a lot that I don't know about radio. But I think I can say a couple things about the basics of modulation and the problem at hand given the modicum of physics that I have and the experience of coding an FM synthesizer.
First off, I think you might find it easier to work with the source signal's PCM data points if you convert them to normalized floats (ranging from -1f to 1f), rather than working with shorts.
The target frequency of the receiver, 510-1700 kHz (AM radio) is significantly faster than the sample rate of the source sound (presumably 44.1kHz). Assuming you have a way to output the resulting data, the math would involve taking a PCM value from your signal, scaling it appropriately (IDK how much) and multiplying the value against the PCM data points generated by your carrier signal that corresponds to the time interval.
For example, if the carrier signal were 882 kHz, you would multiply a sequence of 20 carrier signal values with the source signal value before moving on to the next source signal value. Again, my ignorance: the tech may have some sort of smoothing algorithm for the transition between the source signal data points. I really don't know about that or not, or at what stage it occurs.
For FM, we have carrier signals in the MHz range, so we are talking orders of magnitude more data being generated per each source signal value than with AM. I don't know the exact algorithm used but here is a simple conceptual way to implement frequency modulation of a sine that I used with my FM synthesizer.
Let's say you have a table with 1000 data points that represents a single sine wave that ranges between -1f to 1f. Let's say you have a cursor that repeatedly traverses the table. If the cursor advanced exactly 1 data point at 44100 fps and delivered the values at that rate, the resulting tone would be 44.1 Hz, yes? But you can also traverse the table via intervals larger than 1, for example 1.5. When the cursor lands in between two table values, one can use linear interpolation to determine the value to output. The cursor increment of 1.5 would result in the sine wave being pitched at 66.2 Hz.
What I think is happening with FM is that this cursor increment is continuously varied, and the amount it is varied depends on some sort of scaling from the source signal translated into a range of increments.
The specifics of the scaling are unknown to me. But suppose a signal is being transmitted with a carrier of 10MHz and ranges ~1% (roughly from 9.9 MHz to 10.1 MHz), the normalized source signal would have some sort of algorithm where a PCM value of -1 match an increment that traverses the carrier wave causing it to produce the slower frequency and +1 match an increment that traverses the carrier wave causing it to produce the higher frequency. So, if an increment of +1 delivers 10 MHz, maybe a source wave PCM signal of -1 elicits a cursor increment of +0.99, a PCM value of -0.5 elicits an increment of +0.995, a value of +0.5 elicits an increment of +1.005, a value of +1 elicits a cursor increment of 1.01.
This is pure speculation on my part as to the relationship between the source PCM values and how that are used to modulate the carrier frequency. But maybe it helps give a concrete image of the basic mechanism?
(I use something similar, employing a cursor to iterate over wav PCM data points at arbitrary increments, in AudioCue (a class for playing back audio data based on the Java Clip), for real time frequency shifting. Code line 1183 holds the cursor that iterates over the PCM data that was imported from the wav file, with the variable idx holding the cursor increment amount. Line 1317 is where we fetch the audio value after incrementing the cursor. Code lines 1372 has the method readFractionalFrame() which performs the linear interpolation. Real time volume changes are also implemented, and I use smoothing on the values that are provided from the public input hooks.)
Again, IDK if any sort of smoothing is used between source signal values or not. In my experience a lot of the tech involves filtering and other tricks of various sorts that improve fidelity or processing calculations.
I am working with some code that takes in a binary file as input. However, I am having trouble understanding the for loop in the code, as I don't understand what the bitwise operators do to IFD_Address, such as the |=, <<, and & 0xff. I think IFD_Address refers to a pointer in the binary file, but I am not sure. What is this piece of code trying to achieve?
byte[] IFD_Address_tmp = Arrays.copyOfRange(bytes, 4, 8);
int IFD_Address = 0;
int i = 0;
int shiftBy = 0;
for (shiftBy = 0; shiftBy < 32; shiftBy += 8) {
IFD_Address |= ((long) (IFD_Address_tmp[i] & 0xff)) << shiftBy;
i++;
}
This behavior is best understood in terms of moving bits around, not numbers. Bytes comprise eight bits, integers, 32 bits. The loop basically takes each byte in the array and places the corresponding bits in the integer IFD_Address in 8-bit chunks, from right (least significant) to left (most significant), like this:
About the bitwise operations:
& 0xff is required to capture the 8 bits into an integer;
<< shifts the bits to the left to select the appropriate place in IFD_Address;
|= sets the bits in IFD_Address.
See this tutorial for details.
In C++, why does a bool require one byte to store true or false where just one bit is enough for that, like 0 for false and 1 for true? (Why does Java also require one byte?)
Secondly, how much safer is it to use the following?
struct Bool {
bool trueOrFalse : 1;
};
Thirdly, even if it is safe, is the above field technique really going to help? Since I have heard that we save space there, but still compiler generated code to access them is bigger and slower than the code generated to access the primitives.
Why does a bool require one byte to store true or false where just one bit is enough
Because every object in C++ must be individually addressable* (that is, you must be able to have a pointer to it). You cannot address an individual bit (at least not on conventional hardware).
How much safer is it to use the following?
It's "safe", but it doesn't achieve much.
is the above field technique really going to help?
No, for the same reasons as above ;)
but still compiler generated code to access them is bigger and slower than the code generated to access the primitives.
Yes, this is true. On most platforms, this requires accessing the containing byte (or int or whatever), and then performing bit-shifts and bit-mask operations to access the relevant bit.
If you're really concerned about memory usage, you can use a std::bitset in C++ or a BitSet in Java, which pack bits.
* With a few exceptions.
Using a single bit is much slower and much more complicated to allocate. In C/C++ there is no way to get the address of one bit so you wouldn't be able to do &trueOrFalse as a bit.
Java has a BitSet and EnumSet which both use bitmaps. If you have very small number it may not make much difference. e.g. objects have to be atleast byte aligned and in HotSpot are 8 byte aligned (In C++ a new Object can be 8 to 16-byte aligned) This means saving a few bit might not save any space.
In Java at least, Bits are not faster unless they fit in cache better.
public static void main(String... ignored) {
BitSet bits = new BitSet(4000);
byte[] bytes = new byte[4000];
short[] shorts = new short[4000];
int[] ints = new int[4000];
for (int i = 0; i < 100; i++) {
long bitTime = timeFlip(bits) + timeFlip(bits);
long bytesTime = timeFlip(bytes) + timeFlip(bytes);
long shortsTime = timeFlip(shorts) + timeFlip(shorts);
long intsTime = timeFlip(ints) + timeFlip(ints);
System.out.printf("Flip time bits %.1f ns, bytes %.1f, shorts %.1f, ints %.1f%n",
bitTime / 2.0 / bits.size(), bytesTime / 2.0 / bytes.length,
shortsTime / 2.0 / shorts.length, intsTime / 2.0 / ints.length);
}
}
private static long timeFlip(BitSet bits) {
long start = System.nanoTime();
for (int i = 0, len = bits.size(); i < len; i++)
bits.flip(i);
return System.nanoTime() - start;
}
private static long timeFlip(short[] shorts) {
long start = System.nanoTime();
for (int i = 0, len = shorts.length; i < len; i++)
shorts[i] ^= 1;
return System.nanoTime() - start;
}
private static long timeFlip(byte[] bytes) {
long start = System.nanoTime();
for (int i = 0, len = bytes.length; i < len; i++)
bytes[i] ^= 1;
return System.nanoTime() - start;
}
private static long timeFlip(int[] ints) {
long start = System.nanoTime();
for (int i = 0, len = ints.length; i < len; i++)
ints[i] ^= 1;
return System.nanoTime() - start;
}
prints
Flip time bits 5.0 ns, bytes 0.6, shorts 0.6, ints 0.6
for sizes of 40000 and 400K
Flip time bits 6.2 ns, bytes 0.7, shorts 0.8, ints 1.1
for 4M
Flip time bits 4.1 ns, bytes 0.5, shorts 1.0, ints 2.3
and 40M
Flip time bits 6.2 ns, bytes 0.7, shorts 1.1, ints 2.4
If you want to store only one bit of information, there is nothing more compact than a char, which is the smallest addressable memory unit in C/C++. (Depending on the implementation, a bool might have the same size as a char but it is allowed to be bigger.)
A char is guaranteed by the C standard to hold at least 8 bits, however, it can also consist of more. The exact number is available via the CHAR_BIT macro defined in limits.h (in C) or climits (C++). Today, it is most common that CHAR_BIT == 8 but you cannot rely on it (see here). It is guaranteed to be 8, however, on POSIX compliant systems and on Windows.
Though it is not possible to reduce the memory footprint for a single flag, it is of course possible to combine multiple flags. Besides doing all bit operations manually, there are some alternatives:
If you know the number of bits at compile time
bitfields (as in your question). But beware, the ordering of fields is not guaranteed, which may result in portability issues.
std::bitset
If you know the size only at runtime
boost::dynamic_bitset
If you have to deal with large bitvectors, take a look at the BitMagic library. It supports compression and is heavily tuned.
As others have pointed out already, saving a few bits is not always a good idea. Possible drawbacks are:
Less readable code
Reduced execution speed because of the extra extraction code.
For the same reason, increases in code size, which may outweigh the savings in data consumption.
Hidden synchronization issues in multithreaded programs. For example, flipping two different bits by two different threads may result in a race condition. In contrast, it is always safe for two threads to modify two different objects of primitive types (e.g., char).
Typically, it makes sense when you are dealing with huge data because then you will benefit from less pressure on memory and cache.
Why don't you just store the state to a byte? Haven't actually tested the below, but it should give you an idea. You can even utilize a short or an int for 16 or 32 states. I believe I have a working JAVA example as well. I'll post this when I find it.
__int8 state = 0x0;
bool getState(int bit)
{
return (state & (1 << bit)) != 0x0;
}
void setAllOnline(bool online)
{
state = -online;
}
void reverseState(int bit)
{
state ^= (1 << bit);
}
Alright here's the JAVA version. I've stored it to an Int value since. If I remember correctly even using a byte would utilize 4 bytes anyways. And this obviously isn't be utilized as an array.
public class State
{
private int STATE;
public State() {
STATE = 0x0;
}
public State(int previous) {
STATE = previous;
}
/*
* #Usage - Used along side the #setMultiple(int, boolean);
* #Returns the value of a single bit.
*/
public static int valueOf(int bit)
{
return 1 << bit;
}
/*
* #Usage - Used along side the #setMultiple(int, boolean);
* #Returns the value of an array of bits.
*/
public static int valueOf(int... bits)
{
int value = 0x0;
for (int bit : bits)
value |= (1 << bit);
return value;
}
/*
* #Returns the value currently stored or the values of all 32 bits.
*/
public int getValue()
{
return STATE;
}
/*
* #Usage - Turns all bits online or offline.
* #Return - <TRUE> if all states are online. Otherwise <FALSE>.
*/
public boolean setAll(boolean online)
{
STATE = online ? -1 : 0;
return online;
}
/*
* #Usage - sets multiple bits at once to a specific state.
* #Warning - DO NOT SET BITS TO THIS! Use setMultiple(State.valueOf(#), boolean);
* #Return - <TRUE> if states were set to online. Otherwise <FALSE>.
*/
public boolean setMultiple(int value, boolean online)
{
STATE |= value;
if (!online)
STATE ^= value;
return online;
}
/*
* #Usage - sets a single bit to a specific state.
* #Return - <TRUE> if this bit was set to online. Otherwise <FALSE>.
*/
public boolean set(int bit, boolean online)
{
STATE |= (1 << bit);
if(!online)
STATE ^= (1 << bit);
return online;
}
/*
* #return = the new current state of this bit.
* #Usage = Good for situations that are reversed.
*/
public boolean reverse(int bit)
{
return (STATE ^= (1 << bit)) == (1 << bit);
}
/*
* #return = <TRUE> if this bit is online. Otherwise <FALSE>.
*/
public boolean online(int bit)
{
int value = 1 << bit;
return (STATE & value) == value;
}
/*
* #return = a String contains full debug information.
*/
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("TOTAL VALUE: ");
sb.append(STATE);
for (int i = 0; i < 0x20; i++)
{
sb.append("\nState(");
sb.append(i);
sb.append("): ");
sb.append(online(i));
sb.append(", ValueOf: ");
sb.append(State.valueOf(i));
}
return sb.toString();
}
}
Also I should point out that you really shouldn't utilize a special class for this, but to just have the variable stored within the class that'll be most likely utilizing it. If you plan to have 100's or even 1000's of Boolean values consider an array of bytes.
E.g. the below example.
boolean[] states = new boolean[4096];
can be converted into the below.
int[] states = new int[128];
Now you're probably wondering how you'll access index 4095 from a 128 array. So what this is doing is if we simplify it. The 4095 is be shifted 5 bits to the right which is technically the same as divide by 32. So 4095 / 32 = rounded down (127). So we are at index 127 of the array. Then we perform 4095 & 31 which will cast it to a value between 0 and 31. This will only work with powers of two minus 1. E.g. 0,1,3,7,15,31,63,127,255,511,1023, etc...
So now we can access the bit at that position. As you can see this is very very compact and beats having 4096 booleans in a file :) This will also provide a much faster read/write to a binary file. I have no idea what this BitSet stuff is, but it looks like complete garbage and since byte,short,int,long are already in their bit forms technically you might as well use them as is. Then creating some complex class to access the individual bits from memory which is what I could grasp from reading a few posts.
boolean getState(int index)
{
return (states[index >> 5] & 1 << (index & 0x1F)) != 0x0;
}
Further information...
Basically if the above was a bit confusing here's a simplified version of what's happening.
The types "byte", "short", "int", "long" all are data types which have different ranges.
You can view this link: http://msdn.microsoft.com/en-us/library/s3f49ktz(v=vs.80).aspx
To see the data ranges of each.
So a byte is equal to 8 bits. So an int which is 4 bytes will be 32 bits.
Now there isn't any easy way to perform some value to the N power. However thanks to bit shifting we can simulate it somewhat. By performing 1 << N this equates to 1 * 2^N. So if we did 2 << 2^N we'd be doing 2 * 2^N. So to perform powers of two always do "1 << N".
Now we know that a int will have 32 bits so can use each bits so we can just simply index them.
To keep things simple think of the "&" operator as a way to check if a value contains the bits of another value. So let's say we had a value which was 31. To get to 31. we must add the following bits 0 through 4. Which are 1,2,4,8, and 16. These all add up to 31. Now when we performing 31 & 16 this will return 16 because the bit 4 which is 2^4 = 16. Is located in this value. Now let's say we performed 31 & 20 which is checking if bits 2 and 4 are located in this value. This will return 20 since both bits 2 and 4 are located here 2^2 = 4 + 2^4 = 16 = 20. Now let's say we did 31 & 48. This is checking for bits 4 and 5. Well we don't have bit 5 in 31. So this will only return 16. It will not return 0. So when performing multiple checks you must check that it physically equals that value. Instead of checking if it equals 0.
The below will verify if an individual bit is at 0 or 1. 0 being false, and 1 being true.
bool getState(int bit)
{
return (state & (1 << bit)) != 0x0;
}
The below is example of checking two values if they contain those bits. Think of it like each bit is represented as 2^BIT so when we do
I'll quickly go over some of the operators. We've just recently explained the "&" operator slightly. Now for the "|" operator.
When performing the following
int value = 31;
value |= 16;
value |= 16;
value |= 16;
value |= 16;
The value will still be 31. This is because bit 4 or 2^4=16 is already turned on or set to 1. So performing "|" returns that value with that bit turned on. If it's already turned on no changes are made. We utilize "|=" to actually set the variable to that returned value.
Instead of doing -> "value = value | 16;". We just do "value |= 16;".
Now let's look a bit further into how the "&" and "|" can be utilized.
/*
* This contains bits 0,1,2,3,4,8,9 turned on.
*/
const int CHECK = 1 | 2 | 4 | 8 | 16 | 256 | 512;
/*
* This is some value were we add bits 0 through 9, but we skip 0 and 8.
*/
int value = 2 | 4 | 8 | 16 | 32 | 64 | 128 | 512;
So when we perform the below code.
int return_code = value & CHECK;
The return code will be 2 + 4 + 8 + 16 + 512 = 542
So we were checking for 799, but we recieved 542 This is because bits o and 8 are offline we equal 256 + 1 = 257 and 799 - 257 = 542.
The above is great great great way to check if let's say we were making a video game and wanted to check if so and so buttons were pressed if any of them were pressed. We could simply check each of those bits with one check and it would be so many times more efficient than performing a Boolean check on every single state.
Now let's say we have Boolean value which is always reversed.
Normally you'd do something like
bool state = false;
state = !state;
Well this can be done with bits as well utilizing the "^" operator.
Just as we performed "1 << N" to choose the whole value of that bit. We can do the same with the reverse. So just like we showed how "|=" stores the return we will do the same with "^=". So what this does is if that bit is on we turn it off. If it's off we turn it on.
void reverseState(int bit)
{
state ^= (1 << bit);
}
You can even have it return the current state. If you wanted it to return the previous state just swap "!=" to "==". So what this does is performs the reversal then checks the current state.
bool reverseAndGet(int bit)
{
return ((state ^= (1 << bit)) & (1 << bit)) != 0x0;
}
Storing multiple non single bit aka bool values into a int can also be done. Let's say we normally write out our coordinate position like the below.
int posX = 0;
int posY = 0;
int posZ = 0;
Now let's say these never wen't passed 1023. So 0 through 1023 was the maximum distance on all of these. I'm choose 1023 for other purposes as previously mentioned you can manipulate the "&" variable as a way to force a value between 0 and 2^N - 1 values. So let's say your range was 0 through 1023. We can perform "value & 1023" and it'll always be a value between 0 and 1023 without any index parameter checks. Keep in mind as previously mentioned this only works with powers of two minus one. 2^10 = 1024 - 1 = 1023.
E.g. no more if (value >= 0 && value <= 1023).
So 2^10 = 1024, which requires 10 bits in order to hold a number between 0 and 1023.
So 10x3 = 30 which is still less than or equal to 32. Is sufficient for holding all these values in an int.
So we can perform the following. So to see how many bits we used. We do 0 + 10 + 20. The reason I put the 0 there is to show you visually that 2^0 = 1 so # * 1 = #. The reason we need y << 10 is because x uses up 10 bits which is 0 through 1023. So we need to multiple y by 1024 to have unique values for each. Then Z needs to be multiplied by 2^20 which is 1,048,576.
int position = (x << 0) | (y << 10) | (z << 20);
This makes comparisons fast.
We can now do
return this.position == position;
apposed to
return this.x == x && this.y == y && this.z == z;
Now what if we wanted the actual positions of each?
For the x we simply do the following.
int getX()
{
return position & 1023;
}
Then for the y we need to perform a left bit shift then AND it.
int getY()
{
return (position >> 10) & 1023;
}
As you may guess the Z is the same as the Y, but instead of 10 we use 20.
int getZ()
{
return (position >> 20) & 1023;
}
I hope whoever views this will find it worth while information :).
If you really want to use 1 bit, you can use a char to store 8 booleans, and bitshift to get the value of the one you want. I doubt it will be faster, and it's probably going to gives you a lot of headaches working that way, but technically it's possible.
On a side note, an attempt like this could prove useful for systems that don't have a lot of memory available for variables but do have some more processing power then what you need. I highly doubt you will ever need it though.
I have found some code to calculate microphone sound level (RMS):
public int calculateRMSLevel(byte[] audioData) {
// audioData might be buffered data read from a data line
long lSum = 0;
for (int i = 0; i < audioData.length; i++) {
lSum = lSum + audioData[i];
}
double dAvg = lSum / audioData.length;
double sumMeanSquare = 0d;
for (int j = 0; j < audioData.length; j++) {
sumMeanSquare = sumMeanSquare + Math.pow(audioData[j] - dAvg, 2d);
}
double averageMeanSquare = sumMeanSquare / audioData.length;
return (int) (Math.pow(averageMeanSquare, 0.5d) + 0.5);
}
But it only works for the following audio format:
private AudioFormat getAudioFormat() {
float sampleRate = 8000.0F;
int sampleSizeInBits = 8;
int channels = 1;
boolean signed = true;
boolean bigEndian = true;
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,
bigEndian);
}
How to extend the code so it can work with different bitness? If I change the bitness to 16 it returns values of around 50 when silence where for 8 bits it returns 1 or 2.Also I would like to graph the sound levels on a graph, how are the sound level values related to time?
The sample rate doesn't matter, but the bit depth, endianness, and, in a different way, number of channels, do matter.
To see why, you must simply notice that the function in question takes a byte array as an argument and processes each value from that array individually. The byte datatype is an 8-bit value. If you want something that works with 16-bit values, you need to use a different datatype (short) or convert to that from bytes.
Once you do that, you will still get different values for 16 bits vs 8 bit because the range is different: 8 bit goes from -128 to +127 and 16 bit goes from -32768 to +32767, but they are both measuring the same thing, meaning they scaling the same real-word values to different represented values.
As for sound-levels and their relationship to time.... well it depends on your sample rate and the size of the arrays going into this function. For example, if your samplerate is 8kHz and you have 2048 samples per buffer, then your function is going to be called 8000/2048 or about 3.9 times per second, meaning your results are coming in at that rate (every 256 milliseconds).
You can always scale your inputs to the same min-max range to get similar results from different formats.
As for sound level w.r.t. time, there isn't any relation other than samples being apart from each other by 1/SampleRate(in Hz) seconds.
I somehow have to keep my program running until the output of the exponent function exceeds the input value, and then compare that to the previous output of the exponent function. How would I do something like that, even if in just pseudocode?
Find logarithm to base 2 from given number => x := log (2, input)
Round the value acquired in step 1 both up and down => y := round(x), z := round(x) + 1
Find 2^y, 2^z, compare them both with input and choose the one that suits better
Depending on which language you're using, you can do this easily using bitwise operations. You want either the value with a single 1 bit set greater than the highest one bit set in the input value, or the value with the highest one bit set in the input value.
If you do set all of the bits below the highest set bit to 1, then add one you end up with the next greater power of two. You can right shift this to get the next lower power of two and choose the closer of the two.
unsigned closest_power_of_two(unsigned value)
{
unsigned above = (value - 1); // handle case where input is a power of two
above |= above >> 1; // set all of the bits below the highest bit
above |= above >> 2;
above |= above >> 4;
above |= above >> 8;
above |= above >> 16;
++above; // add one, carrying all the way through
// leaving only one bit set.
unsigned below = above >> 1; // find the next lower power of two.
return (above - value) < (value - below) ? above : below;
}
See Bit Twiddling Hacks for other similar tricks.
Apart from the looping there's also one solution that may be faster depending on how the compiler maps the nlz instruction:
public int nextPowerOfTwo(int val) {
return 1 << (32 - Integer.numberOfLeadingZeros(val - 1));
}
No explicit looping and certainly more efficient than the solutions using Math.pow. Hard to say more without looking what code the compiler generates for numberOfLeadingZeros.
With that we can then easily get the lower power of 2 and then compare which one is nearer - the last part has to be done for each solution it seems to me.
set x to 1.
while x < target, set x = 2 * x
then just return x or x / 2, whichever is closer to the target.
public static int neareastPower2(int in) {
if (in <= 1) {
return 1;
}
int result = 2;
while (in > 3) {
in = in >> 1;
result = result << 1;
}
if (in == 3) {
return result << 1;
} else {
return result;
}
}
I will use 5 as input for an easy example instead of 50.
Convert the input to bits/bytes, in this case 101
Since you are looking for powers of two, your answer will all be of the form 10000...00 (a one with a certain amount of zeros). You take the input value (3 bits) and calculate the integer value of 100 (3 bits) and 1000 (4 bits). The integer 100 will be smaller then the input, the integer 1000 will be larger.
You calculate the difference between the input and the two possible values and use the smallest one. In this case 100 = 4 (difference of 1) while 1000 = 8 (difference of 3), so the searched answer is 4
public static int neareastPower2(int in) {
return (int) Math.pow(2, Math.round(Math.log(in) / Math.log(2)));
}
Here's the pseudo code for a function that takes the input number and returns your answer.
int findit( int x) {
int a = int(log(x)/log(2));
if(x >= 2^a + 2^(a-1))
return 2^(a+1)
else
return 2^a
}
Here's a bitwise solution--it will return the lessor of 2^N and 2^(N+1) in case of a tie. This should be very fast compare to invoking the log() function
let mask = (~0 >> 1) + 1
while ( mask > value )
mask >> 1
return ( mask & value == 0 ) ? mask : mask << 1