INTERACT FORUM

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1]   Go Down

Author Topic: Audio Output plugin  (Read 12986 times)

muchadhesion

  • Recent member
  • *
  • Posts: 44
Audio Output plugin
« on: February 25, 2009, 10:55:36 am »

Hi there,

I'd like to write a output plugin similar to DiskWriter, or out_mj.dll that would be selectable as an output setting from  "Options | Playback | Audio | Output mode" drop down.

From what I can tell, the "Output mode" setting is indexed through the supplied out_mj.dll which implements the WaveOut, DirectSound, Disk Writer, etc..etc..

Should I be replacing out_MJ.dll with my own implementation, or is there another way of adding output plugins to the out_MJ.dll list?

Is there a published interface that out_MJ.dll implements?

Thanks in advance.



Logged

Matt

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 41949
  • Shoes gone again!
Re: Audio Output plugin
« Reply #1 on: February 25, 2009, 11:04:21 am »

The output plugin SDK has not been released.  If you provide more details about your intentions, we might be able to help.

Thanks.
Logged
Matt Ashland, JRiver Media Center

muchadhesion

  • Recent member
  • *
  • Posts: 44
Re: Audio Output plugin
« Reply #2 on: February 25, 2009, 12:32:02 pm »

Hi,

Thanks for the swift response.

I'm building a muti-room audio system.  A networked digital media player in each room is synchronised to an audio stream (with timing information) sent over a LAN.  I'd like to make JRiver a first class front-end and audio source in this system.  To do that, I'd like to capture the MC audio stream, reencode it with (global) timing information, and send it to remote players in each room.

I could capture the audio at the OS/driver level, or (I guess) with a MC DSP plugin.  But I'd prefer to do this as a first class Audio output from MC.

The output functionality I'm hoping to implement is
a) Local PC output of JRiver MC can be "Muted" (sent to null) or delayed ("synchonise" local PC playback to global clock)
b) Encode the MC audio stream, add timing information and send to remote players.


Logged

Matt

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 41949
  • Shoes gone again!
Re: Audio Output plugin
« Reply #3 on: February 25, 2009, 02:48:32 pm »

This doesn't have all the includes you'd need, but it shows the output plugin interface (IMJOutputPlugin).  You'll have to export a C++ class (interface) from a DLL with a function GetOutputPlugin.

Here's the main header file:
Code: [Select]
/************************************************************************************
IMJOutputPlugin - base class for Media Jukebox output plugins.
Copyright (c) 2001-2008 JRiver, Inc.

It's strongly recommend that you DO NOT ALTER this file.  This class is a base building
class for new plugins.  Add any specific changes to the new class.

Last updated: January 2, 2003
************************************************************************************/

/************************************************************************************
Description of architecture:

1) Open(...) with some desired output format
2) The plugin gets run in a loop like this, until the user stops playback or there's no more data:
UpdateBuffer(...)
remove any spent (played) data from your buffer and return the number of bytes removed
FillBuffers(...)
fill your buffer(s) with as much data as possible, return the number of bytes added or
FILL_BUFFERS_NO_ROOM if they're already full (so returning 0 would mean that there was no more data available to fill from)
Sleep(...)
the loop will pause GetSleepMS(...) milliseconds (1000 = 1 second)... if you have large buffers, you can make this
a higher number to prevent FillBuffers(...) from getting called too often

notes:
- It is crucial that the number of bytes returned by UpdateBuffer(...) and FillBuffers(...) stay synchronized.  For every byte that
gets added, another byte must be eventually removed.  Otherwise Media Jukebox's internal buffers will get confused and fill up.
- Keep in mind that some amount of time passes between UpdateBuffer(...) and FillBuffers(...), so be careful when tracking
whether a buffer has been processed and should be added to the "played bytes" returned by UpdateBuffer(...).
- A loop is used instead of events to ease the creation of plugins -- that way, systems like DirectSound don't
require a polling thread inside of the plugin (their callback methods are unreliable, so can't be used)
- With functions that return an int, 0 means success, and any other value is considered an error code.
************************************************************************************/

#pragma once

