diff --git a/BizHawk.Client.EmuHawk/config/GB/GBPrefControl.Designer.cs b/BizHawk.Client.EmuHawk/config/GB/GBPrefControl.Designer.cs index 4ec1be52b3..5ded3cb4b8 100644 --- a/BizHawk.Client.EmuHawk/config/GB/GBPrefControl.Designer.cs +++ b/BizHawk.Client.EmuHawk/config/GB/GBPrefControl.Designer.cs @@ -31,6 +31,7 @@ this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); this.buttonDefaults = new System.Windows.Forms.Button(); this.buttonPalette = new System.Windows.Forms.Button(); + this.checkBoxMuted = new System.Windows.Forms.CheckBox(); this.SuspendLayout(); // // propertyGrid1 @@ -68,16 +69,30 @@ this.buttonPalette.UseVisualStyleBackColor = true; this.buttonPalette.Click += new System.EventHandler(this.buttonPalette_Click); // + // checkBoxMuted + // + this.checkBoxMuted.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkBoxMuted.AutoSize = true; + this.checkBoxMuted.Location = new System.Drawing.Point(84, 289); + this.checkBoxMuted.Name = "checkBoxMuted"; + this.checkBoxMuted.Size = new System.Drawing.Size(80, 17); + this.checkBoxMuted.TabIndex = 3; + this.checkBoxMuted.Text = "Mute Audio"; + this.checkBoxMuted.UseVisualStyleBackColor = true; + this.checkBoxMuted.CheckedChanged += new System.EventHandler(this.checkBoxMuted_CheckedChanged); + // // GBPrefControl // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.checkBoxMuted); this.Controls.Add(this.buttonPalette); this.Controls.Add(this.buttonDefaults); this.Controls.Add(this.propertyGrid1); this.Name = "GBPrefControl"; this.Size = new System.Drawing.Size(324, 311); this.ResumeLayout(false); + this.PerformLayout(); } @@ -86,5 +101,6 @@ private System.Windows.Forms.PropertyGrid propertyGrid1; private System.Windows.Forms.Button buttonDefaults; private System.Windows.Forms.Button buttonPalette; + private System.Windows.Forms.CheckBox checkBoxMuted; } } diff --git a/BizHawk.Client.EmuHawk/config/GB/GBPrefControl.cs b/BizHawk.Client.EmuHawk/config/GB/GBPrefControl.cs index ff2f07b613..73582e0a23 100644 --- a/BizHawk.Client.EmuHawk/config/GB/GBPrefControl.cs +++ b/BizHawk.Client.EmuHawk/config/GB/GBPrefControl.cs @@ -33,6 +33,7 @@ namespace BizHawk.Client.EmuHawk.config.GB this.ss = ss ?? new Gameboy.GambatteSyncSettings(); propertyGrid1.SelectedObject = this.ss; propertyGrid1.Enabled = !Global.MovieSession.Movie.IsActive; + checkBoxMuted.Checked = this.s.Muted; } public void GetSettings(out Gameboy.GambatteSettings s, out Gameboy.GambatteSyncSettings ss) @@ -60,5 +61,10 @@ namespace BizHawk.Client.EmuHawk.config.GB { SyncSettingsChanged = true; } + + private void checkBoxMuted_CheckedChanged(object sender, EventArgs e) + { + s.Muted = (sender as CheckBox).Checked; + } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs index 05b583969a..22ee617f7a 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -331,7 +331,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy _cycleCount += (ulong)samplesEmitted; frameOverflow += samplesEmitted; - if (rendersound) + if (rendersound && !Muted) { ProcessSound((int)samplesEmitted); } @@ -354,13 +354,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy _cycleCount += (ulong)samplesEmitted; frameOverflow = 0; - if (rendersound) + if (rendersound && !Muted) { ProcessSound((int)samplesEmitted); } } - if (rendersound) + if (rendersound && !Muted) ProcessSoundEnd(); FrameAdvancePost(); @@ -980,6 +980,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy nsamp = soundoutbuffcontains; } + public bool Muted { get { return _Settings.Muted; } } + #endregion #region Settings @@ -1017,6 +1019,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy public int[] GBPalette; public GBColors.ColorType CGBColors; + /// + /// true to mute all audio + /// + public bool Muted; public GambatteSettings() { diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs index 16c6dd09ed..4c6cb1bfd7 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs @@ -467,38 +467,58 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy int LatchL; int LatchR; - void PrepSound() + unsafe void PrepSound() { - unsafe + fixed (short* sl = LeftBuffer, sr = RightBuffer) { - fixed (short* sl = LeftBuffer, sr = RightBuffer) + for (uint i = 0; i < SampPerFrame * 2; i += 2) { - for (uint i = 0; i < SampPerFrame * 2; i += 2) + int s = (sl[i] + sl[i + 1]) / 2; + if (s != LatchL) { - int s = (sl[i] + sl[i + 1]) / 2; - if (s != LatchL) - { - blip_left.AddDelta(i, s - LatchL); - LatchL = s; - } - s = (sr[i] + sr[i + 1]) / 2; - if (s != LatchR) - { - blip_right.AddDelta(i, s - LatchR); - LatchR = s; - } + blip_left.AddDelta(i, s - LatchL); + LatchL = s; + } + s = (sr[i] + sr[i + 1]) / 2; + if (s != LatchR) + { + blip_right.AddDelta(i, s - LatchR); + LatchR = s; } - } + } + blip_left.EndFrame(SampPerFrame * 2); blip_right.EndFrame(SampPerFrame * 2); int count = blip_left.SamplesAvailable(); if (count != blip_right.SamplesAvailable()) throw new Exception("Sound problem?"); + // calling blip.Clear() causes rounding fractions to be reset, + // and if only one channel is muted, in subsequent frames we can be off by a sample or two + // not a big deal, but we didn't account for it. so we actually complete the entire + // audio read and then stamp it out if muted. + blip_left.ReadSamplesLeft(SampleBuffer, count); + if (L.Muted) + { + fixed (short* p = SampleBuffer) + { + for (int i = 0; i < SampleBuffer.Length; i += 2) + p[i] = 0; + } + } + blip_right.ReadSamplesRight(SampleBuffer, count); + if (R.Muted) + { + fixed (short* p = SampleBuffer) + { + for (int i = 1; i < SampleBuffer.Length; i += 2) + p[i] = 0; + } + } SampleBufferContains = count; }