Hello,
I was wondering if it was possible to (relatively) easily determine the volume of sound as it is being recorded by the NDS microphone.
Thanks.
Sound Recording question
Re: Sound Recording question
Hello josefn,
Here are some codes!
What I did is got the RMS (root mean square) of the sample data when I receive it from the mic (in the callback).
Result is 0..32768, I made a little bar to show the result!!
oh an i threw in a peak test too
You can paste this in an arm9 template to compile it.
Here are some codes!
What I did is got the RMS (root mean square) of the sample data when I receive it from the mic (in the callback).
Result is 0..32768, I made a little bar to show the result!!
oh an i threw in a peak test too
Code: Select all
// mic input amplitude
#include <nds.h>
#include <stdio.h>
#include <nds/registers_alt.h>
#define __TEST_RMS
#define __TEST_PEAK
//the record sample rate
#define sample_rate 8000
//buffer which is written to by the arm7
u16* mic_buffer = 0;
//the mic buffer sent to the arm7 is a double buffer
//every time it is half full the arm7 signals us so we can read the
//data. I want the buffer to swap about once per frame so i chose a
//buffer size large enough to hold two frames of 16bit mic data
u32 mic_buffer_size = sample_rate * 2 / 30;
//mic stream handler
void micHandler(void* data, int length)
{
DC_InvalidateRange(data, length);
s16 *ptr;
int i;
#ifdef __TEST_RMS
// get rms (root mean square) of data
u32 sum = 0;
ptr = data;
for( i = 0; i < length/2; i++ ) {
sum += ((*ptr) * (*ptr)) >> 16;
ptr++;
}
sum /= length;
u32 rms = sqrt32(sum) << 8;
//---------------------------------------
// rms RESULT: 0..32768
//---------------------------------------
REG_WIN0H_SUB = (rms * 255) / 32768; // <----------------------
#endif
#ifdef __TEST_PEAK
// get peak of data
u32 peak = 0;
ptr = data;
for( i = 0; i < length/2; i++ ) {
u32 test = (*ptr) * (*ptr);
if( test > peak ) peak = test;
ptr++;
}
peak = sqrt32(peak);
REG_WIN1H_SUB = (peak * 255) / 32768;
#endif
}
int main(void)
{
consoleDemoInit();
iprintf("recording.....\nRMS\n\nPEAK");
BG_PALETTE_SUB[0] = 0;
BG_PALETTE_SUB[1]= RGB8(255,128,0);
int i;
for( i = 0; i < 16; i++ ) {
BG_GFX_SUB[i] = 0x1111;
}
REG_BG1CNT_SUB = BG_MAP_BASE(1);
videoSetModeSub(
MODE_0_2D |
DISPLAY_BG0_ACTIVE |
DISPLAY_BG1_ACTIVE |
DISPLAY_WIN0_ON |
DISPLAY_WIN1_ON );
REG_WIN0V_SUB = 0x1017;
REG_WIN1V_SUB = 0x2027;
REG_WININ_SUB = 0x202; // bg1 inside window
REG_WINOUT_SUB = 0x3D; // other stuff outside
REG_WIN0H_SUB = 0;
REG_WIN1H_SUB = 0;
mic_buffer = (u16*)malloc(mic_buffer_size);
soundMicRecord(mic_buffer, mic_buffer_size, MicFormat_12Bit, sample_rate, micHandler);
swiIntrWait( 0, 0 );
return 0;
}
Re: Sound Recording question
Thank you so much!
-
- Posts: 1
- Joined: Wed May 13, 2009 2:14 pm
Re: Sound Recording question
Hello eKid,
I see that you are well versed in audio on Nintendo DS.
I tried to programm a scope for my NDS. I will use the microphone input for analog data.
My problem is that the Result is on emulator ok, but it isn't on the real DS. Maybe there is a bad sound in the moment i press the A buttom. I should make it continous but I don't know how.
Here my Code.
Could you say me what is wrong?
Could you give me an hint how I could make it continous, like a real scope?
Best regards
Meike
P.S.: sorry for my bad english.
I see that you are well versed in audio on Nintendo DS.
I tried to programm a scope for my NDS. I will use the microphone input for analog data.
My problem is that the Result is on emulator ok, but it isn't on the real DS. Maybe there is a bad sound in the moment i press the A buttom. I should make it continous but I don't know how.
Here my Code.
Code: Select all
#include <nds.h>
#include <stdio.h>
#include <sound.h>
//the record sample rate
#define sample_rate 8000
//buffer to hold sound data for playback
u16* sound_buffer = 0;
//buffer which is written to by the arm7
u16* mic_buffer = 0;
//the length of the current data
u32 data_length = 0;
//enough hold 5 seconds of 16bit audio
u32 sound_buffer_size = 300; //sample_rate * 2 * 5;
//the mic buffer sent to the arm7 is a double buffer
//every time it is half full the arm7 signals us so we can read the
//data. I want the buffer to swap about once per frame so i chose a
//buffer size large enough to hold two frames of 16bit mic data
u32 mic_buffer_size = sample_rate * 2 / 30;
int coord(int x, int y)
{
int tmp=0;
if ((256*(192-y)+x) < 256*192) //Puffergröße berücksichtigen
tmp = (256*(192-y)+x); //links unten (0/0)
return tmp;
}
//mic stream handler
void micHandler(void* data, int length)
{
if(!sound_buffer || data_length > sound_buffer_size) return;
DC_InvalidateRange(data, length);
dmaCopy(data, ((u8*)sound_buffer) + data_length, length);
data_length += length;
iprintf(".");
}
void record(void)
{
data_length = 0;
soundMicRecord(mic_buffer, mic_buffer_size, MicFormat_12Bit, sample_rate, micHandler);
}
void play(void)
{
soundMicOff();
soundEnable();
iprintf("data length: %i\n", data_length);
soundPlaySample(sound_buffer, SoundFormat_16Bit, data_length, sample_rate, 127, 64, false, 0);
}
void show()
{
soundMicOff();
int i;
for(i = 0; i < 256 * 192; i++) //Bildschirm schwarz
VRAM_A[i] = RGB15(0,0,0);
// Achsen zeichnen
for(i = 0; i < 192; i+=2) // y-Achse
VRAM_A[coord(128,i)] = RGB15(0x00,0xff,0x00);
for(i = 0; i < 256; i+=2) // x-Achse
VRAM_A[coord(i,96)] = RGB15(0xff,0x00,0x00);
for (i=0; i<256; i++) {
iprintf("%i, ", int(sound_buffer[i]/350)); //int(sound_buffer[i]/350)
VRAM_A[coord(i,int(sound_buffer[i]/350)+96)] = RGB15(0xff,0xff,0xff);
}
}
int main(void)
{
int i,j;
int key;
bool recording = false;
sound_buffer = (u16*)malloc(sound_buffer_size);
mic_buffer = (u16*)malloc(mic_buffer_size);
consoleDemoInit();
videoSetMode(MODE_FB0);
vramSetBankA(VRAM_A_LCD);
for(i = 0; i < 256 * 192; i++) //Bildschirm schwarz
VRAM_A[i] = RGB15(0,0,0);
// Achsen zeichnen
for(i = 0; i < 192; i+=2) // y-Achse
VRAM_A[coord(128,i)] = RGB15(0x00,0xff,0x00);
for(i = 0; i < 256; i+=2) // x-Achse
VRAM_A[coord(i,96)] = RGB15(0xff,0x00,0x00);
while(1)
{
scanKeys();
key = keysDown();
if(key & KEY_A)
{
recording ? show() : record();
recording = !recording;
iprintf("%s\n", recording ? "recording" : "showing");
}
swiWaitForVBlank();
}
}
Could you give me an hint how I could make it continous, like a real scope?
Best regards
Meike
P.S.: sorry for my bad english.
Who is online
Users browsing this forum: Ahrefs [Bot] and 3 guests