Info about AudioPlaySdRaw

Status
Not open for further replies.

Sandro

Well-known member
Hi all, I'd like to understand how does AudioPlaySdRaw works in order to make few mods. I'd be gratefull if somebody had the patience to answer to one couple of questions.

In AudioPlaySdRaw.cpp it seems to me that .update is the funcion which takes a bunch of samples (AUDIO_BLOCK_SAMPLES*2) and send them to the Connector:

Code:
void AudioPlaySdRaw::update(void)
{
	unsigned int i, n;
	audio_block_t *block;

	// only update if we're playing
	if (!playing) return;

	// allocate the audio blocks to transmit
	block = allocate();
	if (block == NULL) return;

	if (rawfile.available()) {
		// we can read more data from the file...
		n = rawfile.read(block->data, AUDIO_BLOCK_SAMPLES*2);
		file_offset += n;
		for (i=n/2; i < AUDIO_BLOCK_SAMPLES; i++) {
			block->data[i] = 0;
		}
		transmit(block);
	} else {
		rawfile.close();
		#if defined(HAS_KINETIS_SDHC)
			if (!(SIM_SCGC3 & SIM_SCGC3_SDHC)) AudioStopUsingSPI();
		#else
			AudioStopUsingSPI();
		#endif
		playing = false;
	}
	release(block);
}

I have two questions:
1) why .update function is not used in arduino sketch?
2) why samples are deleted before being sent?

Code:
for (i=n/2; i < AUDIO_BLOCK_SAMPLES; i++) {
    block->data[i] = 0;
}

Thanks a lot!
 
You'll have to dive deeper in the audio library code to understand that there is always one audio "consumer" object, most times an output object, which acts as the heartbeat for the whole sauce. In a simplified way, on could say that it consumes a block with precise timing, sample by sample, and when it comes to the end, it sends automatically the update request through the audio connection object to its predecessor in the chain to get the next block delivered, and so on. Thus, the update() function is time critical communication between the different objects, and that's why it's not called manually from the sketch.

And for your second question, no samples are deleted. It's a kind of format conversion. The raw data is read in a x2 blown up structure
Code:
n = rawfile.read(block->data, AUDIO_BLOCK_SAMPLES[B]*2[/B]);
and afterwards, the unneeded half is cleaned up
Code:
for (i=n/2; i < AUDIO_BLOCK_SAMPLES; i++) {
    block->data[i] = 0;
}
 
Code:
n = rawfile.read(block->data, AUDIO_BLOCK_SAMPLES*2);
This reads in 128 samples (which is 128*2 = 256 bytes). The returned value 'n' is the number of bytes actually read and can range from 2 up to 256. Normally there will be 256 bytes, in which case the following for loop will be equivalent to for(i=128;i < 128;i++). Since 'i' starts at 128, the test of 'i < 128' will fail immediately and none of the samples will be zeroed - which is what we want because we've just read a full buffer's worth of samples. But if there are less than 256 bytes read, the for loop will zero the remainder of the buffer. For example, if it reads 10 bytes, the for loop will be for(i=5; i < 128;i++) and it will zero samples 5 to 255 in the buffer. This makes sure that there's no garbage left in the buffer which could make a terrible noise (loud clicks for example) when transmitted.

Pete
 
Theremingenieur and el_supremo, thank you for your clear explanations, now I can go a little further in my study!
 
Very basic doubt...

Hi all,
since the last posts, I've completely developed my Lilla midi expander and completely rewritten playFlashraw function. Now, going back to the beginning of my work, I notice that I neglected to use the following lines since (apparently!!) AudioStopUsingSPI() function is called in ANY case:

Code:
#if defined(HAS_KINETIS_SDHC)
	if (!(SIM_SCGC3 & SIM_SCGC3_SDHC)) AudioStopUsingSPI();
#else
	AudioStopUsingSPI();
#endif

Would anyone kindly explain me the meaning of the code above?

Thanks a lot!
 
Status
Not open for further replies.
Back
Top