Go Down

Topic: What all these instuctions do ? (Read 170 times) previous topic - next topic

naidu003

Hi , I am doing project on voice recording  i have the module and got the code also

but i can't understand few instructions in this code

1.byte2 = (fileSize >> 8) & 0xff ?

2. if (recByteCount % totalBuf > bufSplit_1 && lastBuf == 7) ?

3. OCR2A = valOCR2A;  ?

4.  cbi(ADCSRA,ADPS2); ,  sbi(ADCSRA,ADPS1);,  sbi(ADCSRA,ADPS0);  ?

5.  ISR(TIMER2_COMPA_vect)  ?

6.   for (int dloop = 0; dloop < 4; dloop++)  ?

7. sbi (TIMSK2, OCIE2A);  ?

Code: [Select]
#include <SdFat.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

SdFat sd;
SdFile rec;

const unsigned int darBufSize = 128;
const unsigned int totalBuf = darBufSize * 8;
const unsigned int bufSplit_1 = darBufSize;
const unsigned int bufSplit_2 = darBufSize * 2;
const unsigned int bufSplit_3 = darBufSize * 3;
const unsigned int bufSplit_4 = darBufSize * 4;
const unsigned int bufSplit_5 = darBufSize * 5;
const unsigned int bufSplit_6 = darBufSize * 6;
const unsigned int bufSplit_7 = darBufSize * 7;

const int chipSelect = 4;
unsigned long fileSize = 0L;
unsigned long waveChunk = 16;
unsigned int waveType = 1;
unsigned int numChannels = 1;

//------------ SET SAMPLE RATE HERE --------------------
unsigned long sampleRate = 48000;
//------------ SET SAMPLE RATE HERE --------------------

unsigned long bytesPerSec = sampleRate;
unsigned int blockAlign = 1;
unsigned int bitsPerSample = 8;
unsigned long dataSize = 0L;
unsigned long recByteCount = 0L;
unsigned long recByteSaved = 0L;
const int btnStart = 6;
const int btnStop = 5;
const int ledStart = 2;
const int ledStop = 3;
int recPressed = 0;
int stopPressed = 0;
unsigned long oldTime = 0L;
unsigned long newTime = 0L;
byte buf00[darBufSize]; // buffer array 1
byte buf01[darBufSize]; // buffer array 2
byte buf02[darBufSize]; // buffer array 3
byte buf03[darBufSize]; // buffer array 4
byte buf04[darBufSize]; // buffer array 4
byte buf05[darBufSize]; // buffer array 4
byte buf06[darBufSize]; // buffer array 4
byte buf07[darBufSize]; // buffer array 4
byte byte1, byte2, byte3, byte4;
unsigned int bufByteCount;
byte bufWrite;
byte lastBuf = 7;
byte valOCR2A = 16000000/(8*sampleRate);

void setup() { // THIS RUNS ONCE

  Setup_timer2();
  Setup_ADC();
  pinMode(10, OUTPUT);
  pinMode(ledStart, OUTPUT);
  pinMode(ledStop, OUTPUT);
  pinMode(btnStop, INPUT_PULLUP);
  pinMode(btnStart, INPUT_PULLUP);
 
  if (sd.begin(chipSelect, SPI_FULL_SPEED)) { // initialise card on SPI to 8MHz SPI bus speed
    for (int dloop = 0; dloop < 4; dloop++) {
      digitalWrite(ledStart,!digitalRead(ledStart));
      delay(100);
    }
  } else { // if error, flash LED twice per second, until reset
    while(1) {
      digitalWrite(ledStart,!digitalRead(ledStart));
      digitalWrite(ledStop,!digitalRead(ledStop));
      delay(500);
    }
  }

}

