Playing consecutive pitches in MATLAB - audio

so I've been struggling with this for a while. I am supposed to make a sequence of tones play with only one soundsc(wave,fs) call, but when I try to put the tone waves in an array, it just plays them at the same time instead of consecutively. For example:
pitch1 = sin(2*pi*freq1*t);
pitch2 = sin(2*pi*freq2*t);
pitch3 = sin(2*pi*freq3*t);
concat_pitch = [pitch1; pitch2; pitch3]; % I want them to play in order, not together
soundsc(concat_pitch, fs); % this just plays them all together
Can anyone help me out? Thanks.

Change your concatenation to form a single row vector:
concat_pitch = [pitch1, pitch2, pitch3];
Or if the concatenation you specified is important and has to stay as is, then you can loop through the rows of the 2-d matrix:
for ind=1:length(concat_pitch)
soundsc(concat_pitch(ind,:), fs);
end

Related

Python loop performance

If I loop through 1 big list like:
range1 = list(range(100))
for i in range1:
print ('i')
Will it be faster than looping through a nested list with the same number of iterables:
range2 = list(range(10))
range3 = list(range(10))
for i in range2:
for ii in range3:
print ('i')
I'm guessing it will be the same, but I'm not sure if iterable number (correct word?) is the only determinant of loop performance. Thought I would check with the coding gods!
Cheers,
Tim
Yes, it is the same thing because of something called "Time Complexity". This is how much the time scales with the given input. It's hard to explain in just a post like this, but it means that you're looping through 100 elements no matter what and it won't change the duration.
I recommend this video where it is explained perfectly: https://www.youtube.com/watch?v=D6xkbGLQesk

Find the closest distance between every galaxy in the data and create pairs based on closest distance between them

