Getting error while subscribing to audio raw data

Hello Team,

I have been exploring on ways to access raw data streams using c# wrapper of windows meeting sdk.
I am able to start the meeting and start recording.
Q1) After startrawrecording i am trying to subscribe to audio raw events(onMixedAudioRawDataReceived, onOneWayAudioRawDataReceived) but i am getting error "SDKERR_NO_PERMISSION ". Do we need to enable any setting or do i need to get any permission for this. Please explain.
I have not been using any pro plans.

Help would be appreciated.

Thank You

does the SDK have host, co-host or recording permission?

This method needs to be called on the main thread, and after the user is in meeting.

Dear Chun,

Appreciate your reply.
I am starting the call as a host, and once the meeting is started, i am registering to callbacks for audio (onMixedAudioRawDataReceived) after which I am starting recording, which is happening successfully. But the callbacks which need to be fired are not working.

Not sure where it’s going wrong.

Thank you,

can you take a look at this?

I have an event listener onInMeeting which invokes when I’m get the INMEETING status.

I’ll then check if I have permissions (host / co-host/ permission) to start recording

If I do have permission, I’ll call attemptToStartRawRecording

  • In this method I will call meetingService->GetMeetingRecordingController();
  • Which I use to call StartRawRecording
  • If no error is thrown, I will call GetAudioRawdataHelper();
    -Which I use to call subscribe(audio_source);

What is audio_source?

It is an implementation of IZoomSDKAudioRawDataDelegate. My events(onMixedAudioRawDataReceived, onOneWayAudioRawDataReceived) are found within this implementation

1 Like

Dear Chun,
Awesome thanks for your code I will check the code and let you know if it worked or not.
FYI I am using c# wrapper and I have written wrappers on top of audio classes. I have attached them for your reference.

rawdata_audio_channel_dotnet_wrap.h

#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
#include "zoom_sdk_dotnet_wrap_def.h"
//#include "h/zoom_sdk_raw_data_helper_interface.h"
#include "wrap/sdk_wrap.h"

namespace ZOOM_SDK_DOTNET_WRAP {

	public enum class RawDataMemoryMode : int
	{
		RawDataMemoryMode_Stack,
		RawDataMemoryMode_Heap,
	};

	public ref class DotNetAudioRawData
	{
	public:
		bool CanAddRef() {
			return _data->CanAddRef();
		}
		bool AddRef() {
			return _data->AddRef(); 
		}
		int Release() {
			return _data->Release();
		}
		array<Byte>^ GetBuffer() {
			char* buf = _data->GetBuffer();
			unsigned int len = _data->GetBufferLen();

			array<Byte>^ byteArray = gcnew array< Byte >(len + 2);
			// convert native pointer to System::IntPtr with C-Style cast
			Marshal::Copy((IntPtr)buf, byteArray, 0, len);
			return byteArray;
		}
		UInt32 GetBufferLen() {
			return _data->GetBufferLen();
		}
		UInt32 GetSampleRate() {
			return _data->GetSampleRate();
		}
	private:
		AudioRawData* _data;

	public:
		DotNetAudioRawData(AudioRawData* data) {
			_data = data;
		}
	};

	public interface class IAudioRawDataReceiverDotNetWrap {
	public: 
		void onMixedAudioRawDataReceived(DotNetAudioRawData^ data_);
		void onOneWayAudioRawDataReceived(DotNetAudioRawData^ data_, UInt32 node_id);
	};

	public interface class IAudioRawDataChannelDotNetWrap {
	public: 
		SDKError Start(IAudioRawDataReceiverDotNetWrap^ receiver);
		SDKError Stop();
	};

	private ref class CAudioRawDataChannelDotNetWrap sealed : public IAudioRawDataChannelDotNetWrap {

	public:
		static property CAudioRawDataChannelDotNetWrap^ Instance
		{
			CAudioRawDataChannelDotNetWrap^ get() { return m_Instance; }
		}

		virtual SDKError Start(IAudioRawDataReceiverDotNetWrap^ receiver);
		virtual SDKError Stop();

    private: 
		CAudioRawDataChannelDotNetWrap();
		virtual ~CAudioRawDataChannelDotNetWrap();
		static CAudioRawDataChannelDotNetWrap^ m_Instance = gcnew CAudioRawDataChannelDotNetWrap;
	};
}

rawdata_audio_channel_dotnet_wrap.cpp

#include "stdafx.h"
#include "rawdata_audio_channel_dotnet_wrap.h"
#include "zoom_sdk_dotnet_wrap_util.h"
#include "wrap/sdk_wrap.h"

namespace ZOOM_SDK_DOTNET_WRAP {
	class AudioRawDataReceiver : public ZOOM_SDK_NAMESPACE::IZoomSDKAudioRawDataDelegate
	{
	public:
		virtual void onMixedAudioRawDataReceived(AudioRawData* data_) 
		{
			DotNetAudioRawData^ data_c = gcnew DotNetAudioRawData(data_);
			_dotnetWrap->onMixedAudioRawDataReceived(data_c);
		}
		virtual void onOneWayAudioRawDataReceived(AudioRawData* data_, unsigned int node_id)
		{
			DotNetAudioRawData^ data_c = gcnew DotNetAudioRawData(data_);
			_dotnetWrap->onOneWayAudioRawDataReceived(data_c, node_id);
		}

		AudioRawDataReceiver(IAudioRawDataReceiverDotNetWrap^ dotnetWrap) {
			_dotnetWrap = dotnetWrap;
		}

	private:
		gcroot<IAudioRawDataReceiverDotNetWrap^> _dotnetWrap;
	};

	CAudioRawDataChannelDotNetWrap::CAudioRawDataChannelDotNetWrap()
	{
	}

	CAudioRawDataChannelDotNetWrap::~CAudioRawDataChannelDotNetWrap()
	{
	}

	SDKError CAudioRawDataChannelDotNetWrap::Stop()
	{
		SDKError res = (SDKError)ZOOM_SDK_NAMESPACE::CSDKWrap::GetInst().GetAudioRawdataHelperWrap().unSubscribe();
		ZOOM_SDK_NAMESPACE::CSDKWrap::GetInst().GetAudioRawdataHelperWrap().Uninit();
		return res;
	}

	SDKError CAudioRawDataChannelDotNetWrap::Start(IAudioRawDataReceiverDotNetWrap^ receiver)
	{
		ZOOM_SDK_NAMESPACE::CSDKWrap::GetInst().GetAudioRawdataHelperWrap().Init();
		ZOOM_SDK_NAMESPACE::IZoomSDKAudioRawDataDelegate* receiver_c = new AudioRawDataReceiver(receiver);
		return (SDKError)ZOOM_SDK_NAMESPACE::CSDKWrap::GetInst().GetAudioRawdataHelperWrap().subscribe(receiver_c);
	}
}

Dear Chun,

After referring to your code I moved the subscribe to callbacks method after startrawrecording and now I am able to receive callbacks on the events (onMixedAudioRawDataReceived).

I am extremely thankful to you for unblocking me.

Thank you, and have a good day.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.