void loop() { // THIS RUNS LOTS!

  if (digitalRead(btnStart) == LOW && recPressed == 0) {
    StartRec(); // launch StartRec method
  }
  if (digitalRead(btnStop) == LOW && recPressed == 1) {
    StopRec(); // launch StopRec method
  }
 
  if (recPressed == 1) {
    if (recByteCount % totalBuf > bufSplit_1 && lastBuf == 7) {
      rec.write(buf00,darBufSize); lastBuf = 0; recByteSaved += darBufSize;
    } else if (recByteCount % totalBuf > bufSplit_2 && lastBuf == 0) {
      rec.write(buf01,darBufSize); lastBuf = 1; recByteSaved += darBufSize;
    } else if (recByteCount % totalBuf > bufSplit_3 && lastBuf == 1) {
      rec.write(buf02,darBufSize); lastBuf = 2; recByteSaved += darBufSize;
    } else if (recByteCount % totalBuf > bufSplit_4 && lastBuf == 2) {
      rec.write(buf03,darBufSize); lastBuf = 3; recByteSaved += darBufSize;
    } else if (recByteCount % totalBuf > bufSplit_5 && lastBuf == 3) {
      rec.write(buf04,darBufSize); lastBuf = 4; recByteSaved += darBufSize;
    } else if (recByteCount % totalBuf > bufSplit_6 && lastBuf == 4) {
      rec.write(buf05,darBufSize); lastBuf = 5; recByteSaved += darBufSize;
    } else if (recByteCount % totalBuf > bufSplit_7 && lastBuf == 5) {
      rec.write(buf06,darBufSize); lastBuf = 6; recByteSaved += darBufSize;
    } else if (recByteCount % totalBuf < bufSplit_1 && lastBuf == 6) {
      rec.write(buf07,darBufSize); lastBuf = 7; recByteSaved += darBufSize;
    }
  } 
}

void StartRec() { // begin recording process

  digitalWrite(ledStart,HIGH);
  digitalWrite(ledStop,LOW);
  recByteCount = 0;
  bufByteCount = 0;
  recByteSaved = 0;
  bufWrite = 0;
  recPressed = 1; // recording button has been pressed
  stopPressed = 0;
  writeWavHeader();
  sbi (TIMSK2, OCIE2A); // enable timer interrupt, start grabbing audio

}

void StopRec() { // stop recording process, update WAV header, close file
   
  cbi (TIMSK2, OCIE2A); // disable timer interrupt
  writeOutHeader();
  digitalWrite(ledStart,LOW); // turn off recording LED
  digitalWrite(ledStop,HIGH); // light stop LED
  recPressed = 0;
 
}
 
void writeOutHeader() { // update WAV header with final filesize/datasize

  rec.seekSet(4);
  byte1 = recByteSaved & 0xff;
  byte2 = (recByteSaved >> 8) & 0xff;
  byte3 = (recByteSaved >> 16) & 0xff;
  byte4 = (recByteSaved >> 24) & 0xff; 
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.seekSet(40);
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.close();
 
}

