Sound Recording question

Post Reply
josefn
Posts: 5
Joined: Tue Apr 14, 2009 11:33 pm
Location: Irvine, CA

Sound Recording question

Post by josefn » Wed Apr 15, 2009 6:24 am

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.

eKid
Posts: 65
Joined: Sat Dec 06, 2008 6:07 pm
Contact:

Re: Sound Recording question

Post by eKid » Wed Apr 15, 2009 2:05 pm

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

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;
}
You can paste this in an arm9 template to compile it.

josefn
Posts: 5
Joined: Tue Apr 14, 2009 11:33 pm
Location: Irvine, CA

Re: Sound Recording question

Post by josefn » Wed Apr 15, 2009 9:31 pm

Thank you so much!

meikewaldmann
Posts: 1
Joined: Wed May 13, 2009 2:14 pm

Re: Sound Recording question

Post by meikewaldmann » Wed May 13, 2009 2:34 pm

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.

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 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.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 3 guests