带处理和音频输入的NullPointerException

问题描述:

我正在处理草图,其中我从音频文件获取输入,该音频文件的主要频率映射到三个动画“蛇”的移动。代码工作有时很好,有时不会(NullPointerException)!我想它必须处理一些细节,我错过了/没有得到,但我感到困惑,因为我的代码不会每次都破坏!如果你可以检查并找出问题,我将不胜感激! 这里是主要的草图:带处理和音频输入的NullPointerException

import beads.*; 

// sound variables 
AudioContext ac; 
Gain g; 
PowerSpectrum ps; 
Frequency f; 
String sourceFile; 
SamplePlayer player; 
float inputFrequency; 
float mappedFrequency; 
float prevFrequency; 

// visual variables 
ShapeA shA1; 
ShapeA shA2; 
ShapeA shA3; 
boolean shA1pressed, shA2pressed, shA3pressed; 

void setup() { 
    size(900, 600); 
    frameRate(30); // doesn't affect sound 
    inputFrequency = 0; 
    mappedFrequency = 0; 
    prevFrequency = 0; 

    // get sound source 
    ac = new AudioContext(); 
    sourceFile = sketchPath("") + "data/rite1.mp3"; 
    try { 
    player = new SamplePlayer(ac, new Sample(sourceFile)); 
    } 
    catch(Exception e) 
    { 
    println("Exception while attempting to load sample!"); 
    e.printStackTrace(); 
    exit(); 
    } 
    g = new Gain(ac, 2, 0.3); 
    g.addInput(player); 
    ac.out.addInput(g); 

    /* prerequisites for getting main frequency */ 
    ShortFrameSegmenter sfs = new ShortFrameSegmenter(ac); 
    sfs.addInput(ac.out); 
    FFT fft = new FFT(); 
    sfs.addListener(fft); 
    ps = new PowerSpectrum(); 
    fft.addListener(ps); 
    f = new Frequency(44100.0f); 
    ps.addListener(f); 
    ac.out.addDependent(sfs); 
    /* end of prerequistes */ 

    ac.start(); 

    smooth(); 
    noStroke(); 
    //strokeWeight(2); // affecting the size of a point 
    shA1 = new ShapeA(3); // random factor affecting angle 
    shA2 = new ShapeA(6); 
    shA3 = new ShapeA(8); 
    shA1pressed = false; 
    shA2pressed = false; 
    shA3pressed = false; 
} 

void draw() { 
    //background(255); 
    fill(255,10); 
    rect(0-10,0-10,width+20,height+20); 

    text(" Input Frequency: ", -100, -100); // for some reason, needed!! 
    inputFrequency = f.getFeatures(); // ** THIS IS THE MAIN FREQUENCY ** 
    mappedFrequency = map(inputFrequency,20,2000,0,20); // computational power! 

    if (shA1pressed) { 
    shA1.angle(); 
    shA1.display(shA1.angle); 
    } 
    if (shA2pressed) { 
    shA2.angle(); 
    shA2.display(shA2.angle); 
    } 
    if (shA3pressed) { 
    shA3.angle(); 
    shA3.display(shA3.angle); 
    } 

    prevFrequency = inputFrequency; 
} 

void keyPressed() { 
    if (key == '1') { 
    if (shA1pressed == false) { 
     shA1pressed = true; 
    } else { 
     shA1pressed = false; 
    } 
    } 
    if (key == '2') { 
    if (shA2pressed == false) { 
     shA2pressed = true; 
    } else { 
     shA2pressed = false; 
    } 
    } 
    if (key == '3') { 
    if (shA3pressed == false) { 
     shA3pressed = true; 
    } else { 
     shA3pressed = false; 
    } 
    } 
} 

这里是ShapeA类:

class ShapeA { 
float angleCount = 7; 
float stepSize = 3.3; 
int i = 0; 
float angle = radians(270); 
float r; 

ArrayList<PVector> points = new ArrayList<PVector>(); 

ShapeA(float _r) { 
    // set position of first point 
    points.add(new PVector(random(width), random(height))); 
    r = _r; 
} 

float angle() { 
    if (prevFrequency <= inputFrequency) { 
    angle = angle - radians(mappedFrequency*random(r)); 
    } else { 
    angle = angle + radians(mappedFrequency*random(r)); 
    } 
    return angle; 
} 

void display(float _angle) { 
    PVector point = points.get(i); 
    fill(0); 
    ellipse(point.x, point.y, 3, 3); 

    // add a new point 
    PVector prevPoint = points.get(points.size()-1); 
    float x = prevPoint.x + cos(_angle) * stepSize; 
    float y = prevPoint.y + sin(_angle) * stepSize; 
    points.add(new PVector(x, y)); 

    // check if shape hits display borders 
    float a = (floor(random(-angleCount, angleCount)) + 0.5) * 90.0/angleCount; 
    if (y <= 0) { 
    angle = a+90; 
    } 
    else if (x >= width) { 
    angle = a+180; 
    } 
    else if (y >= height) { 
    angle = a-90; 
    } 
    else if (x <= 0) { 
    angle = a; 
    } 
    i++; 
} 

} 

当我收到一条错误信息,这是一个NullPointerException异常讯息,以突出主这条线(草图):

inputFrequency = f.getFeatures(); // **这是主频率**

另外,我也注意到,通过采取了以下行

文本( “输入频率”,-100,-100 );

我也收到相同类型的消息,虽然该行是没用的!

有人可以解释我,为什么这些“事情”发生?

在此先感谢, - 伊利亚斯

+0

似乎draw()在setup()之前被调用。如果是这种情况,穷人的解决方案是使用布尔变量:如果没有设置,则在setup()和draw()返回时将其设置为true。 –

在未来,你应该尝试后你得到任何错误的全文,以及指向您正在使用的库。

但是我有一个理论:

Frequency类有一个叫做getFeatures()函数返回一个Float

请注意,大写字母F表示Float。这是一个对象,而不是一个原始的小写float这意味着它可以为空

然后,当你将其转换成小写float(通过拆箱),你会得到一个NullPointerException,因为它不知道如何null转换为float

我不知道为什么函数返回null;你必须检查文档并为此进行一些调试。但是,您必须跟踪原因并阻止它,否则您必须添加一个空值检查,只有在该值为非空值时才会输入您的代码。事情是这样的:

Float returnedFrequency = f.getFeatures(); 
if(returnedFrequency != null){ 
    inputFrequency = returnedFrequency; 
    //rest of your code 

至于为什么你需要的text()功能,我的猜测是,它只是一个巧合。我想也许它造成了足够的延迟,在Frequency类中发生任何需要,但延迟应该只有几毫秒,所以我真的怀疑是这样。无论如何,如果您追查空值的原因或添加空检查,它就成为一个争论点。

顺便说一句,你已经在这里发布了一堆额外的代码 - 你的问题与键盘无关,所以所有的代码只是混淆了你的问题。下一次尝试创建一个MCVE - 只需几行即可获得相同的错误,而不是整个草图。祝你好运。

+0

谢谢,凯文!你的理论很有道理!我试过你的代码,现在我没有遇到错误。关于text()函数,它似乎确实是延迟的情况,所以text()补偿了这一点。我将draw()代码设置为在特定的frameCount之后运行,看起来效果很好。我也会考虑你的MCVE评论。谢谢。 –