mirror of
https://github.com/musix-org/musix-oss
synced 2025-06-17 10:46:01 +00:00
Modules
This commit is contained in:
51
node_modules/node-opus/src/common.h
generated
vendored
Normal file
51
node_modules/node-opus/src/common.h
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
#if !defined( COMMON_H )
|
||||
#define COMMON_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRACING
|
||||
#if defined(TRACING)
|
||||
|
||||
#define TRACE(msg) printf(" TRACE: %s\n", msg)
|
||||
#define TRACE_S(msg, s) printf(" TRACE: %s : %s\n", msg, s)
|
||||
#define TRACE_I(msg, i) printf(" TRACE: %s : %d\n", msg, i)
|
||||
#define TRACE_CALL printf("-> TRACE: Call::%s\n", __FUNCTION__)
|
||||
#define TRACE_CALL_I(p1) printf("-> TRACE: Call::%s(%d)\n", __FUNCTION__, p1)
|
||||
#define TRACE_END printf("<- Call::%s\n", __FUNCTION__)
|
||||
|
||||
#else
|
||||
|
||||
#define TRACE(msg)
|
||||
#define TRACE_CALL
|
||||
#define TRACE_CALL_I(p1)
|
||||
#define TRACE_END
|
||||
|
||||
#endif
|
||||
|
||||
#define THROW_TYPE_ERROR( MSG ) \
|
||||
return Nan::ThrowTypeError( MSG );
|
||||
|
||||
#define CHECK_ARG(I, CHECK, DO_TRUE, DO_FALSE) \
|
||||
if ( info.Length() <= (I) || !info[I]->CHECK ) { DO_FALSE; } else { DO_TRUE; }
|
||||
|
||||
#define REQUIRE_ARG(I, CHECK) \
|
||||
CHECK_ARG( I, CHECK, , THROW_TYPE_ERROR("Argument " #I " must be an object") )
|
||||
|
||||
#define REQ_OBJ_ARG(I, VAR) \
|
||||
REQUIRE_ARG( I, IsObject() ) \
|
||||
Local<Object> VAR = Local<Object>::Cast( info[I] )
|
||||
|
||||
#define REQ_INT_ARG(I, VAR) \
|
||||
REQUIRE_ARG( I, IsNumber() ) \
|
||||
int VAR = Nan::To<int>( info[I] ).FromJust()
|
||||
|
||||
#define OPT_INT_ARG(I, VAR, DEFAULT) \
|
||||
int VAR; \
|
||||
CHECK_ARG( I, IsNumber(), VAR = Nan::To<int>( info[I] ).FromJust(), VAR = DEFAULT )
|
||||
|
||||
#define REQ_FUN_ARG(I, VAR) \
|
||||
if (info.Length() <= (I) || !info[I]->IsFunction()) \
|
||||
return Nan::ThrowTypeError("Argument " #I " must be a function"); \
|
||||
Local<Function> VAR = Local<Function>::Cast(info[I]);
|
||||
|
||||
#endif
|
250
node_modules/node-opus/src/node-opus.cc
generated
vendored
Normal file
250
node_modules/node-opus/src/node-opus.cc
generated
vendored
Normal file
@ -0,0 +1,250 @@
|
||||
|
||||
#include <v8.h>
|
||||
#include <node.h>
|
||||
#include <node_buffer.h>
|
||||
#include <node_object_wrap.h>
|
||||
#include "../deps/opus/include/opus.h"
|
||||
#include "common.h"
|
||||
#include <nan.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
using namespace node;
|
||||
using namespace v8;
|
||||
|
||||
#define FRAME_SIZE 960
|
||||
#define MAX_FRAME_SIZE 6*960
|
||||
#define MAX_PACKET_SIZE (3*1276)
|
||||
#define BITRATE 64000
|
||||
|
||||
const char* getDecodeError( int decodedSamples ) {
|
||||
switch( decodedSamples ) {
|
||||
case OPUS_BAD_ARG:
|
||||
return "One or more invalid/out of range arguments";
|
||||
case OPUS_BUFFER_TOO_SMALL:
|
||||
return "The mode struct passed is invalid";
|
||||
case OPUS_INTERNAL_ERROR:
|
||||
return "An internal error was detected";
|
||||
case OPUS_INVALID_PACKET:
|
||||
return "The compressed data passed is corrupted";
|
||||
case OPUS_UNIMPLEMENTED:
|
||||
return "Invalid/unsupported request number.";
|
||||
case OPUS_INVALID_STATE:
|
||||
return "An encoder or decoder structure is invalid or already freed.";
|
||||
case OPUS_ALLOC_FAIL:
|
||||
return "Memory allocation has failed";
|
||||
default:
|
||||
return "Unknown OPUS error";
|
||||
}
|
||||
}
|
||||
|
||||
class OpusEncoder : public ObjectWrap {
|
||||
private:
|
||||
OpusEncoder* encoder;
|
||||
OpusDecoder* decoder;
|
||||
|
||||
opus_int32 rate;
|
||||
int channels;
|
||||
int application;
|
||||
|
||||
unsigned char outOpus[ MAX_PACKET_SIZE ];
|
||||
opus_int16* outPcm;
|
||||
|
||||
protected:
|
||||
int EnsureEncoder() {
|
||||
if( encoder != NULL ) return 0;
|
||||
int error;
|
||||
encoder = opus_encoder_create( rate, channels, application, &error );
|
||||
return error;
|
||||
}
|
||||
int EnsureDecoder() {
|
||||
if( decoder != NULL ) return 0;
|
||||
int error;
|
||||
decoder = opus_decoder_create( rate, channels, &error );
|
||||
return error;
|
||||
}
|
||||
|
||||
public:
|
||||
OpusEncoder( opus_int32 rate, int channels, int application ):
|
||||
encoder( NULL ), decoder( NULL ),
|
||||
rate( rate ), channels( channels ), application( application ) {
|
||||
|
||||
outPcm = new opus_int16[ channels * MAX_FRAME_SIZE ];
|
||||
}
|
||||
|
||||
~OpusEncoder() {
|
||||
if( encoder != NULL )
|
||||
opus_encoder_destroy( encoder );
|
||||
if( decoder != NULL )
|
||||
opus_decoder_destroy( decoder );
|
||||
|
||||
encoder = NULL;
|
||||
decoder = NULL;
|
||||
|
||||
delete outPcm;
|
||||
outPcm = NULL;
|
||||
}
|
||||
|
||||
static void Encode( const Nan::FunctionCallbackInfo< v8::Value >& info ) {
|
||||
|
||||
// Unwrap the encoder.
|
||||
OpusEncoder* self = ObjectWrap::Unwrap<OpusEncoder>( info.This() );
|
||||
if( self->EnsureEncoder() != OPUS_OK ) {
|
||||
Nan::ThrowError( "Could not create encoder. Check the encoder parameters" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Read the function arguments
|
||||
REQ_OBJ_ARG( 0, pcmBuffer );
|
||||
OPT_INT_ARG( 1, maxPacketSize, MAX_PACKET_SIZE );
|
||||
|
||||
// Read the PCM data.
|
||||
char* pcmData = Buffer::Data(pcmBuffer);
|
||||
opus_int16* pcm = reinterpret_cast<opus_int16*>( pcmData );
|
||||
int frameSize = Buffer::Length( pcmBuffer ) / 2 / self->channels;
|
||||
|
||||
// Encode the samples.
|
||||
int compressedLength = opus_encode( self->encoder, pcm, frameSize, &(self->outOpus[0]), maxPacketSize );
|
||||
|
||||
// Create a new result buffer.
|
||||
Nan::MaybeLocal<Object> actualBuffer = Nan::CopyBuffer(reinterpret_cast<char*>(self->outOpus), compressedLength );
|
||||
if( !actualBuffer.IsEmpty() )
|
||||
info.GetReturnValue().Set( actualBuffer.ToLocalChecked() );
|
||||
}
|
||||
|
||||
static void Decode( const Nan::FunctionCallbackInfo< v8::Value >& info ) {
|
||||
|
||||
REQ_OBJ_ARG( 0, compressedBuffer );
|
||||
|
||||
// Read the compressed data.
|
||||
unsigned char* compressedData = (unsigned char*)Buffer::Data( compressedBuffer );
|
||||
size_t compressedDataLength = Buffer::Length( compressedBuffer );
|
||||
|
||||
OpusEncoder* self = ObjectWrap::Unwrap<OpusEncoder>( info.This() );
|
||||
if( self->EnsureDecoder() != OPUS_OK ) {
|
||||
Nan::ThrowError( "Could not create decoder. Check the decoder parameters" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Encode the samples.
|
||||
int decodedSamples = opus_decode(
|
||||
self->decoder,
|
||||
compressedData,
|
||||
compressedDataLength,
|
||||
&(self->outPcm[0]),
|
||||
MAX_FRAME_SIZE, /* decode_fex */ 0 );
|
||||
|
||||
if( decodedSamples < 0 ) {
|
||||
return Nan::ThrowTypeError( getDecodeError( decodedSamples ) );
|
||||
}
|
||||
|
||||
// Create a new result buffer.
|
||||
int decodedLength = decodedSamples * 2 * self->channels;
|
||||
Nan::MaybeLocal<Object> actualBuffer = Nan::CopyBuffer( reinterpret_cast<char*>(self->outPcm), decodedLength );
|
||||
if( !actualBuffer.IsEmpty() )
|
||||
info.GetReturnValue().Set( actualBuffer.ToLocalChecked() );
|
||||
}
|
||||
|
||||
static void ApplyEncoderCTL( const Nan::FunctionCallbackInfo< v8::Value >&info ) {
|
||||
|
||||
REQ_INT_ARG( 0, ctl );
|
||||
REQ_INT_ARG( 1, value );
|
||||
|
||||
OpusEncoder* self = ObjectWrap::Unwrap<OpusEncoder>( info.This() );
|
||||
if ( self->EnsureEncoder() != OPUS_OK ) {
|
||||
Nan::ThrowError( "Could not create encoder. Check the encoder parameters" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( opus_encoder_ctl( self->encoder, ctl, value ) != OPUS_OK )
|
||||
return Nan::ThrowError( "Invalid ctl/value" );
|
||||
}
|
||||
|
||||
static void ApplyDecoderCTL( const Nan::FunctionCallbackInfo< v8::Value >&info ) {
|
||||
|
||||
REQ_INT_ARG( 0, ctl );
|
||||
REQ_INT_ARG( 1, value );
|
||||
|
||||
OpusEncoder* self = ObjectWrap::Unwrap<OpusEncoder>( info.This() );
|
||||
if ( self->EnsureDecoder() != OPUS_OK ) {
|
||||
Nan::ThrowError( "Could not create decoder. Check the decoder parameters" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( opus_decoder_ctl( self->decoder, ctl, value ) != OPUS_OK)
|
||||
return Nan::ThrowError( "Invalid ctl/value" );
|
||||
}
|
||||
|
||||
static void SetBitrate( const Nan::FunctionCallbackInfo< v8::Value >& info ) {
|
||||
|
||||
REQ_INT_ARG( 0, bitrate );
|
||||
|
||||
OpusEncoder* self = ObjectWrap::Unwrap<OpusEncoder>( info.This() );
|
||||
if( self->EnsureEncoder() != OPUS_OK ) {
|
||||
Nan::ThrowError( "Could not create encoder. Check the encoder parameters" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( opus_encoder_ctl( self->encoder, OPUS_SET_BITRATE( bitrate ) ) != OPUS_OK )
|
||||
return Nan::ThrowError( "Invalid bitrate" );
|
||||
}
|
||||
|
||||
static void GetBitrate( const Nan::FunctionCallbackInfo< v8::Value >& info ) {
|
||||
|
||||
OpusEncoder* self = ObjectWrap::Unwrap<OpusEncoder>( info.This() );
|
||||
if( self->EnsureEncoder() != OPUS_OK ) {
|
||||
Nan::ThrowError( "Could not create encoder. Check the encoder parameters" );
|
||||
return;
|
||||
}
|
||||
|
||||
opus_int32 bitrate;
|
||||
opus_encoder_ctl( self->encoder, OPUS_GET_BITRATE( &bitrate ) );
|
||||
|
||||
info.GetReturnValue().Set( Nan::New<v8::Integer>( bitrate ) );
|
||||
}
|
||||
|
||||
static void New( const Nan::FunctionCallbackInfo< v8::Value >& info ) {
|
||||
|
||||
if( !info.IsConstructCall() ) {
|
||||
return Nan::ThrowTypeError("Use the new operator to construct the OpusEncoder.");
|
||||
}
|
||||
|
||||
OPT_INT_ARG( 0, rate, 48000 );
|
||||
OPT_INT_ARG( 1, channels, 1 );
|
||||
OPT_INT_ARG( 2, application, OPUS_APPLICATION_AUDIO );
|
||||
|
||||
OpusEncoder* encoder = new OpusEncoder( rate, channels, application );
|
||||
|
||||
encoder->Wrap( info.This() );
|
||||
info.GetReturnValue().Set( info.This() );
|
||||
}
|
||||
|
||||
static void Init( Local<Object> exports ) {
|
||||
Nan::HandleScope scope;
|
||||
|
||||
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>( New );
|
||||
tpl->SetClassName(Nan::New("OpusEncoder").ToLocalChecked());
|
||||
tpl->InstanceTemplate()->SetInternalFieldCount( 1 );
|
||||
|
||||
Nan::SetPrototypeMethod( tpl, "encode", Encode );
|
||||
Nan::SetPrototypeMethod( tpl, "decode", Decode );
|
||||
Nan::SetPrototypeMethod( tpl, "applyEncoderCTL", ApplyEncoderCTL );
|
||||
Nan::SetPrototypeMethod( tpl, "applyDecoderCTL", ApplyDecoderCTL );
|
||||
Nan::SetPrototypeMethod( tpl, "setBitrate", SetBitrate );
|
||||
Nan::SetPrototypeMethod( tpl, "getBitrate", GetBitrate );
|
||||
|
||||
//v8::Persistent<v8::FunctionTemplate> constructor;
|
||||
//Nan::AssignPersistent(constructor, tpl);
|
||||
Nan::Set( exports,
|
||||
Nan::New("OpusEncoder").ToLocalChecked(),
|
||||
Nan::GetFunction( tpl ).ToLocalChecked() );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void NodeInit( Local< Object > exports ) {
|
||||
OpusEncoder::Init( exports );
|
||||
}
|
||||
|
||||
NODE_MODULE(node_opus, NodeInit)
|
Reference in New Issue
Block a user