oscilloscope

This commit is contained in:
y4my4my4m 2023-09-04 21:15:09 +09:00
parent 53ed2bbc2e
commit c92f7db428
5 changed files with 112 additions and 22 deletions

View file

@ -21,12 +21,15 @@ U16 currentRate = InU16(ac97.nam + EXT_FRONT_RATE);
"currentRate: %d\n", currentRate; "currentRate: %d\n", currentRate;
#include "Classes" #include "Classes"
#include "Utils"
// include_noreindex "MIDIHandling" // include_noreindex "MIDIHandling"
// include_noreindex "WaveformGen" // include_noreindex "WaveformGen"
// include_noreindex "UITracker" // include_noreindex "UITracker"
#include "Oscilloscope"
#include "MusicTracker" #include "MusicTracker"
AutoComplete(0); AutoComplete(0);
MusicTracker; MusicTracker;
StartOscilloscope;

View file

@ -42,7 +42,7 @@ U0 AudioPlayNote(U8 note, U8 velocity, U8 instrument) {
break; break;
case SAMPLE: case SAMPLE:
PlaySample(buffer, bufferSize, note, velocity); PlaySample(buffer, bufferSize, note, velocity);
Print("Buffer first values: %d, %d, %d, %d...\n", buffer[0], buffer[1], buffer[2], buffer[3]); //Print("Buffer first values: %d, %d, %d, %d...\n", buffer[0], buffer[1], buffer[2], buffer[3]);
break; break;
default: default:
GenerateSineWave(buffer, bufferSize, freq, velocity); GenerateSineWave(buffer, bufferSize, freq, velocity);
@ -51,35 +51,49 @@ U0 AudioPlayNote(U8 note, U8 velocity, U8 instrument) {
//ApplyEnvelope(buffer, SAMPLE_RATE); // TODO: Apply fade in and fade out //ApplyEnvelope(buffer, SAMPLE_RATE); // TODO: Apply fade in and fade out
// I64 i;
// for (i = 0; i < bufferSize; i++) {
// // Copy data to the shared oscilloscope buffer
// gSharedBuffer[i] = buffer[i];
// }
// Play the buffer using the AC97 driver: // Play the buffer using the AC97 driver:
AudioSFXPlay(buffer, bufferSize); AudioSFXPlay(buffer, bufferSize);
// silly debug print // silly debug print
if (instrument == SAMPLE)
"Instrument: $$RED$$ SAMPLE $$DKGRAY$$|$$FG$$ Note: $$YELLOW$$%d$$FG$$\n", note;
if (instrument == PULSE1) if (instrument == PULSE1)
"Instrument: $$GREEN$$ PULSE1 $$DKGRAY$$|$$FG$$ Note: $$YELLOW$$%d$$FG$$\n", note; "³ $$GREEN$$PULSE1 $$FG$$³ $$YELLOW$$%d$$FG$$\t³", note;
if (instrument == PULSE2) if (instrument == PULSE2)
"Instrument: $$CYAN$$ PULSE2 $$DKGRAY$$|$$FG$$ Note: $$YELLOW$$%d$$FG$$\n", note; "³ $$CYAN$$PULSE2 $$FG$$³ $$YELLOW$$%d$$FG$$\t³", note;
if (instrument == TRIANGLE) if (instrument == TRIANGLE)
"Instrument: $$YELLOW$$ TRIANGLE $$DKGRAY$$|$$FG$$ Note: $$YELLOW$$%d$$FG$$\n", note; "³ $$YELLOW$$TRIANGLE $$FG$$³ $$YELLOW$$%d$$FG$$\t³", note;
if (instrument == NOISE) if (instrument == NOISE)
"Instrument: $$BROWN$$ NOISE $$DKGRAY$$|$$FG$$ Note: $$YELLOW$$%d$$FG$$\n", note; "³ $$BROWN$$NOISE $$FG$$³ $$YELLOW$$%d$$FG$$\t³", note;
if (instrument == SAMPLE)
"³ $$RED$$SAMPLE $$FG$$³ $$YELLOW$$%d$$FG$$\t³", note;
if (instrument == INSTRUMENT_NONE)
"³ ³ \t³", note;
"\n";
Free(buffer); Free(buffer);
} }
U0 PlayPattern(Pattern *pattern) { U0 PlayPattern(Pattern *pattern) {
I64 row; I64 row;
NoteCell *cell; NoteCell *cell;
"ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄ¿\n";
"³ INSTRUMENT ³ NOTE ³\n";
"ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄ´\n";
for (row = 0; row < TRACK_LENGTH; row++) { for (row = 0; row < TRACK_LENGTH; row++) {
cell = &pattern->cells[row]; cell = &pattern->cells[row];
if (cell->note) { if (cell->note) {
AudioPlayNote(cell->note, cell->velocity, cell->instrument); AudioPlayNote(cell->note, cell->velocity, cell->instrument);
if (row < TRACK_LENGTH-1) "ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄ´\n";
} }
if (cell->instrument == SAMPLE) Sleep(1000); // wait for 6sec for the 7sec sample test if (cell->instrument == SAMPLE) Sleep(1000); // wait for 6sec for the 7sec sample test
//Sleep(1200); // Adjust for tempo //Sleep(1200); // Adjust for tempo
Sleep(300); Sleep(300);
} }
"ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÙ\n";
} }
U0 EnterPattern(Pattern *pattern) { U0 EnterPattern(Pattern *pattern) {
@ -87,7 +101,7 @@ U0 EnterPattern(Pattern *pattern) {
NoteCell *cell; NoteCell *cell;
for (row = 0; row < TRACK_LENGTH; row++) { for (row = 0; row < TRACK_LENGTH; row++) {
cell = &pattern->cells[row]; cell = &pattern->cells[row];
Print("Enter note for row %d (0-127, 0 for none): ", row); Print("Enter note for row $$LTGREEN$$%d$$FG$$ (0-127, 0 for none): ", row);
cell->note = KeyGet(&sc); cell->note = KeyGet(&sc);
"%d\n", cell->note; "%d\n", cell->note;
if (cell->note) { if (cell->note) {
@ -118,11 +132,10 @@ U0 EnterPattern(Pattern *pattern) {
"SAMPLE\n"; "SAMPLE\n";
break; break;
default: default:
Print("Invalid choice.\n");
cell->instrument = INSTRUMENT_NONE; cell->instrument = INSTRUMENT_NONE;
"SINE\n"; "SINE\n";
break; break;
// return; // return;
} }
AudioPlayNote(cell->note, cell->velocity, cell->instrument); AudioPlayNote(cell->note, cell->velocity, cell->instrument);
@ -216,4 +229,5 @@ U0 MusicTracker() {
} }
} }
CleanupWaveformGen(); // Free the sample buffer CleanupWaveformGen(); // Free the sample buffer
Kill("Oscilloscope");
} }

View file

@ -0,0 +1,73 @@
// Globals
U32 *gSharedBuffer;
I64 gSharedBufferPosition = 0;
I64 gSharedBufferSize;
// Initialize shared buffer
U0 InitSharedBuffer(I64 size) {
gSharedBuffer = MAlloc(size * sizeof(U32));
gSharedBufferSize = size;
gSharedBufferPosition = 0;
}
// Update shared buffer in your audio playback function
U0 UpdateSharedBuffer(U32 *buffer, I64 size) {
I64 i;
for (i = 0; i < size; i++) {
gSharedBuffer[gSharedBufferPosition] = buffer[i];
gSharedBufferPosition = (gSharedBufferPosition + 1) % gSharedBufferSize;
}
}
U0 OscilloscopeDraw() {
I64 i, y;
//GrClear(0); // Clear the screen
I64 startPosition = gSharedBufferPosition;
for (i = 0; i < 400; i++) {
I16 sample_value = (gSharedBuffer[startPosition] & 0xFFFF) - 32768; // extract left channel and center around 0
F64 normalized_sample = ToF64(sample_value) / 32768.0;
y = 300 / 2 - (normalized_sample * 300 / 2);
GrPlot(i, y, WHITE); // Using GrPlot instead of DrawPoint
startPosition = (startPosition + 1) % gSharedBufferSize;
}
}
// Oscilloscope task
U0 OscilloscopeTask() {
// Fs->draw_it = &OscilloscopeDraw; // Set the draw callback
while (TRUE)
{
Refresh;
}
}
U0 StartOscilloscope() {
InitSharedBuffer(44100); // For example, buffer to store 1 second of audio at 44100Hz
// SettingsPush(); // Push current settings
// Fs->win_width = 400; // Width of the oscilloscope window
// Fs->win_height = 300; // Height of the oscilloscope window
WinHorz((TEXT_COLS / 2) - 200,
(TEXT_COLS / 2) - 200 + (200 - 1),
Fs);
WinVert((TEXT_ROWS / 2) - 150,
(TEXT_ROWS / 2) - 150 + (Fs->win_height - 1),
Fs);
// Fs->border_src = BDS_CONST;
// Fs->border_attr = LTGREEN << 4 + WHITE;
// StrCopy(Fs->task_title, "Oscilloscope");
Fs->draw_it = &OscilloscopeDraw; // Set the draw callback
while (TRUE)
{
Refresh;
}
// Spawn("Oscilloscope", OscilloscopeTask); // Start the oscilloscope task
// SettingsPop(); // Pop settings
}

9
src/Home/Tracker/Utils.ZC Executable file
View file

@ -0,0 +1,9 @@
F64 RoundToNearestHalf(F64 value) {
return Round(value * 2.0) / 2.0;
}
F64 GetPlaybackRateMultiplier(U8 targetNote, U8 referenceNote) {
I64 semitoneDifference = targetNote - referenceNote;
return Pow(2.0, semitoneDifference / 12.0);
}


View file

@ -223,15 +223,6 @@ U0 LoadSample(U8 *filename) {
// return ClampToI16(RoundF64(result)); // return ClampToI16(RoundF64(result));
// } // }
F64 RoundToNearestHalf(F64 value) {
return Round(value * 2.0) / 2.0;
}
F64 GetPlaybackRateMultiplier(U8 targetNote, U8 referenceNote) {
I64 semitoneDifference = targetNote - referenceNote;
return Pow(2.0, semitoneDifference / 12.0);
}
U0 PlaySample(U32 *buffer, I64 duration, U8 note, U8 velocity) { U0 PlaySample(U32 *buffer, I64 duration, U8 note, U8 velocity) {
if (!gSampleData || !gSampleSize) { if (!gSampleData || !gSampleSize) {
Print("Sample not loaded.\n"); Print("Sample not loaded.\n");