Code Monkey home page Code Monkey logo

Comments (31)

SteveFosdick avatar SteveFosdick commented on June 12, 2024

I will see if I can try listening to something. I think you did mention in one of the threads on the board that OpenAL was doing re-sampling by linear interpolation and I don't think I have ever come across and application in which that produces acceptable results. Have you changed that? Can you? I have done nothing with OpenAL before.

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

I haven't tried to change the interpolation, and it's not obvious how to do that.

I tried one experiment earlier: hack sound.c to fill each audio buffer with a simple square wave. Each audio buffer is 2000 samples, and the sample rate is 31.25KHz, so a buffer lasts 32ms. I filled each new audio buffer with a period-40 square wave. The result sounded much cleaner than the ^G Beep.

The next thing I was to try is a simple square wave whose period isn't a factor of 2000. This should let us hear if buffers are being dropped.

There are probably several issues here, but it is possible there is a bug in the sn76489 emulation.

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

Ok, so doing something really basic, i.e. SOUND 1,-15,128,20 yes it is very quiet. I do have a HiFi amp connected, though, so I can turn the gain up quite a bit and I am not aware of any noise when B-Em is not making any sound.

I don't have the real BBC do hand so do you know what waveshape the sound command is supposed to produce? If it is supposed to be a sine wave it most definitely is not, it's much too bright.

Thinking on your squarewave test, something adding distortion will be more obvious if the starting point is a sine wave because then any extra harmonics have to have been added in the processing chain.

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

Another thought - if you suspect more than one issue then it may be better to work backwards, i.e. the closest we get to the PC's sound hardware from within B-Em. Presumably that is the OpenAL API? If that doesn't sound clean then we know it is OpenAL or the options we have setup OpenAL with.

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

@SteveFosdick: sn76489 I think only produces square waves, but there is some low pass filtering in the Beeb's audio amplifier that means higher harmonics get attenuated.

Try the following:
FOR A=10 TO 250 STEP 10
SOUND 1,-15,A,50
NEXT

For me anyway, some tones sound clean, others don't. And the higher ones are worse.

@SteveFosdick: yes, that's broadly what I'm trying to do.

The audio output is quite low level and has some HF noise. But there is something else going on in addition to this. It might be resampling artifacts. It might be lost buffers. It might be a bug in the sn76489. More debugging is needed.

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

Ok, I tried that. I think what I am hearing is the intended tone beating with a sampling clock which is a fixed frequency and thus depending on the sound being made the beat frequencies are different.

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

So, if I replace the sound_poll function in sound.c with this:

void sound_poll()
{
	double x = sin((2*M_PI)/(BUFLEN>>1)*sound_pos*100) * 32767;
        sound_buffer[sound_pos++] = (int)x;
        sound_buffer[sound_pos++] = (int)x;
        if (sound_pos >= BUFLEN) {
		al_givebuffer(sound_buffer);
                sound_pos = 0;
        }
}

It very definitely gives two tones mixed.

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

What fundamental frequency were you aiming at above? It looks quite high. My calculation puts it at repeating every 10 samples which would be 3.125HKz. Does that sound about right?

Note, the sound buffer is actually mono at this stage. Pairs of adjacent samples being identical will give some weird harmonics. Try calculating x twice!

The original code is quite confusing, but poll_sound() is called every 64 us, and needs to produce 2 audio samples, that are eventually played back at 31.25KHz (i.e. every 32us)

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

If the sound buffer is mono then the loop that copies into what is presumably a stereo interleaved buffer in soundopenal.c, i.e. the al_givebuffer function is doing something odd:

for (c = 0; c < (BUFLEN >> 1); c++) zbuf[c] = buf[c >> 1];

So for half the length of the buffer from sound.c, copy each sample into adjacent positions in the new buffer that is about to be handed to OpenAL. Should that be:

for (c = 0; c < (BUFLEN << 1); c++) zbuf[c] = buf[c >> 1];

i.e. with the shift on BUFLEN the other way? If we are doing mono to stereo the new buffer (zbuf) should have twice as many samples as the old (buf) and c appears to be indexing the new buffer (zbuf).

If use a sine wave routine from the net rather than trying to remember the maths, and write directly into zbuf from the soundopenal.c al_givebuffer routine I get clean output. Example code:

		phase = 0;
                w = 100 * 2.0 * M_PI / (BUFLEN >> 1);
                for (c = 0; c < (BUFLEN >> 1); c++)
		{
			v = 32767.0 * sin(phase);
			zbuf[c*2] = v;
                        zbuf[c*2+1] = v;
                        phase += w;
                }

in the code above c is indexing stereo pairs.

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

So I wondered if this is any easier to read than the original for the buffer copy:

// Copy the mono input buffer to an interleaved stereo
// buffer to queue with OpenAL.

for (stereo_c = mono_c = 0; mono_c < BUFLEN; mono_c++)
{
	zbuf[stereo_c++] = buf[mono_c];
	zbuf[stereo_c++] = buf[mono_c];
}

Using that version with the SOUND command results in cleaner sound to my ear.

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