void writeWavHeader() { // write out original WAV header to file

  recByteSaved = 0;
  rec.open("rec00000.wav", O_CREAT | O_TRUNC | O_RDWR);
  rec.write("RIFF");
  byte1 = fileSize & 0xff;
  byte2 = (fileSize >> 8) & 0xff;
  byte3 = (fileSize >> 16) & 0xff;
  byte4 = (fileSize >> 24) & 0xff; 
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  rec.write("WAVE");
  rec.write("fmt ");
  byte1 = waveChunk & 0xff;
  byte2 = (waveChunk >> 8) & 0xff;
  byte3 = (waveChunk >> 16) & 0xff;
  byte4 = (waveChunk >> 24) & 0xff; 
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = waveType & 0xff;
  byte2 = (waveType >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  byte1 = numChannels & 0xff;
  byte2 = (numChannels >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  byte1 = sampleRate & 0xff;
  byte2 = (sampleRate >> 8) & 0xff;
  byte3 = (sampleRate >> 16) & 0xff;
  byte4 = (sampleRate >> 24) & 0xff; 
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = bytesPerSec & 0xff;
  byte2 = (bytesPerSec >> 8) & 0xff;
  byte3 = (bytesPerSec >> 16) & 0xff;
  byte4 = (bytesPerSec >> 24) & 0xff; 
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);
  byte1 = blockAlign & 0xff;
  byte2 = (blockAlign >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  byte1 = bitsPerSample & 0xff;
  byte2 = (bitsPerSample >> 8) & 0xff;
  rec.write(byte1);  rec.write(byte2);
  rec.write("data");
  byte1 = dataSize & 0xff;
  byte2 = (dataSize >> 8) & 0xff;
  byte3 = (dataSize >> 16) & 0xff;
  byte4 = (dataSize >> 24) & 0xff; 
  rec.write(byte1);  rec.write(byte2);  rec.write(byte3);  rec.write(byte4);

}

void Setup_timer2() {

  TCCR2B = _BV(CS21);  // Timer2 Clock Prescaler to : 8
  TCCR2A = _BV(WGM21); // Interupt frequency  = 16MHz / (8 x 62 + 1) ~= 32000Hz
  OCR2A = valOCR2A; // Compare Match register set to 62

}

void Setup_ADC() {

  ADMUX = 0x65; // set ADC to read pin A5, ADLAR to 1 (left adjust)
  cbi(ADCSRA,ADPS2); // set prescaler to 3 / ADC clock = 4MHz
  sbi(ADCSRA,ADPS1);
  sbi(ADCSRA,ADPS0);

}

ISR(TIMER2_COMPA_vect) {

  sbi(ADCSRA, ADSC); // start ADC sample
  while(bit_is_set(ADCSRA, ADSC));  // wait until ADSC bit goes low = new sample ready
  recByteCount++; // increment sample counter

  if (recByteCount % totalBuf < bufSplit_1) {
    buf00[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_2) {
    buf01[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_3) {
    buf02[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_4) {
    buf03[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_5) {
    buf04[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_6) {
    buf05[recByteCount % darBufSize] = ADCH;
  } else if (recByteCount % totalBuf < bufSplit_7) {
    buf06[recByteCount % darBufSize] = ADCH;
  } else {
    buf07[recByteCount % darBufSize] = ADCH;
  }

}

sterretje

For 3, 4 and 7, see the datasheet of the microcontroller. Search that datasheet for e.g. cbi, OCR2A etc.

1)
I assume that the smiley equals '8' followed by ')'. This divides filesize by 256 and stores the result in byte2
2)
'%' is C/C++ the modulo operator
5)
This defines an interrupt service routine for the situation where Timer2 compare register generates an input (see datasheet)
6)
a simple loop that executes 4 times

Asking 2 and 6 might show that you're not quite ready yet to dive into the deep; no offense intended.

PaulMurrayCbr

This is the one that worries me:
Code: [Select]
for (int dloop = 0; dloop < 4; dloop++)
If the the OP cannot understand that, then the OP cannot code C at all.

naidu003 - you need to learn C/C++. Visit www.cprogramming.com.
WP personal, WP work-related, twitter

naidu003

that smile was a mistake , its 8 only
thank you

UKHeliBob

Quote
that smile was a mistake , its 8 only
That smiley was there because you didn't put the code in code tags.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

DrAzzy

Wrote is all out last night and forgot to click post. Might as well do it now though.

1. Shift filesize right 8 bits, and bitwise and (&) with 0xFF (ie, this gets the high byte of a 16-bit value, or the second byte of a larger value), and set byte2 to that value. The bitwise and is unnecessary if byte2 is a byte, since it would be done implicitly when converting to a byte anyway.

2. What are you confused about here? % is modulo, and && is logical and. Simple test.

3. Set the OCR2A register to that value. That register is one of several that controls timer2. See the atmega328p datasheet for more than you want to know about what that register does.

4. cbi() and sbi() are "clear bit index" and "set bit index". First argument is a register, second argument is the name for one of the bits in that register - it's a shortcut to set or unset that bit in the register. Again, see datasheet for description of what those registers do. ADCSRA is the ADC control and status register; i think those bits control the ADC clock prescaler.

5. This defines an interrupt servicing routine, called when an interrupt fires - in this case TIMER2_COMPA_vect, which fires when timer2 reaches the specified output compare value (I think the details of when this is called depend on the mode that timer2 is in? Datasheet has answers)

6. Again, see 4. In this case, I happen to know what that does - TIMSK2 is timer interrupt mask for timer2 - that's how interrupts are disabled and enabled. OCIE2A enables the TIMER2_COMPA interrupt (hey, that sounds familiar!)


On a larger scale, from a first glance, it sounds like it's recording audio by using the hardware timer to grab analog samples at a regular rate by taking the data in an ISR driven by timer2, and they directly write registers to configure the ADC and timer to set them up appropriately.

The busy-wait loop in the ISR is not a design pattern to emulate, by the way - you generally want ISRs to run fast.
ATtiny core for 841+1634+828 and x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny 841/1634/828/88/861/167 breakouts, mosfets, touch sensors and prototyping board in my store http://tindie.com/stores/DrAzzy

naidu003

Quote
Wrote is all out last night and forgot to click post. Might as well do it now though.
Thank you DrAzzy , that you did again

I got to know , reading the controller data sheet thoroughly is nice

I have used MAX9814 AGC microphone amplifier board for recording voices 


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy