<commit_before>package eu.rekawek.coffeegb.sound;

import eu.rekawek.coffeegb.AddressSpace;
import eu.rekawek.coffeegb.debug.command.apu.Channel;
import eu.rekawek.coffeegb.memory.Ram;

public class Sound implements AddressSpace {

    private static final int[] MASKS = new int[] {
            0x80, 0x3f, 0x00, 0xff, 0xbf,
            0xff, 0x3f, 0x00, 0xff, 0xbf,
            0x7f, 0xff, 0x9f, 0xff, 0xbf,
            0xff, 0xff, 0x00, 0x00, 0xbf,
            0x00, 0x00, 0x70,
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    private final AbstractSoundMode[] allModes = new AbstractSoundMode[4];

    private final Ram r = new Ram(0xff24, 0x03);

    private final SoundOutput output;

    private int[] channels = new int[4];

    private boolean enabled;

    private boolean[] overridenEnabled = {true, true, true, true};

    public Sound(SoundOutput output, boolean gbc) {
        allModes[0] = new SoundMode1(gbc);
        allModes[1] = new SoundMode2(gbc);
        allModes[2] = new SoundMode3(gbc);
        allModes[3] = new SoundMode4(gbc);
        this.output = output;
    }

    public void tick() {
        if (!enabled) {
            return;
        }
        for (int i = 0; i < allModes.length; i++) {
            AbstractSoundMode m = allModes[i];
            channels[i] = m.tick();
        }

        int selection = r.getByte(0xff25);
        int left = 0;
        int right = 0;
        for (int i = 0; i < 4; i++) {
            if (!overridenEnabled[i]) {
                continue;
            }
            if ((selection & (1 << i)) != 0) {
                left += channels[i];
            }
            if ((selection & (1 << i + 4)) != 0) {
                right += channels[i];
            }
        }
        left /= 4;
        right /= 4;

        int volumes = r.getByte(0xff24);
        left *= (volumes & 0b111);
        right *= ((volumes >> 4) & 0b111);

        output.play((byte) left, (byte) right);
    }

    private AddressSpace getAddressSpace(int address) {
        for (AbstractSoundMode m : allModes) {
            if (m.accepts(address)) {<commit_msg>Stereo audio is flipped #8<commit_after>package eu.rekawek.coffeegb.sound;

import eu.rekawek.coffeegb.AddressSpace;
import eu.rekawek.coffeegb.debug.command.apu.Channel;
import eu.rekawek.coffeegb.memory.Ram;

public class Sound implements AddressSpace {

    private static final int[] MASKS = new int[] {
            0x80, 0x3f, 0x00, 0xff, 0xbf,
            0xff, 0x3f, 0x00, 0xff, 0xbf,
            0x7f, 0xff, 0x9f, 0xff, 0xbf,
            0xff, 0xff, 0x00, 0x00, 0xbf,
            0x00, 0x00, 0x70,
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    private final AbstractSoundMode[] allModes = new AbstractSoundMode[4];

    private final Ram r = new Ram(0xff24, 0x03);

    private final SoundOutput output;

    private int[] channels = new int[4];

    private boolean enabled;

    private boolean[] overridenEnabled = {true, true, true, true};

    public Sound(SoundOutput output, boolean gbc) {
        allModes[0] = new SoundMode1(gbc);
        allModes[1] = new SoundMode2(gbc);
        allModes[2] = new SoundMode3(gbc);
        allModes[3] = new SoundMode4(gbc);
        this.output = output;
    }

    public void tick() {
        if (!enabled) {
            return;
        }
        for (int i = 0; i < allModes.length; i++) {
            AbstractSoundMode m = allModes[i];
            channels[i] = m.tick();
        }

        int selection = r.getByte(0xff25);
        int left = 0;
        int right = 0;
        for (int i = 0; i < 4; i++) {
            if (!overridenEnabled[i]) {
                continue;
            }
            if ((selection & (1 << i + 4)) != 0) {
                left += channels[i];
            }
            if ((selection & (1 << i)) != 0) {
                right += channels[i];
            }
        }
        left /= 4;
        right /= 4;

        int volumes = r.getByte(0xff24);
        left *= ((volumes >> 4) & 0b111);
        right *= (volumes & 0b111);

        output.play((byte) left, (byte) right);
    }

    private AddressSpace getAddressSpace(int address) {
        for (AbstractSoundMode m : allModes) {
            if (m.accepts(address)) {
{'fraction_non_alphanumeric': 0.12613611172688982, 'fraction_numerical': 0.06362225670583019, 'mean_word_length': 1.8793873643905552, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '129714', 'n_tokens_mistral': 1781, 'n_tokens_neox': 1562, 'n_words': 402}