Ok, listening to some tunes on the emulated Music 5000 it certainly sounds familiar yet strange at the same time. Some notes seem noticeably out of tune and yes, there is some odd noise in the output.

An idea that just occurred to me - now you have opened a separate OpenAL stream at a higher sampling rate is sound_poll being called often enough from the 6502 to supply data at that sampling rate?

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

@SteveFosdick - I think the original code is right, if rather unreadable:

for (c = 0; c < (BUFLEN >> 1); c++) zbuf[c] = buf[c >> 1];

It's right because in this file BUFLEN is defined in bytes:

#define BUFLEN (2000<<2)

I think it's done this way because that's what alBufferData() takes the length in bytes:

image

Your point about the rate of calling sound_poll is a good one. If the Music 5000 is uses any form of software modulation, then it's possible calling every 64us is a bit slow. This is easy to experiment with.

What I will try this morning is to replicate your sin wave experiment, and maybe look at the output on a scope.

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

I've just tested the following:

void sound_poll()
{
  int i;
  for (i = 0; i < 2; i++) {
    double x = sin((2*M_PI)*cycle_pos*ram[0x2fff]/BUFLEN) * 10000;
    sound_buffer[sound_pos] = (int)x;
    cycle_pos++;
    sound_pos++;
  }
  if (sound_pos >= BUFLEN) {
		al_givebuffer(sound_buffer);
    sound_pos = 0;
  }
}

Which lets you set the frequency with ?&2FFF

  • 1 gives 62.5Hz @ 570mV RMS
  • 20 gives 1.2KHz @ 560mV RMS
  • 100 gives 6.25KHz @ 500mV RMS
  • 150 gives 9.4KHz @ 414mV RMS
  • 200 gives 12.5KHz @ 360mV RMS

The lower frequencies sound very good, and the waveform looks quite sinusoidal:
img_0843

But these is possibly something wrong with the handling of high frequencies.

At 6.25KHz there is some noticeable amplitude modulation of the waveform. This looks to be about 350Hz, and the pk-pk amplitude is varying by about 300ms.
img_0844

At 12.5KHz there is some evidence of resampling artifacts I think:
img_0845
A sample is 32us, which is about 2/3 of a division. Imagine a blob at the crest/trough of each wave, and these are the sample points.

Here's the ^G beep:
img_0846
It's much lower in level, only about 100mV RMS.

There is some evidence the the period is alternating between two different frequencies:
img_0848
If you measure the variation, it's exactly 1/31.25KHz, so maybe this is to be expected.

Not sure what to make of this, or even if there is an issue here.

Dave

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

I've managed to get Music 5000 running in the original Beech emulator, and compared that with my FPGA. Again, there is a massive difference with the "ppach" test track, with Beech sounding quite poor. @SteveFosdick let me know if you want to try this as well, and I'll upload the disks.

Beech seems to use a much higher quality audio pipeline, yet still sounds awful.

This post by Darren is interesting:
http://www.stardot.org.uk/forums/viewtopic.php?p=120212#p120212

One major source of buzziness and distortion will be that I haven't implemented the low-pass filter stage which follows the DAC in the real device. The main reason for this is I just haven't had time. The other reason is I'm not sure of its characteristics!

However, for what it's worth, AudioServices::RunTick() handles downsampling. It actually oversamples all generated sound from the BBC (the 76489 and tape, if enabled, as well as the M5000) at 2MHz and adds that to an accumulator. Then, 44100 times a second (these times are precomputed and stored in graboffsets[]), the accumulator is divided down, placed in the output buffer and reset.

There is a huge difference between the software emulation and the FPGA. One (or both!) is probably incorrect.

The lack of low pass filter might be a red herring.

According to http://www.colinfraser.com/m5000/m5-eti.htm:

The left and right outputs each have a four-pole low-pass filter which reconstruct the Signals from their sampled and chopped form.

What I'm doing in the FPGA is summing the different channels, resulting in a new sample every 6MHz/128 = 46.875MHz.

I'm doing something similar in the B-Em's wrapper for Music 5000:
https://github.com/hoglet67/b-em/blob/e1a2c30a2ea38c05b85d3bfe49d809c47be6091f/src/music5000.c#L174

At this point I'm feeling something is badly wrong in the Music5000 emulation, and that's the main source of noise.

What I think I'll try next is to write a Music 5000 test program that outputs a tone from a single channel, and compare with the Waveforms here:
https://github.com/hoglet67/Music5000/wiki#standard-wave-definitions

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

I think I've found evidence of a bug in the Music 5000 software emulation.

I'm using the test program here:
https://github.com/hoglet67/Music5000/wiki#example-of-using-frequency-modulation

This generates a two-tone siren sound to test frequency modulation. On B-Em there is a nasty click when ever the tone changes frequency. This isn't present in the FPGA.

Here are some scope pictures:

FPGA:
img_0851

B-Em:
img_0852

So it looks like in the hardware implementation something is ensuring that channel switching happens at a defined point, and this is missing the the software emulation.

from b-em.

ThomasAdam avatar ThomasAdam commented on June 12, 2024

@hoglet67 -- this is a really interesting analysis to read. While I can't help at all with it, I'm learning a lot of things about oscilloscopes! Which one are you using? They seem rather expensive pieces of equipment.

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

Dave,

I think it's fair to say failing to implement a low pass filter after a DAC will result in poor sound, worse at higher frequencies than lower ones. I think Darren's argument is that by resampling to the sample rate the sound card is running at he's shifted this job onto the sound card. On the other hand his algorithm looks too simple to be a good one. I know that doesn't sound very scientific but I wonder if it is just one way to implement linear interpolation which is known to give poor results. So I am not sure we should dismiss the filter as irrelevant but maybe the failure to switch frequency at the end of a complete cycle of the current frequency is also pretty significant.

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

@ThomasAdam -- glad your are enjoying it!

The scope is a circa 2000 HP 54622D. It's a mixed signal scope, so it has 2 analog channels plus 16 digital channels, and quite deep memory (2M samples).

Dave Jones did a nice EEVBlog tear-down:
http://www.eevblog.com/forum/blog/eevblog-591-agilent-54622d-retro-mixed-signal-osciloscope-review-teardown/

It wasn't cheap (even second hand), but it's by far the most useful item of test equipment I have. I used to work for HP, so I have a soft spot for their test kit.

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

I also know you questioned the quality of the sound hardware on a PC so here are some samples captured in software by taking a copy of what is being output by the BBC in software. This is using pulseaudio which gives the feature to record what is being sent to the sound card via a standard program, e.g. audacity.

So, 62.5Hz zoomed out:

62-5-out

62.5Hz zoomed in:

62-5-in

1.2Khz zoomed out:

1-2k-out

1.2Khz zoomed in:

1-2k-in

6.25Khz zoomed out:

6-25k-out

6.25Khz zoomed in:

6-25k-in

9.4Khz zoomed out:

9-4k-out

9.4Khz zoomed in:

9-4k-in

12.5Khz zoomed out

12-5k-out

12.5Khz zoomed in:

12-5k-in

and finally a very different waveform for the ^G beep:

beep2

I think you can still see a lower frequency ripple imposed on those higher frequencies.

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

@hoglet67 We used to use some HP test kit back when we actually did any electronics. I remember we had one of the fancy scopes that had a colour screen and a blue "Auto" button that you could just press and it would find your waveform for you. We also had some HP computers driving automated test and measurement setups over HPIB.

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

@SteveFosdick -- Do you have the "Internal Sound Filter" enabled? I'm wondering if that is affecting the expected square wave from ^G?

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

@hoglet67 Dave, yes I did. Without it I get a fairly clean square wave with none of the noise in the horizontal lines:

beep3

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

Well, after some effort and with the assistance of BigEd, we found the issue that was causing the modulation discontinuity. The software emulation wrongly had two phase accumulators per channel pair that ran independently. The real hardware has just one that's shared between a channel and it's alternate. After fixing this, the sound is really good, and is very very close to my FPGA.

There is one other area of the emulation I'm suspicious about, and that's where the channel amplitude is applied. The emulation uses a multiple, where as the real hardware uses an add (as it's working in the log domain). I'll try changing this later.

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

A couple more difference between the emulation and the real hardware sorted. This now sounds very close indeed. There's some code tidy up I want to do tomorrow, then I'll create a pull request for this branch.

BTW, I still think there is an issue with the sn76489 emulation causing a slightly "grainy" ^G but that's a separate issue.

I also still need to test the windows build.

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

@hoglet67 Out of interest do you know how close the FPGA sounds to the original hardware. I do have a Music 500 though I haven't yet dared to plug it in as I don't know if it would be subject to failing PSU capacitors in the same way as the BBC itself. It would also be a bit of work to try to get floppies with the right software on as I don't have an MMC at the moment.

Well done for solving the issue.

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

@SteveFosdick -- It would be great to do a comparison with the real hardware. I think it should be quite close, but who knows!

We compared this video on YouTube:
https://www.youtube.com/watch?v=3S54O2ecRAY
with the same track on the FPGA and tonally it sounds very similar, but the FPGA was a bit less noisy, and less bandwidth limited. Not sure if that's just the recording that was lacking.

Looking at the pictures here:
image
http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Hybrid_Music5000.html
there are no X2 capacitor to go bang!

I can point you to the right disc image.

Do you have Master or a Model B?

from b-em.

SteveFosdick avatar SteveFosdick commented on June 12, 2024

Model B.

from b-em.

ThomasAdam avatar ThomasAdam commented on June 12, 2024

This should be fixed...

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

Actually, I think there's still an issue with the sn76489 emulation, but haven't had time to investigate.

I'll rename this issue to be specific to Music 5000, and open a new one.

from b-em.

ThomasAdam avatar ThomasAdam commented on June 12, 2024

Thanks.

from b-em.

hoglet67 avatar hoglet67 commented on June 12, 2024

#16

from b-em.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.