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

Add "-e rawout" to "play" a file to an OPL2/3 .RAW file #9

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

arodland
Copy link

I'm not really a C++ dev, and I'm sure that this could really use some refactoring, but it works.

The idea is to allow someone to do adplay -e rawout -d song.raw song.rad to convert a song in some module format to the RDOS RAW format using adplug's "disk OPL" class. gamemus can then convert the RAW to formats like DRO, IMF, or VGM. -e rawout implies -O null -o since those are the options you probably want for conversion.

As part of the change, the null output driver now parses the input (calls p->update()) instead of ignoring the input and going to a non-playing state immediately.

The stuff I did with dynamic_cast is probably a bad idea, but I didn't see a better way without changing the interface of Copl, which I didn't want to take on.

Copy link
Member

@Malvineous Malvineous left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good but I'd rather NullOutput be left unchanged and a second class be created instead, see inline comments for details. Also looks like one change can be avoided by fixing what looks like a CDiskopl bug in the core AdPlug library.

src/adplay.cc Show resolved Hide resolved
src/adplay.cc Outdated Show resolved Hide resolved
src/null.h Outdated
if (dopl != NULL) {
dopl->update(p);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not so keen on changing NullOutput to no longer be null, as it's used elsewhere for things like getting the length of the song. If it starts processing output, then operations like retrieving the length of songs will become slower and CPU-intensive.

Would it be possible to clone NullOutput to something like DiscardOutput and apply your changes there instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that's easily done.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last commit addresses this @Malvineous

src/output.cc Outdated
if (dopl != NULL) {
dopl->update(p);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is due to a bug in AdPlug. CDiskopl::update() only contains one parameter, but it should contain two in order to correctly override Copl::update().

For this I would suggest adding the second parameter to CDiskopl::update() so that this bit of the patch is no longer required.

If it works, please submit a PR to the main AdPlug library for this part.

Thanks for sending in the PR, I hope you don't mind my comments!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not just that, though, because the param it does take is a CPlayer, which is incompatible with what Copl::update does. I'm sure there's a nicer way to do things, but I'm not sure what it is.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(change the signature of update to require all three things, and ignore various subsets of them in different OPLs? That has a broad impact though.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CDiskopl->update is on purpose not overriding the virtual update from the Copl base class, since they are for very different things. They should had different names, but a bit late to change that now.

virtual Copl->update(short *buf, int samples) is only used when the audio chain involves an PCM audio stream:
ALSA/OSS/ESD/libao talks with CPlayer to push time and retrieve delays, and pulls audio-data from the Copl->update(buf,length) as needed.

CDiskopl has its own dance. It wants the I/O data written to Copl, but it also wants the delay information that CPlayer provides which does not fit the model that audio-stream uses.
CDiskopl->update() is the common code that the top-level classes like EmuPlayer in AdPlug/Unix would have contained.

I also agree to hijacking NullOutput is a bit dirty, and a more clean implementation would be to add it as its own Player class "DiskPlayer" that always and only is used when emulator type is Emu_Rawout.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'll happily admit that this isn't done "right". I didn't quite follow your class hierarchy and C++ isn't a language I touch very often. I'd be grateful for any amount of surgery if it gets this mergeable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are a bit messy, and update() name is used multiple locations

@mywave82
Copy link
Contributor

mywave82 commented Feb 1, 2024

I am going to rebase this onto current master, and fix the indentation problems

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

Successfully merging this pull request may close these issues.

3 participants