简体   繁体   中英

Function behaves differently when stepping through to when stepping over

I'm having a problem with my unit testing of a function employing NAudio's PinkNoiseGenerator.

The behaviour of the createPinkNoiseGeneratorLists function seems to be pretty much as expected when stepping through the program - that is to say that the receiverGeneratorList (see below) is populated with lists of PinkNoiseGenerators, each of which contains a list of samples which, crucially, all have different values:

单步执行 单步执行

The problem occurs when stepping over the function. The receiverGeneratorList is still populated with lists of PinkNoiseGenerators, but the samples are identically-valued:

跨步 跨步

The second behaviour is unwanted. I need the pink noise generators to be differently-valued, both in testing and when the program is run. I have narrowed the behaviour down to the following nested for-loop (full code at the bottom):

for (int j = 0; j < receiverList[i].AmplitudeCurveList.Count; j++)
{
    // Calculate duration of pink noise in seconds

    double time = receiverList[i].AmplitudeCurveList[j].Count / (double)sampleRate;

    // Instantiate new generator (list of pink noise samples) at given duration

    PinkNoiseGenerator generator = new PinkNoiseGenerator(time, sampleRate, outputFileName, numberOfChannels);

    // Add generator to generator list which will then be added to the list of lists of pink noise generators,

    generatorList.Add(generator);
}

I can't see anything immediately wrong with the code - could this be a timing issue with NAudio? I've googled round the issue, which seems quite rare but the people who have experienced similar sometimes get responses to do with multithreading - I'm not using any multithreading myself but admittedly there might be some going on 'under the hood' in NAudio.

I have also had a look through the 'similar questions' in the sidebar and they are mostly not similar. This question's top answer alludes to a seeding issue - I thought a similar thing may be to blame for my problem, and understand the concept, but am unsure how to apply it to my specific problem - could my issue be to do with how the pink noise is seeded? I'm really not sure how to debug an error like this.

My system is running:

Windows 7 64-Bit

VS2013 v12.0.21005.1

NET v4.6.01055


Below is the full test/function code if it will help solve the problem:

Here is the (abridged) test class:

[TestMethod]
public void testPinkNoise()
{
    string outputFileName = @"C:\Users\Mick\Test\\Output\Test.wav";
    int numberOfChannels = 1;
    int sampleRate = 1000;

    // Act

    // Problem with identical PinkNoiseGenerators occurs here -> timing issue with NAudio?

    receiverGeneratorList = scene.createPinkNoiseGeneratorLists(sampleRate, outputFileName, numberOfChannels); 
}

And here is the function itself (for the record, I know the variable names are confusing and the function in general is in dire need of refactoring for clarity/readability, what with it's lists of lists of curves and whatnot - haven't gotten round to it yet):

public List<List<PinkNoiseGenerator>> createPinkNoiseGeneratorLists(int sampleRate, string outputFileName, int numberOfChannels)
{
    // Initialise list of lists of pink noise samples

    List<List<PinkNoiseGenerator>> receiverGeneratorList = new List<List<PinkNoiseGenerator>>();

    for (int i = 0; i < receiverList.Count; i++)
    {
        List<PinkNoiseGenerator> generatorList = new List<PinkNoiseGenerator>();

        // For every amplitude curve within the receiver, generate a corresponding pink noise curve

        for (int j = 0; j < receiverList[i].AmplitudeCurveList.Count; j++)
        {
            // Calculate duration of pink noise in seconds

            double time = receiverList[i].AmplitudeCurveList[j].Count / (double)sampleRate;

            // Instantiate new generator (list of pink noise samples) at given duration

            PinkNoiseGenerator generator = new PinkNoiseGenerator(time, sampleRate, outputFileName, numberOfChannels);

            // Add generator to generator list which will then be added to the list of lists of pink noise curves,

            generatorList.Add(generator);
        }

        // Add list of pink noise curves 

        receiverGeneratorList.Add(generatorList);
    }

    return receiverGeneratorList;
}

NAudio generates internally a random number generator, taking the time as seed value. When you step over the function, the two new PinkNoiseGenerator() calls happen so fast that the time hasn't changed and the same seed value was used. To verify this, try to call Thread.Sleep(1000) after the new PinkNoiseGenerator() call and see if it made a difference.

If that's indeed the problem, you can consider two alternatives:

  1. Placing an intentional delay in the code so that subsequent constructor calls of PinkNoiseGenerator happen in different timestamps
  2. Creating just one Generator (one random seed), and read all the buffers from it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM