Closed jeffkit closed 10 years ago
I think the way you are getting the buffer and numFrames and numChannels is correct. The problem is that the SoundLevelMeter code works with something like a moving average, and it seems you are re-allocating a new LevelMeter every render. You can see what I'm talking about at this line: NVSoundLevelMeter.m#L31. A few lines further you can also see that the first time you run it, it will start with -50dB.
So if it's possible in your design, alloc/init the SoundLevelMeter once and reuse it again and again on the buffers as you are processing them. The first time you run it the dBLevel will be -50dB but running it again will allow it to 'come up' from -50 dB.
The reason why I implemented it this way is because if your buffers are really small this will provide a more sensible (slower) dB signal. It's not the only solution but it worked for my applications. After a few buffers (less than a second in most of my cases) it's at a reasonable level and also changes quickly enough with changes in sound level. It's also a performance increase to allocate once and re-use the same thing again.
Please let me know if this works for you!
Thank you for reply! I followed you advise, alloc/init the soundLevelMeter only once。but it still not work for me, I got another db value '-inf'. Here is the log: 2014-02-24 10:51:02.889 Demo[46318:9107] db value -50.00 2014-02-24 10:51:02.897 Demo[46318:9107] db value -inf 2014-02-24 10:51:02.908 Demo[46318:9107] db value -50.00 2014-02-24 10:51:02.920 Demo[46318:9107] db value -inf 2014-02-24 10:51:02.932 Demo[46318:9107] db value -50.00 2014-02-24 10:51:02.943 Demo[46318:9107] db value -inf 2014-02-24 10:51:02.955 Demo[46318:9107] db value -50.00 2014-02-24 10:51:02.966 Demo[46318:9107] db value -inf .........
Hmm, that's weird. By the way, I got this dB measuring code by looking at a piece of example code of the library of Novocaine: master/ViewController.m#L85
Try to change the getdBLevel
method back to the code below (copied from the example above) You will also have to add the dbVal variable to the header file, and initialise it as 0.0 (dbVal is a block variable in the Novocaine example).
- (float) getdBLevel:(float *)data numFrames:(UInt32)numFrames numChannels:(UInt32)numChannels {
vDSP_vsq(data, 1, data, 1, numFrames*numChannels);
float meanVal = 0.0;
vDSP_meanv(data, 1, &meanVal, numFrames*numChannels);
float one = 1.0;
vDSP_vdbcon(&meanVal, 1, &one, &meanVal, 1, 1, 0);
dbVal = dbVal + 0.2*(meanVal - dbVal);
printf("Decibel level: %f\n", dbVal);
}
Note that I later added code to make a copy of the data variable, because this measurement of dB will also alter the contents of data, I think it muted it, but I'm not sure. Maybe this fresh code will give you good db values!
sadly .. the dbVal is always 'nan'.
Have you tried printing meanVal?
Did things work out? I think you could also check the way the buffer is formatted vs how the buffer of the Novocaine library is formatted.
I wrote a recorder in remote IO Unit.I want to calculate the sound level of the samples in the render callback. I found NVDSP project have an util method to getDBLevel:
So, I try to pass the AudioBuffer as parameters of this method:
but this is not work as expect, it always return -50db.
Any idea?