Skip to content

Commit

Permalink
add sound
Browse files Browse the repository at this point in the history
  • Loading branch information
jwt2706 committed Apr 30, 2024
1 parent fd1c246 commit 6522bbf
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This is a CHIP-8 interpreter, built with SDL2. It mimics the CHIP-8 system and i

[This general high-level guide](https://tobiasvl.github.io/blog/write-a-chip-8-emulator) is what got me into making this. It was a lot of fun! I suggest you try it too.

[Here](https://github.com/loktar00/chip8/tree/master/roms) is the source of the roms. I do not own or claim ownership of these files. They are only present in this repository for educational purposes.
[Here](https://github.com/loktar00/chip8/tree/master/roms) is the source of the all the roms. I just renamed them to making testing easier. I do not own or claim ownership of these files. They are only present in this repository for educational purposes.

## TODO

Expand Down
2 changes: 1 addition & 1 deletion include/chip8.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define CHIP8_H

// CHIP-8 system variables
// (NOTE: chars are 8-bits, shorts are 16-bits)
// NOTE: chars are 8-bits, shorts are 16-bits
struct chip8
{
unsigned short opcode; // current operation code
Expand Down
2 changes: 2 additions & 0 deletions include/sdlutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ typedef struct
{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_AudioDeviceID audio;
} SDLComponents;

int initSDL(SDLComponents *components);
void redrawDisplay(SDLComponents *components, struct chip8 *chip8);
void destroySDL(SDLComponents *components);
void playSound();

#endif
File renamed without changes.
9 changes: 8 additions & 1 deletion src/chip8.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "../include/chip8.h"
#include "../include/sdlutils.h"

#define F 0xF // the 16th V register is for the carry flag

Expand Down Expand Up @@ -169,6 +170,7 @@ void cycle(struct chip8 *chip8)
case 0xC000: // CXNN: Sets VX to the result of a bitwise AND operation on a random number and NN
// just need to make sure that the random number fits in 8-bits
chip8->V[X] = (rand() % 256) & NN;
chip8->pc += 2;
break;
case 0xD000: // DXYN: Draws a sprite at coordinate (VX, VY) that has a width of 8 pixels and a height of N pixels
unsigned short x = chip8->V[X];
Expand Down Expand Up @@ -210,6 +212,7 @@ void cycle(struct chip8 *chip8)
{
case 0x0007: // FX07: Sets VX to the value of the delay timer
chip8->V[X] = chip8->delayTimer;
chip8->pc += 2;
break;
case 0x000A: // FX0A: A key press is awaited, and then stored in VX
for (int i = 0; i < 16; i++)
Expand All @@ -224,17 +227,21 @@ void cycle(struct chip8 *chip8)
return; // if no key is pressed, return without incrementing the program counter
case 0x0015: // FX15: Sets the delay timer to VX
chip8->delayTimer = chip8->V[X];
chip8->pc += 2;
break;
case 0x0018: // FX18: Sets the sound timer to VX
chip8->soundTimer = chip8->V[X];
chip8->pc += 2;
break;
case 0x001E: // FX1E: Adds VX to I
chip8->I += chip8->V[X];
chip8->pc += 2;
break;
case 0x0029: // FX29: Sets I to the location of the sprite for the character in VX
// Characters 0-F (in hexadecimal) are represented by a 4x5 font
// so to move the I to the correct location, we need to multiply the value of VX by 5
chip8->I = chip8->V[X] * 0x5;
chip8->pc += 2;
break;
case 0x0033: // FX33: Stores the binary-coded decimal representation of VX at the addresses I, I plus 1, and I plus 2
chip8->memory[chip8->I] = chip8->V[X] / 100; // fetches the hundreds digit: X00
Expand Down Expand Up @@ -272,7 +279,7 @@ void cycle(struct chip8 *chip8)
{
if (chip8->soundTimer == 1)
{
// play a sound
playSound();
}
chip8->soundTimer--;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ int main()
initKeymap();

// load ROM
loadRom(&chip8, "roms/IBMLogo.ch8");
loadRom(&chip8, "roms/Pong.ch8");

// main loop
while (1)
Expand All @@ -46,7 +46,7 @@ int main()
chip8.drawFlag = 0;
}

SDL_Delay(100);
SDL_Delay(10);
}
destroySDL(&components);
return 0;
Expand Down
52 changes: 51 additions & 1 deletion src/sdlutils.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

#include "../include/sdlutils.h"
#include "../include/chip8.h"

static SDL_AudioDeviceID *audioPointer;

int initSDL(SDLComponents *components)
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
return 1;
Expand Down Expand Up @@ -31,6 +37,25 @@ int initSDL(SDLComponents *components)
return 1;
}

// setup audio
SDL_AudioSpec want, have;
SDL_zero(want);
want.freq = 44100;
want.format = AUDIO_S16SYS;
want.channels = 1;
want.samples = 2048;
want.callback = NULL;

// open audio
components->audio = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
if (components->audio == 0)
{
printf("Failed to open audio device! SDL_Error: %s\n", SDL_GetError());
return 1;
}

audioPointer = &components->audio;

return 0;
}

Expand Down Expand Up @@ -61,3 +86,28 @@ void destroySDL(SDLComponents *components)
SDL_DestroyWindow(components->window);
SDL_Quit();
}

void playSound()
{
// params
int freq = 440; // frequency
int samples = 2048; // number of samples to generate
int sample_rate = 44100; // sample rate

// sound generation
int16_t *sound = malloc(samples * sizeof(int16_t));
for (int i = 0; i < samples; i++)
{
sound[i] = 32767.0 * sin(2.0 * M_PI * freq * i / sample_rate);
}

// play the sound
SDL_QueueAudio(*audioPointer, sound, samples * sizeof(int16_t));
SDL_PauseAudioDevice(*audioPointer, 0);

// wait for the sound to finish playing
SDL_Delay(samples * 1000 / sample_rate);

// free the sound
free(sound);
}

0 comments on commit 6522bbf

Please sign in to comment.