//Duplicate every other sample to make it seem like its half speed int HalfPlay(data_file file_, int l_, int* clusters_) { int i, j, r = 0; BYTE playBuffer[BUF_SIZE] = {0}; for (i = 0; i < l_ * BPB_SecPerClus; i++) { if (_playing == 0) break; //Buffer current sector (i) from cluster into the playBuffer get_rel_sector(&file_, playBuffer, clusters_, i); for (j = 0; j < BUF_SIZE; j+=2) { //Wait for signal to write for audio, then write to it with prepared bytes while(IORD(AUD_FULL_BASE, 0)){} IOWR(AUDIO_0_BASE, 0 , BytePrep(playBuffer[j], playBuffer[j + 1])); //Logic to play the bytes twice (repeat every 4 bits) if (j % 4 == 0) { if (r == 1){ r = 0; }else{ j -= 4; r = 1; } } } } }
int DelayPlay(data_file file_, int l_, int* clusters_) { int i, j; //Create an additional delay buffer with the size of sample rate BYTE playBuffer[BUF_SIZE] = {0}; UINT16 delayBuffer[SAMPLE_RATE] = {0}; int idxDelay, flag = 0; //Iterate through the audio for (i = 0; i < l_ * BPB_SecPerClus; i++) { if (_playing == 0) break; get_rel_sector(&file_, playBuffer, clusters_, i); for (j = 0; j < BUF_SIZE; j+=2) { //Wait for signal to write for audio, then write to it with prepared bytes while(IORD(AUD_FULL_BASE, 0)){} //Populate delayBuffer using idxDelay with what's in playBuffer on an edge if (flag == 0){ IOWR(AUDIO_0_BASE, 0 , BytePrep(playBuffer[j], playBuffer[j + 1])); flag = 1; }else{ IOWR(AUDIO_0_BASE, 0, delayBuffer[idxDelay]); delayBuffer[idxDelay] = BytePrep(playBuffer[j], playBuffer[j + 1]); flag = 0; } //If we exceed the buffer size, loop around to beginning of array idxDelay++; if (idxDelay > SAMPLE_RATE) idxDelay = idxDelay % SAMPLE_RATE; } } //Finish from current delay index to end of delay array for (i = idxDelay; i < SAMPLE_RATE; i++) { if (_playing == 0) break; while(IORD(AUD_FULL_BASE, 0)){} IOWR(AUDIO_0_BASE, 0, delayBuffer[i]); } //Finish last remaining audio data from beginning to delayIdx for (i = 0; i < idxDelay; i++) { if (_playing == 0) break; while(IORD(AUD_FULL_BASE, 0)){} IOWR(AUDIO_0_BASE, 0, delayBuffer[i]); } }
//Plays the audio backwards by iterating from end of buffer to the beginning int ReversePlay(data_file file_, int l_, int* clusters_) { int i, j; BYTE playBuffer[BUF_SIZE] = {0}; for (i = l_ * BPB_SecPerClus; i > 0; i--) { if (_playing == 0) break; get_rel_sector(&file_, playBuffer, clusters_, i); //Starts from the end and works backwards for (j = 508; j > 0; j-=6) { //Wait for signal to write for audio, then write to it with prepared bytes while(IORD(AUD_FULL_BASE, 0)){} IOWR(AUDIO_0_BASE, 0 , BytePrep(playBuffer[j], playBuffer[j + 1])); //To play the next 2 bits of reverse batch (right side) j+=2; while(IORD(AUD_FULL_BASE, 0)){} IOWR(AUDIO_0_BASE, 0 , BytePrep(playBuffer[j], playBuffer[j + 1])); } } }
void play_normal(data_file* file, BYTE buffer[], int cluster_chain[]){ int isector = 0, ibyte, retval, num_bytes; UINT16 tmp; while (player_state == PLAYER_STATE_PLAYING){ retval = get_rel_sector(file, buffer, cluster_chain, isector++); if (retval != -1){ num_bytes = (retval == 0) ? BPB_BytsPerSec : retval; for (ibyte = 0; (player_state == PLAYER_STATE_PLAYING) && (ibyte < num_bytes); ibyte += 2){ tmp = (buffer[ibyte + 1] << 8) | (buffer[ibyte]); while(IORD(AUD_FULL_BASE, 0)); IOWR(AUDIO_0_BASE, 0, tmp); } } } }
void play_reverse(data_file* file, BYTE buffer[], int cluster_chain[]){ int isector = ceil(file->FileSize/BPB_BytsPerSec) - 1, ibyte, retval, num_bytes; UINT16 tmp; while (player_state == PLAYER_STATE_PLAYING){ retval = get_rel_sector(file, buffer, cluster_chain, isector--); if (retval != -1){ num_bytes = (retval == 0) ? BPB_BytsPerSec : retval; for (ibyte = num_bytes - 1; ibyte >= 1; ibyte -= 2){ tmp = (buffer[ibyte] << 8) | (buffer[ibyte-1]); while(IORD(AUD_FULL_BASE, 0)); IOWR(AUDIO_0_BASE, 0, tmp); } } } }
//Play song in regular speed int NormalPlay(data_file file_, int l_, int* clusters_) { int i, j; BYTE playBuffer[BUF_SIZE] = {0}; for (i = 0; i < l_ * BPB_SecPerClus; i++) { //If play flag is defaulted (user stops music), then stop playing from buffer if (_playing == 0) break; //Buffer current sector (i) from cluster into the playBuffer get_rel_sector(&file_, playBuffer, clusters_, i); for (j = 0; j < BUF_SIZE; j+=2){ //Wait for signal to write for audio, then write to it with prepared bytes while(IORD(AUD_FULL_BASE, 0)){} IOWR(AUDIO_0_BASE, 0 , BytePrep(playBuffer[j], playBuffer[j + 1])); } } }
void play_delay(data_file* file, BYTE buffer[], int cluster_chain[]){ UINT16 tmp, data; int isector = 0, ibyte, ilagbuf = 0, channel = CHANNEL_LEFT, retval, num_bytes; UINT16 lag_buffer[DELAY_SAMPLES] = {0x0000}; while (player_state == PLAYER_STATE_PLAYING){ retval = get_rel_sector(file, buffer, cluster_chain, isector++); if (retval != -1) { num_bytes = (retval == 0) ? BPB_BytsPerSec : retval; for (ibyte = 0; (player_state == PLAYER_STATE_PLAYING) && (ibyte < num_bytes); ibyte += 2){ data = (buffer[ibyte + 1] << 8) | (buffer[ibyte]); if (channel == CHANNEL_LEFT){ tmp = data; } else { if (ilagbuf == DELAY_SAMPLES) ilagbuf = 0; tmp = lag_buffer[ilagbuf]; lag_buffer[ilagbuf++] = data; } while(IORD(AUD_FULL_BASE, 0)); IOWR(AUDIO_0_BASE, 0, tmp); channel ^= 1; } } } int i; for (i = 0; i < DELAY_SAMPLES*2 && player_state == PLAYER_STATE_PLAYING; i++){ if (ilagbuf == DELAY_SAMPLES) ilagbuf = 0; tmp = (channel == CHANNEL_LEFT) ? 0x0000 : lag_buffer[ilagbuf++]; while(IORD(AUD_FULL_BASE, 0)); IOWR(AUDIO_0_BASE, 0, tmp); channel ^=1 ; } }
//Skips every other sample to make it seem like its playing double speed. int DoublePlay(data_file file_, int l_, int* clusters_) { int i, j = 0; BYTE playBuffer[BUF_SIZE] = {0}; for (i = 0; i < l_ * BPB_SecPerClus; i++) { if (_playing == 0) break; //Buffer current sector (i) from cluster into the playBuffer get_rel_sector(&file_, playBuffer, clusters_, i); for (j = 0; j < BUF_SIZE; j+=2) { //Wait for signal to write for audio, then write to it with prepared bytes while(IORD(AUD_FULL_BASE, 0)){} IOWR(AUDIO_0_BASE, 0 , BytePrep(playBuffer[j], playBuffer[j + 1])); //Skip 2 lefts and 2 rights every 2 lefts and 2 rights... get it? HAHAHAHAA if (j % 4 == 0) j += 4; } } }
void play_music(int playType){ /* Play Types * 0 = Normal * 1 = Double * 2 = Half * 3 = Delay * 4 = Reverse */ int sectorSize; secCount = playType == 4 ? (floor( (float) returnData.FileSize/512) - 1) : 0; sectorSize = get_rel_sector(&returnData, buffer, cc, secCount); while(sectorSize != -1){ if(stop_flag) break; if(sectorSize == 0){ if(playType == 0 || playType == 4) write_to_codec(buffer,BPB_BytsPerSec); else if(playType == 1) write_to_codec_double(buffer,BPB_BytsPerSec); else if(playType == 2) write_to_codec_half(buffer,BPB_BytsPerSec); else{ UINT16 tmp; int i; for (i = 0; (i+4) < BPB_BytsPerSec; i+=4){ rightBuffer[delay_cnt] = buffer[i+2]; rightBuffer[delay_cnt+1] = buffer[i+3]; delay_cnt += 2; if ((delay_cnt + 1) >= 88200){ delay_cnt = 0; } tmp = ((buffer[i+1] << 8) | (buffer[i])); while(IORD(AUD_FULL_BASE,0)) {} // Wait until FIFO is ready IOWR(AUDIO_0_BASE, 0 , tmp); tmp = ((rightBuffer[delay_cnt+1] << 8) | (rightBuffer[delay_cnt])); while(IORD(AUD_FULL_BASE,0)) {} // Wait until FIFO is ready IOWR(AUDIO_0_BASE, 0 , tmp); } } } else{ if(playType == 0 || playType == 4) write_to_codec(buffer,sectorSize); else if(playType == 1) write_to_codec_double(buffer,sectorSize); else if(playType == 2) write_to_codec_half(buffer,sectorSize); else{ printf("Playing End of Delay"); write_to_codec_delay(buffer,sectorSize); } } secCount = playType == 4 ? secCount - 1 : secCount + 1 ; sectorSize = get_rel_sector(&returnData, buffer, cc, secCount); } // Reset stop_flag if (stop_flag == 1) stop_flag = 0; else stop_flag = 1; }