Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

So here is some weird behavior: When I create a list inside a loop whose elements are Play functions, with arguments that depend on the counter, it is as if the counter is being stored symbolically, so all the list elements - not just the last one - change with each iteration. THis only happens with Play. If I do the same thing with Plot, for example, it works as expected. Here is an example, though I have also tried creating the list using Append and AppendTo, I have assigned the outputs, etc. list1 has every part the same, and all equal to the result with the current value of i. list2 has each part equal to what it was when it was first created (so the first with the results evaluated with i=1, the second with i=2, etc.). Why? How do I fix Play?

list1 = {0, 0, 0};
list2 = list1;
Do[
 list1[[i]] = Play[Cos[150*i*2*Pi*t], {t, 0, 0.5}];
 list2[[i]] = Plot[Cos[i*2*Pi*t], {t, 0, 0.5}];
 Print[list1, list2],
 {i, 3}
 ]
Show[list1]
Show[list2]
list1
list2
share|improve this question
2  
Why do you want to show Sound ? –  Artes Oct 6 '13 at 22:26
add comment

4 Answers

If you were to read the Details and Options section in the documentation for Play, you would find the following statement:

Play has attribute HoldAll, and evaluates $f$ only after assigning specific numerical values to $t$.

That is the "why" you are looking for. The simplest fix is to pass the Cos expression to Evaluate to force the evaluation of i.

list1 = {0, 0, 0};
list2 = list1;
Do[
    list1[[i]] = Play[Evaluate @ Cos[150*i*2*Pi*t], {t, 0, 0.5}];
    list2[[i]] = Plot[Cos[i*2*Pi*t], {t, 0, 0.5}];
    Print[list1, list2],
  {i, 3}]

With this single modification, your code should work the way you were expecting.

share|improve this answer
add comment

Get the i out of the Play[] to get it evaluated:

list1 = {0, 0, 0};
Do[list1[[i]] = Play[#, {t, 0, 0.5}] &@Cos[150 i 2 Pi t], {i, 3}]
Column@list1

Mathematica graphics

share|improve this answer
add comment

Another standard trick is to use With:

list1 = {0, 0, 0};
list2 = list1;
Do[
  list1[[i]] = With[{i = i}, Play[Cos[150*i*2*Pi*t], {t, 0, 0.5}]];
  list2[[i]] = Plot[Cos[i*2*Pi*t], {t, 0, 0.5}],
  {i, 3}];
list1
list2

Mathematica graphics

Mathematica graphics

share|improve this answer
add comment

If what you wish to do is to make a list of sounds for later playing, here is one way:

t = Range[0, 0.5, 1/8000];
listSounds = Table[Cos[150*i*2*Pi*t], {i, 1, 3}];
ListPlay[listSounds[[#]]] & /@ Range[3]
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.