Creating Java echo sound effect - java

So I am trying to manipulate a sound file in java by breaking it up into samples and storing those samples in an array. I then loop through the array changing each sample. I realize that there is already an echo filter in java but I need to design my own by having the sound repeated at various intervals throughout the sound clip with diminishing volume. I currently have a method that controls the volume but am stumped when it comes to getting the sound to repeat starting at a particular delay over the current sound file. This is what I have so far:
public void echoEffect(int delay){
SoundSample[] sampleArray = this.getSamples(); // get array
SoundSample sample = null; // current sample obj
int value = 0; // value at sample
// loop through SoundSample objects
for(int i = 0, index = 0; index < sampleArray.length; i++,index++)
{
sample = sampleArray[index]; // get current obj
value = sample.getValue(); // get the value
sample.setValue(value*2); // set the value
}
}
What I believe I need to do is change the method from void to Sound and return the the delayed sound file. Possibly returning something like value + value[i+delay]*(some fraction to decrease the sound)
New Update rather than post:
Anyway this is what I have so far I just can't seem to get the code to work properly and I know I'm close but I need the method to output an echo effect on a sound file. Here is what I have at the current point:
public void echo(int delay){
SoundSample[] sampleArray = this.getSamples(); // get array
//Sound target = new Sound(sampleArray.length);
SoundSample sampleDelay = null;
SoundSample sample = null; // current sample obj
int value = 0; // value at sample
int index = 0;
double value2 = 0;
// loop through SoundSample objects
while (index < sampleArray.length)
{
sample = sampleArray[index]; // get current obj
value = sample.getValue(); // get the value
sampleDelay = (sampleArray[delay-index]);
value2 = (sampleDelay.getValue()*.6);
sample.setValue(value + (int) value2); // set the value
index++; // increment index
}
}
Let me know what you guys think all this seems to do is shift the amplitude for some reason...
The problem with posting an SSCCE is that this is using some classes that are not regularly in java I believe and therefor I was just looking for someone to help with the logic. I'm trying to loop through the samples of a sound file then set the value at the delay point to be the beginning of the sound but fainter in volume. IDK if I'm explaining this right but I was hoping this would be a simple fix.

Instead of
sampleDelay = (sampleArray[delay-index]);
you want
sampleDelay = (sampleArray[index-delay]);

Are you sure it is not the following?
sampleDelay = (sampleArray[index*delay]);

Related

Variable in for loop is giving a message that "The value of the local variable i is not used"

I wrote a for loop that is supposed to determine if there is user input. If there is, it sets the 6 elements of int[] valueArr to the input, a vararg int[] statValue. If there is no input, it sets all elements equal to -1.
if (statValue.length == 6) {
for (int i = 0; i < 6; i++) {
valueArr[i] = statValue[i];
}
} else {
for (int i : valueArr) {
i = -1;
}
}
I am using Visual Studio Code, and it is giving me a message in for (int i : valueArr) :
"The value of the local variable i is not used."
That particular for loop syntax is still new to me, so I may be very well blind, but it was working in another file:
for(int i : rollResults) {
sum = sum + i;
}
I feel that I should also mention that the for loop giving me trouble is in a private void method. I'm still fairly new and just recently started using private methods. I noticed the method would give the same message when not used elsewhere, but I do not see why it would appear here.
I tried closing and reopening Visual Studio Code, deleting and retyping the code, and other forms of that. In my short experience, I've had times where I received errors and messages that should not be there and fixed them with what I mentioned, but none of that worked here.
for (int i : valueArr) {
.... CODE HERE ...
}
This sets up a loop which will run CODE HERE a certain number of times. Inside this loop, at the start of every loop, an entirely new variable is created named i, containing one of the values in valueArr. Once the loop ends this variable is destroyed. Notably, i is not directly the value in valueArr - modifying it does nothing - other than affect this one loop if you use i later in within the block. It does not modify the contents of valueArr.
Hence why you get the warning: i = -1 does nothing - you change what i is, and then the loop ends, which means i goes away and your code hasn't changed anything or done anything, which surely you didn't intend. Hence, warning.
It's not entirely clear what you want to do here. If you intend to set all values in valueArr to -1, you want:
for (int i = 0; i < valueArr.length; i++) valueArr[i] = -1;
Or, actually, you can do that more simply:
Arrays.fill(valueArr, -1);
valueArr[i] = -1 changes the value of the i-th value in the valueArr array to -1. for (int i : valueArr) i = -1; does nothing.