/************************************************************************************
Output plugins MUST be built in Unicode
************************************************************************************/
#if (!defined(UNICODE) || !defined(_UNICODE))
#error "Output plugins must be built in Unicode mode!"
#endif

/************************************************************************************
Includes
************************************************************************************/
#include <windows.h>
#include "AudioFormat.h"

/************************************************************************************
Definitions
************************************************************************************/
#define FILL_BUFFERS_NO_ROOM (-1000)

/************************************************************************************
Information fields
************************************************************************************/
enum MJ_OUTPUT_PLUGIN_INFO_FIELDS
{
MJ_OUTPUT_PLUGIN_INFO_NAME, // get the display name of the plugin (i.e. "JRiver WaveOut" or similar)
MJ_OUTPUT_PLUGIN_INFO_SUPPORTED_BY_SYSTEM, // return TRUE if the plugin is supported by the system
MJ_OUTPUT_PLUGIN_INFO_SUPPORTS_USER_BIT_DEPTH, // whether or not this plugin can support user bit depth selections
MJ_OUTPUT_PLUGIN_INFO_ACCELERATED_SPEED, // return TRUE for plugins that run as fast as possible (instead of real-time) (Disk Writer, etc.)
MJ_OUTPUT_PLUGIN_INFO_HAS_CONFIGURATION, // whether or not the plugin supports MJ_OUTPUT_PLUGIN_COMMAND_CONFIGURE
MJ_OUTPUT_PLUGIN_INFO_AUTHORIZATION, // get the authorization code
MJ_OUTPUT_PLUGIN_INFO_ZONE, // the playback zone (so settings can be saved on a zone-by-zone basis)
MJ_OUTPUT_PLUGIN_INFO_NO_PRE_BUFFER, // return TRUE for plugins that run real-time in background (where choppy playback isn't an issue) but require quick response to cancel
MJ_OUTPUT_PLUGIN_INFO_OUTPUT_DEVICE_NAME, // the name of the current sound card line (empty if default or unknown)
MJ_OUTPUT_PLUGIN_INFO_CUSTOM_BASE = 1000, // some derived classes need custom messages
};

/************************************************************************************
Commands
************************************************************************************/
enum MJ_OUTPUT_PLUGIN_COMMANDS // description [nParam1, nParam2]
{
MJ_OUTPUT_PLUGIN_COMMAND_PAUSE, // set the pause state [pause state (non-zero for paused), ignored]
MJ_OUTPUT_PLUGIN_COMMAND_FLUSH, // flush (used when seeking, etc. to remove queued data) [ignored, ignored]
MJ_OUTPUT_PLUGIN_COMMAND_SET_EOF, // called to signal that the EOF has been reached (can be used to break files with Disk Writer, etc.) [bytes until EOF, ignored]
MJ_OUTPUT_PLUGIN_COMMAND_FINALIZE, // the EOF has been reached, and more data isn't on the way (at least for a while) [ignored, ignored]
MJ_OUTPUT_PLUGIN_COMMAND_CONFIGURE, // show the plugin configuration dialog [HWND parent, ignored]
};

