Dear Sir,
I have finally got the TAS2560 to play sound on 8 khz 16 bit. However the sound is not turning out the way it is suppose to . I have attached two files
1) which plays an audio file which says "Walk sign is on for all crossing"
2) a 1 khz sign wave generated with below function:
uint32_t generate_stereo_tone(uint16_t *buffer, unsigned int sample_rate, double duration, double frequency, bool reset, uint16_t writeBufferSize)
{
unsigned int num_samples = (unsigned int)(sample_rate * duration);
short amplitude = 32767; // 16-bit maximum amplitude
static unsigned int k = 0;
uint16_t maxBufferSize=(writeBufferSize/2)-1;
int addr=0;
uint16_t test=0;
if (reset == true || k>=num_samples)
{
k =1;
}
else{
for (unsigned int i = k; i < num_samples; i++)
{
double time = (double)i / sample_rate;
buffer[2 * (i-k)+1] = (short)(amplitude * sin(2 * M_PI * frequency * time)); // Left channel
buffer[2 * (i - k)] = 0; // Right channel (silence)
if ((i - k) ==maxBufferSize)
{
k = i;
return (num_samples-i);
}
}
}
}
Can you please advise what must be the problem, some times it feels like i am not feed it enough data , but seems hard to believe as I have 4 writeBuffers of 1024bytes each below is my i2x setup code :
void I2S_Setup()
{
// Initialize the I2S driver
I2S_init();
I2S_Params i2sParams;
// Initialize I2S opening parameters
// I2S_Params i2sParams;
I2S_Params_init(&i2sParams);
i2sParams.samplingFrequency = SAMPLE_RATE;
i2sParams.fixedBufferLength = WRITE_BUF_LENGTH * 2;
i2sParams.bitsPerWord = 16;
i2sParams.writeCallback = writeCallbackFxn;
i2sParams.readCallback = readCallbackFxn;
i2sParams.errorCallback = errCallbackFxn;
i2sParams.CCLKDivider = 4;
i2sParams.isDMAUnused = true;
i2sHandle = I2S_open(CONFIG_I2S_0, &i2sParams);
I2S_startClocks(i2sHandle);
}
This is my Play thread :
void *playAudioThread(void *arg0)
{
int k;
I2S_Transaction *lastAchievedTransaction;
bool static firstTime = true;
uint32_t offset;
uint32_t events;
printf("Transaction1 address = 0x%x writeBuf1 address = 0x%x\n", &i2sWrite1, &writeBuf1);
printf("Transaction2 address = 0x%x writeBuf2 address = 0x%x\n", &i2sWrite2, &writeBuf2);
printf("Transaction3 address = 0x%x writeBuf3 address = 0x%x\n", &i2sWrite3, &writeBuf3);
printf("Transaction4 address = 0x%x writeBuf4 address = 0x%x\n\n\n", &i2sWrite4, &writeBuf4);
//initAudioBuffers();
I2S_Setup();
uint32_t bytesRemaining = 0;
while (1)
{
if (playStop == true)
{
if(firstTime == true)
{
initAudioBuffers();
bytesRemaining=preload_Config_AudioBuffers(writeBuf1, writeBuf2, writeBuf3, writeBuf4, playFile, 0, WRITE_BUF_LENGTH);
firstTime = false;
I2S_setWriteQueueHead(i2sHandle, &i2sWrite1);
I2S_startWrite(i2sHandle);
offset=0;
}
if (writeFinished == true)
{
if(transactionFinished != NULL)
{
// Need a critical section to be sure to have corresponding bufPtr and bufSize
uintptr_t key = HwiP_disable();
uint16_t *buf = transactionFinished->bufPtr;
uint16_t bufLength = transactionFinished->bufSize / sizeof(uint16_t);
bytesRemaining = loadAudioChunk(buf, playFile, offset, WRITE_BUF_LENGTH);
offset=offset+WRITE_BUF_LENGTH;
HwiP_restore(key);
List_put(&i2sWriteList, (List_Elem*)transactionFinished);
// audio_console_print_function(console_debug,"Reload Buffer");
}
//
if (bytesRemaining <= 0x100)
{
endTicks = Clock_getTicks();
elapsedTimeTicks = endTicks - startTicks;
Task_sleep(CLOCK_MS(150));
I2S_stopWrite(i2sHandle);
// I2S_stopClocks(i2sHandle);
StopSound();
bytesRemaining = 0;
firstTime = true;
playStop=false;
writeFinished = false;
audio_console_print_function(console_debug,"Sound file Played");
}
writeFinished = false;
//audio_console_print_function(console_debug,"transaction complete %x ,bytes remaining %d, no of completions: %d",transactionFinished, bytesRemaining,transactionFinished->numberOfCompletions);
}
else
{
Task_sleep(CLOCK_MS(5));
}
}
else
{
Task_sleep(CLOCK_MS(100));
I2S_stopWrite(i2sHandle);
}
}
}
write callback
static void writeCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {
// We must remove the previous transaction (the current one is not over)
transactionFinished = (I2S_Transaction*)List_prev(&transactionPtr->queueElement);
// audio_console_print_function(console_debug,"transaction complete prev%x",(I2S_Transaction*)List_prev(&transactionPtr->queueElement));
// audio_console_print_function(console_debug,"transaction complete next%x",(I2S_Transaction*)List_next(&transactionPtr->queueElement));
// audio_console_print_function(console_debug,"transaction complete %x",transactionFinished);
if(transactionFinished != NULL){
// Remove the finished transaction from the write queue
List_remove(&i2sWriteList, (List_Elem*)transactionFinished);
writeFinished=true;
}
if(status>I2S_TRANSACTION_SUCCESS)
{
audio_console_print_function(console_debug,"I2S Error %x", status);
}
if(status==I2S_ALL_TRANSACTIONS_SUCCESS)
{
audio_console_print_function(console_debug,"Buffer UnderRun");
writeFinished=false;
}
}