JPEG how to skip user defined tags while decoding the file stream

public ArrayList DCTread(char[] im,int flag,int select, int DC0,int row,int col){
//Input:im is the binary sequence of the host image. I wrote a "byte2char" function to convert that. flag serves as an outside pointer to locate the to-be-decoded chars. DC0 is the DC coeff for the last block.And row,col is simply for debug.
//Main Output:An ArrayList that contains the DCT coeffs,pointer(an int showing how many bits are read in this function)
String rev=new String();char[] DCcode;
ArrayList res = new ArrayList(2);int[][] ac = null; int[][] dc = null;int[][] coeff = new int[8][8];int pointer = 0;
int[] ans;int wordLen;int zeroLen;int diff;int ACnum = 1;int dct;
switch(select){//determine using which two huffman trees.
case(0):ac = a0;dc = d0;break;
case(1):ac = a1;dc = d0;break;
case(16):ac = a0;dc = d1;break;
case(17):ac = a1;dc = d1;break;
}
//DC
ans = T.huffmanDecoder(im,pointer+flag,dc,row,col);
if(ans[0]==-1){
int a1 = T.bin2dec_str(im,pointer+flag,8);int a2 = T.bin2dec_str(im,pointer+flag+8,8);
pointer +=16;//I wish to skip the User Defined Tags by reading its length
int autoLen = T.bin2dec_str(im,pointer+flag,8)*16+T.bin2dec_str(im,pointer+flag+8,8);
pointer +=autoLen*8;
}
ans = T.huffmanDecoder(im,pointer+flag,dc,row,col);
pointer += ans[0];wordLen = ans[1];
diff = T.i_unsignDecoder(T.bin2dec_str(im,pointer+flag,wordLen),wordLen);
coeff[0][0]= DC0 + diff;
pointer += wordLen;DCcode=Arrays.copyOfRange(im, flag, pointer+flag);
//AC
while(ACnum<=63){
ans = T.huffmanDecoder(im,pointer+flag,ac,row,col);
pointer += ans[0];
if(ans[1]==0){//
break;}
zeroLen = (ans[1]&(0xF0))/16;wordLen = ans[1]&(0x0F);
for(int j=0;j<zeroLen;j++){
coeff[zigZag[ACnum][0]][zigZag[ACnum][1]] = 0;
ACnum ++;
}
dct = T.i_unsignDecoder(T.bin2dec_str(im,pointer+flag,wordLen),wordLen);
pointer += wordLen;
coeff[zigZag[ACnum][0]][zigZag[ACnum][1]] = dct;
ACnum ++;
}
res.add(coeff);
res.add(pointer);
res.add(DCcode);
return res;
}
Hi everyone, firstly I'm so glad to welcome you for seeing my tough problem that has bothered me for two days, and gratefully thank you for your time helping me solve this problem. I've been a watcher of StackOverflow for a long time yet it really is my first time posing a problem.
What I want is to read DCT of JPEG in Java without utilizing the libjpeg library (which is written in C++).However I encounter many user defined tags(UDTs) that I find hard to skip using the method I listed above in the algorithm. I'm quite not familiar with UDTs.
AREN'T THEY written with the beginning of "0xFFXX 0x...."(where 0x.... gives the length of this tag)? Your suggestions would be of great help to me. Thanks!
The markers that can be user defined are APPn's and COM. Those markers are followed by lengths in BIG ENDIAN format.
However, I am surprised you are finding "many" such tags. Typically, there will only be one or two in a JPEG stream.

String naming convention in java