/************************************************************************************
Security modes
************************************************************************************/
#ifndef MJ_OUTPUT_PLUGIN_SECURITY_MODE_NONE_DEFINED
#define MJ_OUTPUT_PLUGIN_SECURITY_MODE_NONE_DEFINED
static const GUID MJ_OUTPUT_PLUGIN_SECURITY_MODE_NONE = { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
#endif

/*************************************************************************************
Callbacks (used by the output plugin)
*************************************************************************************/
class IMJOutputPluginCallbacks
{
public:

// get data for playback (already DSP'd, cross-faded, etc.)
// note, you can specify a nBitsPerSample if MJ_OUTPUT_PLUGIN_INFO_SUPPORTS_USER_BIT_DEPTH is false
// also, setting bAllowEatCrossFade to false will make it so you'll get guaranteed fade lengths (good for disk writing, etc.)
virtual int FillPlaybackBuffer(void * pBuffer, int nMaximumBytes, int nBitsPerSample = -1, BOOL bAllowEatCrossFade = TRUE) = 0;

// gets the number of milliseconds that are empty in the buffer
// use this to slow down to real-time using GetSleepMS(...) for accelerated outputs
// otherwise, cross-fading, etc. won't work
// example: GetSleepMS(IMJOutputPluginCallbacks * pCallbacks) { return (pCallbacks->GetBufferEmptyMS() > 4000) ? 1000 : 10; }
virtual int GetBufferEmptyMS() = 0;
};

/*************************************************************************************
The output plugin base class
*************************************************************************************/
class IMJOutputPlugin
{
public:

// construction / destruction
IMJOutputPlugin() {}
virtual ~IMJOutputPlugin() {}

// open the plugin
virtual int Open(const CAudioFormat * pafOutput) = 0;

// main processing loop functions -- see the above architecture description
virtual int UpdateBuffer() = 0;
virtual int FillBuffers(IMJOutputPluginCallbacks * pCallbacks) = 0;
virtual int GetSleepMS(IMJOutputPluginCallbacks * pCallbacks) = 0;

// generic interface functions (see enumerations for details)
virtual int GetInformation(MJ_OUTPUT_PLUGIN_INFO_FIELDS nInfoID, LPTSTR pResult = NULL) = 0;
virtual int SetInformation(MJ_OUTPUT_PLUGIN_INFO_FIELDS nInfoID, LPCTSTR pValue) = 0;
virtual int DoCommand(MJ_OUTPUT_PLUGIN_COMMANDS nCommandID, int nParam1 = 0, int nParam2 = 0) = 0;
};

/*************************************************************************************
External functions that the plugin will export
*************************************************************************************/
typedef int (*proc_GetOutputPlugin)(int nIndex, IMJOutputPlugin ** ppPlugin);

Hopefully this is enough to get started.
Logged
Matt Ashland, JRiver Media Center

wombat66

  • World Citizen
  • ***
  • Posts: 152
Re: Audio Output plugin
« Reply #4 on: February 25, 2009, 03:29:34 pm »

...
muti-room audio system... networked digital media player in each room...synchronised to an audio stream (with timing information) sent over a LAN. ...


Oh Oh Oh! Pushing synchronized audio to networked players AND using MC as the front end!!
I've been wanting something like this for years.

Please tell us more about the "networked digital media player"(s). And post here often to share your progress!
Logged

muchadhesion

  • Recent member
  • *
  • Posts: 44
Re: Audio Output plugin
« Reply #5 on: February 26, 2009, 02:55:18 pm »

Matt,  Many thanks for this header file - it does the job nicely.

wombat66, I'll keep you updated.

regards,
Logged

muchadhesion

  • Recent member
  • *
  • Posts: 44
Re: Audio Output plugin
« Reply #6 on: March 03, 2009, 09:39:10 am »

Hi there,

Matt, that header file worked a treat. 

My output plugin is working for 2 channel audio sampled at 44.1KHz/48KHz, and a sample depth of 16bits.

I need to identify and adapt it to HD audio formats, ie 88Khz/96Khz or 192Khz 24bits per sample.

I'm guessing the information I need is in the CAudioFormat structure passed into the Open function?  The most immediatly important bit of info is the "bits per sample".

Any chance of seeing the CAudioFormat structure?

Thanks in advance...



Logged

Matt

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 41949
  • Shoes gone again!
Re: Audio Output plugin
« Reply #7 on: March 03, 2009, 09:47:48 am »

Glad to hear you got it working.

I emailed the audio format headers to jriver at morganism dot info.
Logged
Matt Ashland, JRiver Media Center

MerlinWerks

  • Regular Member
  • World Citizen
  • ***
  • Posts: 173
Re: Audio Output plugin
« Reply #8 on: April 07, 2009, 09:38:12 am »

Muchadhesion,

How is your project going? Do you have anything you can share with us yet?
Logged

muchadhesion

  • Recent member
  • *
  • Posts: 44
Re: Audio Output plugin
« Reply #9 on: April 14, 2009, 07:22:05 pm »

Hi,

> How is your project going? Do you have anything you can share with us yet?
Thanks for the interest. 

The first release of my project is available at http://getcatwalk.net/  It supports control of Linn's UPnP digital streaming players from within JRiver MC.

Currently, I've only implemented support for Linn's DS players, but I'll add other players over time.  Let me know if you have a favorite.

Multi-room streaming of audio directly from MC is not yet implemented - I have a couple of other features to complete first.
Logged

MerlinWerks

  • Regular Member
  • World Citizen
  • ***
  • Posts: 173
Re: Audio Output plugin
« Reply #10 on: April 15, 2009, 05:12:52 am »

Congratulations, I hope it does well for you. I 'd really like something like Catwalk for the Squeezebox Duet receiver.
Logged

)p(

  • Citizen of the Universe
  • *****
  • Posts: 579
Re: Audio Output plugin
« Reply #11 on: April 15, 2009, 05:50:10 am »

I 'd really like something like Catwalk for the Squeezebox Duet receiver.

I use Virtual Audio Cable that connects MC's sound output through the SC wavinput plugin directly to my SB3's each with its own zone assigned to it. Works perfectly.

peter
Logged

muchadhesion

  • Recent member
  • *
  • Posts: 44
Re: Audio Output plugin
« Reply #12 on: April 15, 2009, 08:05:10 am »

Quote
I use Virtual Audio Cable that connects MC's sound output through the SC wavinput plugin directly to my SB3's
"Virtual Audio Cable" sounds like a useful application.  Is this the one?
  http://software.muzychenko.net/eng/vac.html

Logged

)p(

  • Citizen of the Universe
  • *****
  • Posts: 579
Re: Audio Output plugin
« Reply #13 on: April 15, 2009, 09:46:04 am »

Yes it allows me to stream a bitperfect output from mc to sc. And with the mc write playing plugin I can even show what is playing on the sb's.

peter
Logged

MerlinWerks

  • Regular Member
  • World Citizen
  • ***
  • Posts: 173
Re: Audio Output plugin
« Reply #14 on: April 15, 2009, 03:32:53 pm »

I use Virtual Audio Cable that connects MC's sound output through the SC wavinput plugin directly to my SB3's each with its own zone assigned to it. Works perfectly.

peter

Yes, I believe we discussed this a bit on the SD forum. I've used that setup as well and while it did work well there was something that I did not like about it. I'll have to set it up again and see what it was. I think it had something to do with a delay, possibly due to buffering, when issuing play, stop, next etc.
Logged

)p(

  • Citizen of the Universe
  • *****
  • Posts: 579
Re: Audio Output plugin
« Reply #15 on: April 15, 2009, 03:42:59 pm »

Yes, I believe we discussed this a bit on the SD forum. I've used that setup as well and while it did work well there was something that I did not like about it. I'll have to set it up again and see what it was. I think it had something to do with a delay, possibly due to buffering, when issuing play, stop, next etc.


Yes the delay is very much depended on the server and the wavinput plugin settings. Fortunately on my setup the lag is <2 seconds in responding to play, stop, next etc. So no issue to me, but I have heard of >5 seconds in very bad cases.

peter
Logged

MerlinWerks

  • Regular Member
  • World Citizen
  • ***
  • Posts: 173
Re: Audio Output plugin
« Reply #16 on: April 16, 2009, 11:38:21 am »

Thanks Peter, what specific settings have you found that affect the amount of delay?

@muchadehesion, Do you have any experience with the Squeezebox products? There may be a market there for you  ;)
Logged

