Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spectrogram Orientation #27

Closed
padesso opened this issue Aug 31, 2020 · 7 comments
Closed

Spectrogram Orientation #27

padesso opened this issue Aug 31, 2020 · 7 comments

Comments

@padesso
Copy link

padesso commented Aug 31, 2020

Hi Scott,

I've been working with your Spectrogram for a few weeks and like it very much. I was able to integrate into my project but am considering updating it to support both the existing horizontal orientation as well as vertical. It's not a trivial change and I also don't think I can accomplish it without breaking changes. Do you have any plans to do so? Would it be an appealing PR?

@swharden
Copy link
Owner

swharden commented Aug 31, 2020

Hi @padesso I'm happy to hear you're enjoying Spectrogram!

Adding a top-down orientation is a good idea. "Waterfall" displays are really common (especially in RF analysis) so supporting this makes sense. Probably the simplest way to do this is to add a bool horizontal = true argument to the Spectrogram.GetBitmap method:

public Bitmap GetBitmap(double intensity = 1, bool dB = false, bool roll = false) =>
Image.GetBitmap(ffts, cmap, intensity, dB, roll, NextColumnIndex);

...then add that same argument to the Image.GetBitmap method. You'd have to refactor this method a bit to support vertical orientation, but support could be added just by refactoring this method:

public static Bitmap GetBitmap(List<double[]> ffts, Colormap cmap, double intensity = 1, bool dB = false, bool roll = false, int rollOffset = 0)
{
if (ffts.Count == 0)
throw new ArgumentException("This Spectrogram contains no FFTs (likely because no signal was added)");
int Width = ffts.Count;
int Height = ffts[0].Length;
Bitmap bmp = new Bitmap(Width, Height, PixelFormat.Format8bppIndexed);
cmap.Apply(bmp);
var lockRect = new Rectangle(0, 0, Width, Height);
BitmapData bitmapData = bmp.LockBits(lockRect, ImageLockMode.ReadOnly, bmp.PixelFormat);
int stride = bitmapData.Stride;
byte[] bytes = new byte[bitmapData.Stride * bmp.Height];
Parallel.For(0, Width, col =>
{
int sourceCol = col;
if (roll)
{
sourceCol += Width - rollOffset % Width;
if (sourceCol >= Width)
sourceCol -= Width;
}
for (int row = 0; row < Height; row++)
{
double value = ffts[sourceCol][row];
if (dB)
value = 20 * Math.Log10(value + 1);
value *= intensity;
value = Math.Min(value, 255);
int bytePosition = (Height - 1 - row) * stride + col;
bytes[bytePosition] = (byte)value;
}
});
Marshal.Copy(bytes, 0, bitmapData.Scan0, bytes.Length);
bmp.UnlockBits(bitmapData);
return bmp;
}
}

If you want to have a go at adding this feature you're welcome to make a PR! If you don't get around to it, I'll leave this issue open and try to support this feature some time in the future. Thanks for the suggestion!

@swharden
Copy link
Owner

... and perhaps a bool reverse = false argument would be helpful too? This could simply reverse the FFTs prior to plotting them, but the argument could control whether the waterfall display scrolls upward or downward 🤔

@padesso
Copy link
Author

padesso commented Aug 31, 2020

Thanks for the quick response! I think that by far the most common use case, and coincidentally mine for a radio project :) using this would be waterfall and particularly done in a way so it could be aligned with a graphical equalizer that shows peaks of the audio Your suggestion is certainly where I will start to look at this. There are some other more minor areas (like the scale bar) that will need to be touched but I aim to start looking into the implementation details in the evenings this week and will stay in touch on this issue with progres/blockers.

@swharden
Copy link
Owner

Sounds great! I'll keep an eye out for a PR, but let me know if you have any questions along the way.

You may find helpful code at https://github.com/swharden/FSKview such as Ruler.cs

@padesso
Copy link
Author

padesso commented Sep 16, 2020

Just checking in with you. I have the spectrogram in a waterfall orientation but need to complete some work on the scale bar and do some validation. I haven't been able to focus on it because of work but expect to pick this back up soon.

@swharden
Copy link
Owner

Just checking in with you. I have the spectrogram in a waterfall orientation but need to complete some work on the scale bar and do some validation. I haven't been able to focus on it because of work but expect to pick this back up soon.

Hey, no worries! I appreciate you working on it, and definitely take as long as you need to do it well 👍

I'm happy to leave this issue open a while longer so it stays on both of our radars. I'm happy to see what you come up with!

Best,
Scott

@swharden
Copy link
Owner

swharden commented Nov 1, 2020

I haven't seen movement on this for a while so I'll close this issue, but if/when the topic arises again I'll open this back up and pick up where we left off 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants