So I have an ambitious project I want to dive into - Build a Teensy based CDJ - Like the Pioneer CDJ1000.
This project is purely for fun right now.
I have a CDJ1000mk3 jog wheel with the pressure sensor and encoder on the way, and I would like to start to put something together, going from basic to a more advanced implementation.
Basic:
Using a T4.1, load an MP3 or WAV file from the SD card, transform it into a RAW file on the fly (if possible), then using a custom built audio object be able to play it, pitch bend the track and scrub the track - all using just the jog wheel and the pressure sensor.
Advance:
Using a T4.1 or a Devboard v5 (SDRAM, SDCARD, LCD etc)
Would like to add temp/pitch shifting, loop support, display support (display waveform, set cue(s), display cursor etc)
I've seen different custom implementations of scrubbing, pitch shifting, BPM detection and so forth, but from what I can gather, the Audio library as it stands won't be enough to accomplish even the basic requirement.
I've found a project that has most of these feature implemented on an STM32F746 - while I can't use the same code, I would like to try and use is as a basis for the structure of the audio playback and manipulation
Here is the IRQ for the SAI that plays back the audio on that project
GitHub for reference: https://github.com/djgreeb/CDJ-1000mk3_new_life_project
Source Code (ZIP): https://drive.google.com/file/d/1VFx4JItAnkkie4v-_Njo-SxVj8lTepl5/view?usp=sharing
I'd like to start off with being able to load an audio file from the SD card, copy it into PSRAM/SDRAM, then play it back using the Audio board.
But, I would like to do this raw, not using the available functions of the audio library, as I will need to make modifications anyways.
Would appreciate any help/guidance.
This project is purely for fun right now.
I have a CDJ1000mk3 jog wheel with the pressure sensor and encoder on the way, and I would like to start to put something together, going from basic to a more advanced implementation.
Basic:
Using a T4.1, load an MP3 or WAV file from the SD card, transform it into a RAW file on the fly (if possible), then using a custom built audio object be able to play it, pitch bend the track and scrub the track - all using just the jog wheel and the pressure sensor.
Advance:
Using a T4.1 or a Devboard v5 (SDRAM, SDCARD, LCD etc)
Would like to add temp/pitch shifting, loop support, display support (display waveform, set cue(s), display cursor etc)
I've seen different custom implementations of scrubbing, pitch shifting, BPM detection and so forth, but from what I can gather, the Audio library as it stands won't be enough to accomplish even the basic requirement.
I've found a project that has most of these feature implemented on an STM32F746 - while I can't use the same code, I would like to try and use is as a basis for the structure of the audio playback and manipulation
Here is the IRQ for the SAI that plays back the audio on that project
C:
void SAI2_IRQHandler(void) ////////////////////////////////AUDIO PROCESSING 44K1Hz//////////////////////////////
{
//HAL_GPIO_WritePin(GPIOB, LED_TAG_LIST_Pin, GPIO_PIN_SET);
HAL_SAI_IRQHandler(&hsai_BlockA2);
HAL_SAI_Transmit_IT(&hsai_BlockA2, SAMPLE, 2);
if(Tbuffer[19]&0x8 && ((slip_play_adr+((slip_position+pitch_for_slip)/10000))<294*all_long)) //SLIP MODE ENABLE
{
slip_position+= pitch_for_slip;
slip_play_adr+=slip_position/10000;
slip_position = slip_position%10000;
}
position+= pitch;
if(position>9999)
{
step_position = position/10000;
if(reverse==0 && ((play_adr+step_position+3)<=(294*all_long)))
{
play_adr+= step_position;
if(step_position==1)
{
LR[0][0] = LR[0][1];
LR[1][0] = LR[1][1];
LR[0][1] = LR[0][2];
LR[1][1] = LR[1][2];
LR[0][2] = LR[0][3];
LR[1][2] = LR[1][3];
}
else
{
sdram_adr = play_adr&0xFFFFF;
LR[0][0] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][0];
LR[1][0] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][1];
sdram_adr = (play_adr+1)&0xFFFFF;
LR[0][1] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][0];
LR[1][1] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][1];
sdram_adr = (play_adr+2)&0xFFFFF;
LR[0][2] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][0];
LR[1][2] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][1];
}
sdram_adr = (play_adr+3)&0xFFFFF;
LR[0][3] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][0];
LR[1][3] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][1];
}
else if(reverse==1 && play_adr>=step_position)
{
play_adr-= step_position;
if(step_position==1)
{
LR[0][0] = LR[0][1];
LR[1][0] = LR[1][1];
LR[0][1] = LR[0][2];
LR[1][1] = LR[1][2];
LR[0][2] = LR[0][3];
LR[1][2] = LR[1][3];
sdram_adr = (play_adr)&0xFFFFF;
LR[0][3] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][0];
LR[1][3] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][1];
}
else
{
sdram_adr = play_adr&0xFFFFF;
LR[0][3] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][0];
LR[1][3] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][1];
sdram_adr = (play_adr+1)&0xFFFFF;
LR[0][2] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][0];
LR[1][2] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][1];
sdram_adr = (play_adr+2)&0xFFFFF;
LR[0][1] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][0];
LR[1][1] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][1];
sdram_adr = (play_adr+3)&0xFFFFF;
LR[0][0] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][0];
LR[1][0] = PCM[(sdram_adr>>13)+offset_adress][sdram_adr&0x1FFF][1];
}
}
position = position%10000;
}
T = position;
T = T/10000;
T = T - 1/2.0F;
even1 = LR[0][2];
even1 = even1 + LR[0][1];
odd1 = LR[0][2];
odd1 = odd1 - LR[0][1];
even2 = LR[0][3];
even2 = even2 + LR[0][0];
odd2 = LR[0][3];
odd2 = odd2 - LR[0][0];
c0 = (float)even1*COEF[0];
r0 = (float)even2*COEF[1];
c0 = c0 + r0;
c1 = (float)odd1*COEF[2];
r1 = (float)odd2*COEF[3];
c1 = c1 + r1;
c2 = (float)even1*COEF[4];
r2 = (float)even2*COEF[5];
c2 = c2 + r2;
c3 = (float)odd1*COEF[6];
r3 = (float)odd2*COEF[7];
c3 = c3 + r3;
SAMPLE_BUFFER = c0+T*(c1+T*(c2+T*c3));
SAMPLE_BUFFER = SAMPLE_BUFFER*0.90F;
PCM_2[0] = (int)SAMPLE_BUFFER;
even1 = LR[1][2];
even1 = even1 + LR[1][1];
odd1 = LR[1][2];
odd1 = odd1 - LR[1][1];
even2 = LR[1][3];
even2 = even2 + LR[1][0];
odd2 = LR[1][3];
odd2 = odd2 - LR[1][0];
c0 = (float)even1*COEF[0];
r0 = (float)even2*COEF[1];
c0 = c0 + r0;
c1 = (float)odd1*COEF[2];
r1 = (float)odd2*COEF[3];
c1 = c1 + r1;
c2 = (float)even1*COEF[4];
r2 = (float)even2*COEF[5];
c2 = c2 + r2;
c3 = (float)odd1*COEF[6];
r3 = (float)odd2*COEF[7];
c3 = c3 + r3;
SAMPLE_BUFFER = c0+T*(c1+T*(c2+T*c3));
SAMPLE_BUFFER = SAMPLE_BUFFER*0.90F;
PCM_2[1] = (int)SAMPLE_BUFFER;
SAMPLE[3] = PCM_2[0]/256;
SAMPLE[2] = PCM_2[0]%256;
SAMPLE[1] = PCM_2[1]/256;
SAMPLE[0] = PCM_2[1]%256;
//HAL_GPIO_WritePin(GPIOB, LED_TAG_LIST_Pin, GPIO_PIN_RESET);
}
GitHub for reference: https://github.com/djgreeb/CDJ-1000mk3_new_life_project
Source Code (ZIP): https://drive.google.com/file/d/1VFx4JItAnkkie4v-_Njo-SxVj8lTepl5/view?usp=sharing
I'd like to start off with being able to load an audio file from the SD card, copy it into PSRAM/SDRAM, then play it back using the Audio board.
But, I would like to do this raw, not using the available functions of the audio library, as I will need to make modifications anyways.
Would appreciate any help/guidance.