muchadhesion

  • Recent member
  • *
  • Posts: 44
Re: Audio Output plugin
« Reply #17 on: April 16, 2009, 12:22:11 pm »


Quote
@muchadehesion, Do you have any experience with the Squeezebox products? There may be a market there for you
Thanks.  I'll bump Squeezebox integration further up my Todo list.  (In the mean time, have you tried MC2Slim?)

To be honest I'm supprised Squeezebox support is not a core part of JRiver already.
Logged

MerlinWerks

  • Regular Member
  • World Citizen
  • ***
  • Posts: 173
Re: Audio Output plugin
« Reply #18 on: April 16, 2009, 01:10:38 pm »

Yes I've tried MC2Slim and do appreciate the author's efforts, but I could not get it working as smoothly as I would like.

MC native integration for the Squeezebox would be sweet  8)
It would be great to use the SB as if it were a standard sound device. This functionality would probably win A LOT of converts to MC as I think many of people desire an alternative to Squeeze Center for playback, plus you need something to rip and manage your library anyway...
Logged

)p(

  • Citizen of the Universe
  • *****
  • Posts: 579
Re: Audio Output plugin
« Reply #19 on: April 16, 2009, 03:30:21 pm »

Yes I've tried MC2Slim and do appreciate the author's efforts, but I could not get it working as smoothly as I would like.

MC native integration for the Squeezebox would be sweet  8)
It would be great to use the SB as if it were a standard sound device. This functionality would probably win A LOT of converts to MC as I think many of people desire an alternative to Squeeze Center for playback, plus you need something to rip and manage your library anyway...

Same here...MC2Slim was not stable enough for me.

I am not sure jrmc can do much more then the vac/wavinput plugin option does right now to make the sb act like a standard sound device. You always have to go through squeezecenter...as they are SLIM devices.

peter
Logged

)p(

  • Citizen of the Universe
  • *****
  • Posts: 579
Re: Audio Output plugin
« Reply #20 on: April 16, 2009, 03:33:21 pm »

Thanks Peter, what specific settings have you found that affect the amount of delay?


I use the default settings. But you can try the -m buffersize and -n number of buffers commandline options to influence the latency of wavin2cmd.exe.

peter
Logged

jeroen020

  • Regular Member
  • Recent member
  • *
  • Posts: 32
Re: Audio Output plugin
« Reply #21 on: May 16, 2009, 05:32:32 pm »

To be honest I'm supprised Squeezebox support is not a core part of JRiver already.

Indeed. I think proper support for a dedicated hardware music player for different rooms around the house that is well integrated into MC (zones, control etc) is sorely missed.

For me, Linn hardware is a bit over the top for kitchen, bedroom etc. I'd be more than happy to purchase Catwalk if it would be on devices like Squeezebox or Sonos. Another thought here though - how about Airport Express? Rogue Amoeba's Airfoil is software that you can use to pipe audio from any app on PC or Mac to any Airfoil speakers (Mac, PC, Airport Express, even Iphone/Ipod Touch can act as speakers). However Airfoil hijacks the audio of MC and all zones are output to the speakers you've selected.

Anyway, the Airport Express is a very affordable, compact device for multiroom audio and if there'd ever be a way to address a bunch of them as different zones in MC (like you can in Itunes) that would be very, very nice. So, Catwalk for Airport Express?
Logged

bspachman

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 888
Re: Audio Output plugin
« Reply #22 on: May 18, 2009, 08:21:29 am »

Anyway, the Airport Express is a very affordable, compact device for multiroom audio and if there'd ever be a way to address a bunch of them as different zones in MC (like you can in Itunes) that would be very, very nice. So, Catwalk for Airport Express?

+1 from me!

I already use Airfoil from Rogue Amoeba to stream from MC to a single Airport Express. Airfoil can address multiple AEs, but is limited to pulling audio from the first zone.

brad
Logged

wombat66

  • World Citizen
  • ***
  • Posts: 152
Re: Audio Output plugin
« Reply #23 on: October 25, 2009, 02:19:29 am »

Thanks.  I'll bump Squeezebox integration further up my Todo list.  (In the mean time, have you tried MC2Slim?)

To be honest I'm supprised Squeezebox support is not a core part of JRiver already.


Yes agreed. In the meantime, do you have any updates?
Logged

Guillaume06

  • Member
  • *
  • Posts: 1
Re: Audio Output plugin
« Reply #24 on: November 18, 2013, 12:25:26 pm »

Hello,

I'd be interested in writing an output plugin as well to support a digital amplifier I designed a while ago, as an alternative to writing an ASIO driver. The interface to my amplifier is USB but with a totally custom protocol.
I already wrote an output plugin for another application (XMPlay).

I copied the header file for the IMJOutputPlugin base class. I would need the AudioFormat.h header file too... and, is there any kind of code sample?

Another question: is there any means of forwarding the general volume setting to an output plugin or another kind of plugin? My amplifier has a built-in volume control...

Thanks a lot!!
Logged
Pages: [1]   Go Up