My task is to pair up galaxies that are closest together from a large list of galaxies. I have the RA, DEC and Z of each, and a formula to work out the distance between each one from the data given. However, I can't work out an efficient method of iterating over the whole list to find the distance between EACH galaxy and EVERY other galaxy in the list, with the intention of then matching each galaxy with its nearest neighbour.
The data has been imported in the following way:
hdulist = fits.open("documents/RADECMASSmatch.fits")
CATAID = data['CATAID_1']
Xpos_DEIMOS_1 = data['Xpos_DEIMOS_1']
z = data['Z_1']
RA = data['RA']
DEC = data['DEC']
I have tried something like:
radiff = []
for i in range(0,n):
for j in range(i+1,n):
radiff.append(abs(RA[i]-RA[j]))
to initially work out difference in RA and DEC between every galaxy, which does actually work but I feel like there must be a better way.
A friend suggested something along the lines of:
galaxy_coords = (data['RA'],data['DEC'],data['Z])
separation_matrix = np.zeros((len(galaxy_coords),len(galaxy_coords))
done = []
for i, coords1 in enumerate(galaxy_coords):
for j, coords2 in enumerate(galaxy_coords):
if (j,i) in done:
separation_matrix[i,j] += separation matrix[j,i]
continue
separation = your_formula(coords1, coords2)
separation_matrix[i,j] += separation
done.append((i,j))
But I don't really understand this so can't readily apply it. I've tried but it yields nothing useful.
Any help with this would be much appreciated, thanks
Your friend's code seems to be generating a 2D array of the distances between each pair, and taking advantage of the symmetry (distance(x,y) = distance(y,x)). It would be slightly better if it used itertools to generate combinations, and assigned your_formula(coords1, coords2) to separation_matrix[i,j] and separation_matrix[j,i] within the same iteration, rather than having separate iterations for both i,j and j,i.
Even better would probably be this package that uses a tree-based algorithm: https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.spatial.KDTree.html . It seems to be focused on rectilinear coordinates, but that should be addressable in linear time.

Python 3.x Homework help. Sequential number guessing game.

We are supposed to make a number guessing game where depending on what difficulty the player chooses the game generates 4 or 5 numbers and the player is given all but the last, which they have to guess in 3 tries. The numbers have to be equal distances apart, and the numbers have to be within the 1 - 100 range.
So far I know what it will look like roughly.
def guesses:
function for accumulating tries as long as guesses_taken < 3
let user retry, or congratulate and offer to replay
def game_easy:
code for number generation, step value, etc
guesses()
def game_hard:
same code as easy mode, with the appropriate changes
guesses()
For the random numbers, all I have so far is this
guess_init = rand.int (1,100)
step = rand.int (1,20)
guess_init = guess_init + step
and just having it loop and add the step 4 or 5 times respectively.
Where I'm stuck is 1. How to ensure that none of the numbers generated exceed 100 (so it can't be a step of 1 starting at 98), and 2. how to print all but the last number generated.
What I was thinking was assigning the last number generated to a variable that the player input must match. But I was also thinking that if "guess_init" has ran through the loop, then it will already be holding the value of the last number and all Ill have to check is that user input == guess_init.
In your Case you should read the random section from the Python Standard Library. Especially this is relevant:
random.randrange(start, stop[, step])
Return a randomly selected element from range(start, stop, step). This is equivalent to choice(range(start, stop, step)), but doesn’t actually build a range object.

How to make sure strings would not overlap each other in java processing?

I'm having a problem that I need to make the words I took from an external file "NOT" overlap each other. I have over 50 words that have random text sizes and places when you run it but they overlap.
How can I make them "NOT" overlap each other? the result would probably look like a word cloud.
if you think my codes would help here they are
String [] words;
int index = 0;
void setup ()
{
size (500,500);
background (255);
String [] lines = loadStrings ("alice_just_text.txt");
String entireplay = join(lines, " "); //splits it by line
words = splitTokens (entireplay, ",.?!:-;:()03 "); //splits it by word
for (int i = 0; i < 50; i++) {
float x = random(width);
float y = random(height);
int index = int(random(words.length));
textSize (random(60)); //random font size
fill (0);
textAlign (CENTER);
text (words[index], x, y, width/2, height/2);
println(words[index]);
index++ ;
}
}
Stack Overflow isn't really designed for general "how do I do this" type questions. You'll have much better luck if you post a more specific "I tried X, expected Y, but got Z instead" type question. But I'll try to help in a general sense:
You need to break your problem down into smaller pieces and then take on those pieces one at a time.
For example, you can isolate your problem to making sure rectangles don't overlap, which you can break down even further. There are a number of ways to do that:
You could use a grid to lay out your rectangles. Figure out how many squares a line of text takes up, then find a place in your grid where that word will fit. You could use something like a 2D array of boolean values, for example.
Or you could generate a random location, and then check whether there's already a rectangle there. If so, pick a new random location until you find a clear spot.
In any case, you'll probably need to use collision detection (either point-rectangle or rectangle-rectangle) to determine whether your rectangles are overlapping.
Start small. Create a small example program that just shows two rectangles on the screen. Hardcode their positions at first, but make it so they turn red if they're colliding. Work your way up from there. Make it so you can add rectangles using the mouse, but only let the user add them if there is no overlap. Then add the random location choosing. If you get stuck on a specific step, then post a MCVE and we'll go from there. Good luck.

Creating a continuous tone in MATLAB whose frequency varies in real-time depending on user input

I am currently working on a graphing program in MATLAB that takes input and maps a point to x-y space using this input. However, the program should also output a continuous tone whose frequency varies depending on the location of the point.
I was able to get the tone generation done, however could not get the tone to work continuously due to the nature of the program. (Code in between tone generations) I thought I could solve this using a parfor loop with the code that alters the frequency in one iteration of the loop, and the code that generates the tone in another but cannot seem to get it due to the following error:
Warning: The temporary variable frequency will be cleared at the
beginning of each iteration of the parfor loop. Any value assigned to
it before the loop will be lost. If frequency is used before it is
assigned in the parfor loop, a runtime error will occur. See Parallel
for Loops in MATLAB, "Temporary Variables".
In multiThreadingtest at 5 Error using multiThreadingtest (line 5) Reference to a cleared variable frequency.
Caused by:
Reference to a cleared variable
frequency.
And my code:
global frequency
frequency = 100;
parfor ii=1:2
if ii==1
Fs = 1000;
nSeconds = 5;
y = 100*sin(linspace(0, nSeconds*frequency*2*pi, round(nSeconds*Fs)));
sound(y, Fs);
elseif ii==2
frequency = 100
pause(2);
frequency = 200
pause(2);
frequency = 300
pause(2);
end
end
The solution may not come from multithreading, but from the use of another function to output a tone(audioplayer, play, stop). 'audioplayer/play' has the ability to output sounds that overlap in time. So basically, a pseudo code would be:
get the value of the input
generate/play a corresponding 5 second tone
detect if any change in the input
if no change & elapsed time close to 5 seconds
generate/play an identical 5 second tone
if change
generate a new 5 second tone
%no overlapping
stop old
play new
%overlapping (few milliseconds)
play new
stop old
The matlab code showing the 'sound'/'play' differences.
Fs = 1000;
nSeconds = 5;
frequency = 100;
y1 = 100*sin(linspace(0, nSeconds*frequency*2*pi, round(nSeconds*Fs)));
aud1 = audioplayer(y1, Fs);
frequency = 200;
y2 = 100*sin(linspace(0, nSeconds*frequency*2*pi, round(nSeconds*Fs)));
aud2 = audioplayer(y2, Fs);
% overlapping sound impossible
sound(y1, Fs);
pause(1)
sound(y2, Fs);
% overlapping sound possible
play(aud1);
pause(1);
disp('can compute here');
play(aud2);
pause(1);
stop(aud1);
pause(1);
stop(aud2);

Resources