Reverse reading of audio files (from flash memory chip)

Status
Not open for further replies.

Sandro

Well-known member
Hi all, I'm trying to read in "reverse" direction an audio .RAW file from flash memory chip; I quote olly the relevant part of my code.

First, inside play(filename) function I set rawfile.seek to the last byte of the .RAW file:
Code:
bool Audio_expander_serialflash_raw::play(const char *filename)
{
....
rawfile = SerialFlash.open(filename);
file_size = rawfile.size();
file_offset = file_size-1;
rawfile.seek(file_offset);
....
}

Than, each time update() is called, I read a bunch of 128 samples (beginning from the end), reverse them (last sample in --> first sample out), and send to the next stage:
Code:
void Audio_expander_serialflash_raw::update(void)
{
unsigned int i;
audio_block_t *block;
int16_t r_samples_vector[128]; 

rawfile.read(r_samples_vector, 128<<1);
for (i=0; i<128; i++)
     {
      block->data[i]=r_samples_vector[127-i];
     }
transmit(block);
file_offset -= (128<<1);
rawfile.seek(file_offset);
}

Anyone can please help me to find what's wrong with this code? I apologize becasue I didn't include a check for the end of .RAW file, but problems comes soon at the beginnig of reading 8far from the end of file)
Thank you!
 
I think this:
Code:
file_offset = file_size-1;
should be this:
Code:
file_offset = file_size-256;
so that the seek positions the file at the beginning of the last block of data.

Pete
 
I think this:
Code:
file_offset = file_size-1;
should be this:
Code:
file_offset = file_size-256;
so that the seek positions the file at the beginning of the last block of data.

Pete

Hi Pete, thank you, what you point out is a huge mistake I did. But maybe this is only the tip of the iceberg... nothing good comes out but a lots of noise... :confused:
 
I can't see anything else wrong with the code. Can you post your whole sketch?

Pete

Hi Pete, in the meanwhile I found (I belive) another bad mistake I did:

wrong line:
Code:
file_offset -= (128<<1);

should be (I belive):
Code:
file_offset -= (128<<2);

I'll test the code, than I'll write an update.
Thank you!
Sandro
 
This is the code, a modified version of the original AudioPlaySerialflashRaw:
Code:
#include <Arduino.h>
#include "play_serialflash_raw.h"
#include "spi_interrupt.h"


void AudioPlaySerialflashRaw::begin(void)
{
	playing = false;
	file_offset = 0;
	file_size = 0;
}


bool AudioPlaySerialflashRaw::play(const char *filename)
{
	stop();
	AudioStartUsingSPI();
	rawfile = SerialFlash.open(filename);
	if (!rawfile)
        {
		AudioStopUsingSPI();
		return false;
	}
	file_size = rawfile.size();
	file_offset = file_size - 256;
	rawfile.seek(file_offset);
	playing = true;
	return true;
}

void AudioPlaySerialflashRaw::stop(void)
{
	__disable_irq();
	if (playing)
       {
		playing = false;
		__enable_irq();
		rawfile.close();
		AudioStopUsingSPI();
	}
	else
	{
		__enable_irq();
	}
}


void AudioPlaySerialflashRaw::update(void)
{
	unsigned int i, n;
	audio_block_t *block;
        int16_t r_samples_vector[128];

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

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

	if (rawfile.available())
        {
                 rawfile.read(r_samples_vector, 256);
                 for (i=0; i<128; i++)
                 {
                      block->data[i]=r_samples_vector[127-i];
                 }
                transmit(block);
                file_offset -= (512);
                rawfile.seek(file_offset);
	}
	 
        else
        {
		rawfile.close();
		AudioStopUsingSPI();
		playing = false;
	}
	release(block);
}


Nothig good comes out... A bad square wave from a sinus wave... Maybe each couple of byte in a sample must be inverted??
Thank you!
 
You've got more work/thinking to do. The RAW audio file is probably not a multiple of 256 bytes (AUDIO_SAMPLE_SIZE is 128 16-bit words), so you need to "seek" to that last possibly short block (256-byte blocks), and then leading pad with zeros before copying in the last 16-bit words in reverse order . (You'll note in the original play_sd_raw.cpp, if the last block read is < 256 bytes. it is padded with zeros at the end.)

You'll need to add logic to detect when you have seek'd your way to the beginning of the file so you can stop playing (rawfile.close() etc.)

i think file_offset -= (512); should be file_offset -= 256;


... there are probably more errors
 
Last edited:
Hi Manitou,
wow!! it works!!! :D I wrote this drastic but simple operation:

Code:
bool AudioPlaySerialflashRaw::play(const char *filename)
.....
.....
	file_size = rawfile.size() - (rawfile.size()%256);
	file_offset = file_size - 256;
        rawfile.seek(file_offset);
.....
.....
}

But now, can you kindly explain me: supposing that we read (in the first reading) a bunch (<128) of invalid samples, why this completely compromise the process?
Thank you a lot!!
Sandro



PS: about this comment:
i think file_offset -= (512); should be file_offset -= 256;
I got it... I had (very) badly used rawfile.seek(..)
 
Last edited:
Status
Not open for further replies.
Back
Top