I am currently trying to make a naming convention. The idea behind this is parsing.
Lets say I obtain an xml doc. Everything can be used once, but these 2 in the code below can be submitted several times within the xml document. It could be 1, or simply 100.
This states that ItemNumber and ReceiptType will be grabbed for the first element.
ItemNumber1 = eElement.getElementsByTagName("ItemNumber").item(0).getTextContent();
ReceiptType1 = eElement.getElementsByTagName("ReceiptType").item(0).getTextContent();
This one states that it will grab the second submission if they were in their twice.
ItemNumber2 = eElement.getElementsByTagName("ItemNumber").item(1).getTextContent();
ReceiptType2 = eElement.getElementsByTagName("ReceiptType").item(1).getTextContent();
ItemNumber and ReceiptType must both be submitted together. So if there is 30 ItemNumbers, there must be 30 Receipt Types.
However now I would like to set this in an IF statement to create variables.
I was thinking something along the lines of:
int cnt = 2;
if (eElement.getElementsByTagName("ItemNumber").item(cnt).getTextContent();)
**MAKE VARIABLE**
Then make a loop which adds one to count to see if their is a third or 4th. Now here comes the tricky part..I need them set to a generated variable. Example if ItemNumber 2 existed, it would set it to
String ItemNumber2 = eElement.getElementsByTagName("ItemNumber").item(cnt).getTextContent();
I do not wish to make pre-made variable names as I don't want to code a possible 1000 variables if that 1000 were to happen.
KUDOS for anyone who can help or give tips on just small parts of this as in the naming convention etc. Thanks!
You don't know beforehand how many ItemNumbers and ReceiptTypes you'll get ? Maybe consider using two Lists (java.util.List). Here is an example.
boolean finished = ... ; // true if there is no more item to process
List<String> listItemNumbers = new ArrayList<>();
List<String> listReceiptTypes = new ArrayList<>();
int cnt = 0;
while(!finished) {
String itemNumber = eElement.getElementsByTagName("ItemNumber").item(cnt).getTextContent();
String receiptType = eElement.getElementsByTagName("ReceiptType").item(cnt).getTextContent();
listItemNumbers.add(itemNumber);
listReceiptTypes.add(receiptType);
++cnt;
// update 'finished' (to test if there are remaining itemNumbers to process)
}
// use them :
int indexYouNeed = 32; // for example
String itemNumber = listItemNumbers.get(indexYouNeed); // index start from 0
String receiptType = listReceiptTypes.get(indexYouNeed);

2D advice for nullpointer exception

I apologize in advance, I am a java noob.
I have this in a statement
if(a==0 && b<4)
{
value = ((elev[a][b]-elev[a+1][b])*0.00001* double "variable" ) ;
}
So my main question is would the following....
(elev[a][b]-elev[a+1][b])
return an int value (assuming that the array was initialized and populated with int values, and that for a==0 and b<4 none of the references are null.
Sorry in advance if this is silly. Please don't feel inclined to comment, but help would be appreciated. I haven't done a lot of this java stuff.
When i populated the array, I printed it's contents to make sure I was populating correctly, and everything is where it should be...
Alas, I get a null pointer error wherever that (elev[a][b] - elev[a+1][b]) is first referenced....yet i know that the values are being put there.
Next question. When i populate an array, if i want to reference the values,
while(input.hasNextInt())
{
elev[i][j] = input.nextInt(); <-- this is how i was doing it
}
of elev[][]... do i need to say
elev[i][j] = new input.nextInt();
or is how i was doing it sufficient. When i populated an ArrayList from a file I had to use the "new" prefix So i was trying to figure out why i would get a null there.
Like i said I did print the array after reading it from the file and it printed out everything was in its place.
Thanks everyone.
EDIT
ok sorry for simplicity sake i didn't put in the actual code of "value"
it is actually
double randKg = getRandKg(avgKgNitrogen[z]);
double gradient = 0.00001
double under = ((randKg *(elev[a][b] - elev[a+1][b]) * gradient));
2nd Edit
This is the code for how i populated.
try{
File file = new File(filename);
Scanner input = new Scanner(file);
int rows = 30;
int columns = 10;
int elev[][] = new int[30][10];
for(int i = 0; i < rows; ++i){
for(int j = 0; j < columns; ++j)
{
while(input.hasNextInt())
{
elev[i][j] = input.nextInt();
}
}
}
input.close();
}
catch (java.io.FileNotFoundException e) {
System.out.println("Error opening "+filename+", ending program");
System.exit(1);
}
3rd edit
So i am getting the null pointer here.....
(elev[a][b] - elev[a+1][b]) > 0 )
Which is why i originally asked. I have printed the array before when i populated and everything is where it should be.
You are getting a null pointer exception because double "variable" does not indicate to any integer or double value. Compiler is just trying to convert String 'variable' into double which is not possible. So, try eliminating the Double Quotes from "variable". Moreover you have not declared the data type of value variable.
Ignoring other problems in your code (covered by other answers), here's about your actual question:
If the code
if(a==0 && b<4) {
value = (elev[a][b] - elev[a+1][b]);
}
crashes with NullPointerException, it means elev is null. Assuming a and b are of type int, then there is no other way this can generate that exception (array out of bounds exception would be different). There are two options for the cause:
You execute above code before you do int elev[][] = new int[30][10];, so that elev still has the initial null value.
elev in the crashing line is a different variable than elev in initialization shown in the question.
And in you code, it seems to be 2. You create local elev in the initialization. It goes out of scope and is forgotten. You probably should have this initialization line in your method:
elev = new int[30][10];
And then you should have a class member variable instead of local variable in a method:
private int[][] elev;

Null Pointer that makes no sense to me?

Im currently working on a program and any time i call Products[1] there is no null pointer error however, when i call Products[0] or Products[2] i get a null pointer error. However i am still getting 2 different outputs almost like there is a [0] and 1 or 1 and 2 in the array. Here is my code
FileReader file = new FileReader(location);
BufferedReader reader = new BufferedReader(file);
int numberOfLines = readLines();
String [] data = new String[numberOfLines];
Products = new Product[numberOfLines];
calc = new Calculator();
int prod_count = 0;
for(int i = 0; i < numberOfLines; i++)
{
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
if(data[i].contains("input"))
{
continue;
}
Products[prod_count] = new Product();
Products[prod_count].setName(data[1]);
System.out.println(Products[prod_count].getName());
BigDecimal price = new BigDecimal(data[2]);
Products[prod_count].setPrice(price);
for(String dataSt : data)
{
if(dataSt.toLowerCase().contains("imported"))
{
Products[prod_count].setImported(true);
}
else{
Products[prod_count].setImported(false);
}
}
calc.calculateTax(Products[prod_count]);
calc.calculateItemTotal(Products[prod_count]);
prod_count++;
This is the output :
imported box of chocolates
1.50
11.50
imported bottle of perfume
7.12
54.62
This print works System.out.println(Products[1].getProductTotal());
This becomes a null pointer System.out.println(Products[2].getProductTotal());
This also becomes a null pointer System.out.println(Products[0].getProductTotal());
You're skipping lines containing "input".
if(data[i].contains("input")) {
continue; // Products[i] will be null
}
Probably it would be better to make products an ArrayList, and add only the meaningful rows to it.
products should also start with lowercase to follow Java conventions. Types start with uppercase, parameters & variables start with lowercase. Not all Java coding conventions are perfect -- but this one's very useful.
The code is otherwise structured fine, but arrays are not a very flexible type to build from program logic (since the length has to be pre-determined, skipping requires you to keep track of the index, and it can't track the size as you build it).
Generally you should build List (ArrayList). Map (HashMap, LinkedHashMap, TreeMap) and Set (HashSet) can be useful too.
Second bug: as Bohemian says: in data[] you've confused the concepts of a list of all lines, and data[] being the tokens parsed/ split from a single line.
"data" is generally a meaningless term. Use meaningful terms/names & your programs are far less likely to have bugs in them.
You should probably just use tokens for the line tokens, not declare it outside/ before it is needed, and not try to index it by line -- because, quite simply, there should be absolutely no need to.
for(int i = 0; i < numberOfLines; i++) {
// we shouldn't need data[] for all lines, and we weren't using it as such.
String line = reader.readLine();
String[] tokens = line.split("(?<=\\d)\\s+|\\s+at\\s+");
//
if (tokens[0].equals("input")) { // unclear which you actually mean.
/* if (line.contains("input")) { */
continue;
}
When you offer sample input for a question, edit it into the body of the question so it's readable. Putting it in the comments, where it can't be read properly, is just wasting the time of people who are trying to help you.
Bug alert: You are overwriting data:
String [] data = new String[numberOfLines];
then in the loop:
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
So who knows how large it is - depends on the success of the split - but your code relies on it being numberOfLines long.
You need to use different indexes for the line number and the new product objects. If you have 20 lines but 5 of them are "input" then you only have 15 new product objects.
For example:
int prod_count = 0;
for (int i = 0; i < numberOfLines; i++)
{
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
if (data[i].contains("input"))
{
continue;
}
Products[prod_count] = new Product();
Products[prod_count].setName(data[1]);
// etc.
prod_count++; // last thing to do
}

Categories

Resources