Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
411
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/_ptrlist.h
Normal file
411
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/_ptrlist.h
Normal file
|
@ -0,0 +1,411 @@
|
|||
//PORTABLE
|
||||
#ifndef _PTRLIST_H
|
||||
#define _PTRLIST_H
|
||||
|
||||
#define POS_LAST -1
|
||||
|
||||
// 1k each, leaving 16 bytes for MALLOC overhead
|
||||
#define PTRLIST_INCREMENT 252
|
||||
|
||||
template<class T>
|
||||
class PtrList
|
||||
{
|
||||
public:
|
||||
PtrList()
|
||||
{
|
||||
nitems = 0;
|
||||
nslots = 0;
|
||||
items = NULL;
|
||||
}
|
||||
|
||||
PtrList( PtrList<T> *other )
|
||||
{
|
||||
nitems = other->nitems;
|
||||
nslots = other->nslots;
|
||||
items = (T **)memdup( other->items, nslots * sizeof( T * ) );
|
||||
}
|
||||
|
||||
virtual ~PtrList()
|
||||
{
|
||||
if ( items )
|
||||
free( items );
|
||||
}
|
||||
|
||||
int getNumItems() { return nitems; };
|
||||
|
||||
T *enumItem( int n )
|
||||
{
|
||||
if ( items == NULL )
|
||||
return NULL;
|
||||
|
||||
if ( n < 0 )
|
||||
return NULL;
|
||||
|
||||
if ( n >= nitems )
|
||||
return NULL;
|
||||
|
||||
return items[ n ];
|
||||
}
|
||||
|
||||
T *operator[]( int n ) { return enumItem( n ); }
|
||||
|
||||
// this will safely return NULL if 0 items due to enumItems's boundscheck
|
||||
T *getFirst() { return enumItem( 0 ); }
|
||||
|
||||
T *getLast() { return enumItem( nitems - 1 ); }
|
||||
|
||||
virtual T *addItem( T *item, int pos = POS_LAST )
|
||||
{
|
||||
// ASSERTPR(item != NULL, "can't put NULLs into ptrlists");
|
||||
// ASSERT(nitems <= nslots);
|
||||
if ( items == NULL )
|
||||
{
|
||||
nslots = PTRLIST_INCREMENT;
|
||||
items = (T **)malloc( sizeof( T * ) * nslots );
|
||||
nitems = 0;
|
||||
}
|
||||
else if ( nslots == nitems )
|
||||
{ // time to expand
|
||||
T **newitems;
|
||||
nslots += PTRLIST_INCREMENT;
|
||||
newitems = (T **)malloc( sizeof( T * ) * nslots );
|
||||
memcpy( newitems, items, nitems * sizeof( T * ) );
|
||||
|
||||
if ( items )
|
||||
free( items );
|
||||
|
||||
items = newitems;
|
||||
}
|
||||
|
||||
_addToList( item );
|
||||
if ( pos != POS_LAST )
|
||||
moveItem( nitems - 1, pos );
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
// FG> avoid using this before i tested it more
|
||||
void moveItem( int from, int to )
|
||||
{
|
||||
if ( from == to )
|
||||
return;
|
||||
|
||||
T *ptr = items[ from ];
|
||||
|
||||
if ( nitems > from + 1 ) // if moving from the end, there is nothing to shift behind our src position
|
||||
//IMPORTANT note for future ports: This assumes MEMCPY accepts overlapping segments.
|
||||
memcpy( &items[ from ], &items[ from + 1 ], ( nitems - from ) * sizeof( T * ) );
|
||||
|
||||
if ( to > from )
|
||||
to--;
|
||||
|
||||
if ( nitems > to ) // if moving to the end, there is nothing to shift behind our target position
|
||||
memcpy( &items[ to + 1 ], &items[ to ], ( nitems - to - 1 ) * sizeof( T * ) );
|
||||
|
||||
items[ to ] = ptr;
|
||||
}
|
||||
|
||||
// deletes first instance of a pointer in list, returns how many are left
|
||||
int delItem( T *item )
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
if ( item == NULL || items == NULL || nitems <= 0 )
|
||||
return 0;
|
||||
|
||||
// count occurences of item in items, remember the first one
|
||||
T **p = items;
|
||||
int first = -1;
|
||||
|
||||
for ( int i = 0; i < nitems; i++, p++ )
|
||||
{
|
||||
if ( *p == item )
|
||||
{
|
||||
if ( c++ == 0 )
|
||||
first = i;
|
||||
}
|
||||
}
|
||||
|
||||
// if we found one, remove it
|
||||
if ( c > 0 )
|
||||
{
|
||||
delByPos( first ); // delByPos is faaast
|
||||
c--; // decrease count
|
||||
}
|
||||
|
||||
return c; // returns how many occurences of this item left
|
||||
}
|
||||
|
||||
// removes all instances of this pointer
|
||||
void delEveryItem( T *item ) { while ( delItem( item ) ); }
|
||||
|
||||
// removes pointer at specified pos
|
||||
void delByPos( int pos )
|
||||
{
|
||||
if ( pos < 0 || pos >= nitems )
|
||||
return; //JC
|
||||
|
||||
--nitems;
|
||||
if ( pos == nitems )
|
||||
return; // last one? nothing to copy over
|
||||
|
||||
memcpy( items + pos, items + ( pos + 1 ), sizeof( T * ) * ( nitems - pos ) ); // CT:not (nitems-(pos+1)) as nitems has been decremented earlier
|
||||
}
|
||||
|
||||
// removes last item, leaving pointer alone
|
||||
void removeLastItem()
|
||||
{
|
||||
if ( nitems == 0 || items == NULL )
|
||||
return;
|
||||
|
||||
nitems--; // hee hee
|
||||
}
|
||||
|
||||
// removes all entries, leaving pointers alone
|
||||
void removeAll()
|
||||
{
|
||||
if ( items )
|
||||
free( items );
|
||||
|
||||
items = NULL;
|
||||
nitems = 0;
|
||||
nslots = 0;
|
||||
}
|
||||
|
||||
// removes all entries, calling FREE on the pointers
|
||||
void freeAll()
|
||||
{
|
||||
for ( int i = 0; i < nitems; i++ ) //JC
|
||||
if ( items )
|
||||
free( items[ i ] );
|
||||
|
||||
removeAll();
|
||||
}
|
||||
|
||||
// removes all entries, calling delete on the pointers
|
||||
void deleteAll()
|
||||
{
|
||||
int i;
|
||||
if ( items == NULL || nitems <= 0 )
|
||||
return; //JC
|
||||
|
||||
for ( i = 0; i < nitems; i++ )
|
||||
{ //JC
|
||||
delete items[ i ];
|
||||
}
|
||||
|
||||
removeAll();
|
||||
}
|
||||
|
||||
virtual int haveItem( T *item )
|
||||
{// gross-ass linear search to see if we have it
|
||||
for ( int i = 0; i < nitems; i++ ) //JC
|
||||
if ( items[ i ] == item )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int searchItem( T *item )
|
||||
{ // gross-ass linear search to find index of item
|
||||
for ( int i = 0; i < getNumItems(); i++ )
|
||||
if ( items[ i ] == item )
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _addToList( T *item ) { items[ nitems++ ] = item; }
|
||||
|
||||
int nitems, nslots;
|
||||
T **items;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class PtrListBaseSorted : public PtrList<T>
|
||||
{
|
||||
public:
|
||||
virtual T *findItem( char *attrib )
|
||||
{
|
||||
#if 1
|
||||
if ( nitems == 0 || items == NULL )
|
||||
return NULL;
|
||||
|
||||
int bot = 0, top = nitems - 1;
|
||||
|
||||
for ( int c = 0; c < nitems + 16; c++ )
|
||||
{
|
||||
if ( bot > top )
|
||||
return NULL;
|
||||
|
||||
int mid = ( bot + top ) / 2;
|
||||
int r = compareAttrib( attrib, items[ mid ] );
|
||||
|
||||
if ( r == 0 )
|
||||
return items[ mid ];
|
||||
|
||||
if ( r < 0 )
|
||||
{
|
||||
top = mid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bot = mid + 1;
|
||||
}
|
||||
}
|
||||
// ASSERTPR(0, "binary search fucked up");
|
||||
#else
|
||||
for ( int i = 0; i < nitems; i++ )
|
||||
{
|
||||
if ( compareAttrib( attrib, items[ i ] ) == 0 )
|
||||
return items[ i ];
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
// comparator for searching -- override
|
||||
virtual int compareAttrib( char *attrib, T *item ) = 0;
|
||||
|
||||
// comparator for sorting -- override , -1 p1 < p2, 0 eq, 1 p1 > p2
|
||||
virtual int compareItem( T *p1, T *p2 ) = 0;
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
// try not to use this
|
||||
template<class T>
|
||||
class PtrListSortedInsertion : public PtrListBaseSorted<T>
|
||||
{
|
||||
protected:
|
||||
virtual void _addToList( T *item )
|
||||
{
|
||||
if ( nitems == 0 )
|
||||
{
|
||||
items[ nitems++ ] = item;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < nitems; i++ )
|
||||
{
|
||||
if ( compareItem( items[ i ], item ) == 1 )
|
||||
{
|
||||
T *tmp = items[ i ];
|
||||
items[ i ] = item;
|
||||
for ( int j = i + 1; j < nitems; j++ )
|
||||
{
|
||||
T *tmp2 = items[ j ];
|
||||
items[ j ] = tmp;
|
||||
tmp = tmp2;
|
||||
}
|
||||
|
||||
items[ nitems++ ] = tmp;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
items[ nitems++ ] = item;
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// a base class to defer sorting until lookup
|
||||
template<class T>
|
||||
class PtrListSorted : public PtrListBaseSorted<T>
|
||||
{
|
||||
public:
|
||||
PtrListSorted()
|
||||
{
|
||||
nitems = 0;
|
||||
nslots = 0;
|
||||
items = NULL;
|
||||
need_sorting = 0;
|
||||
}
|
||||
|
||||
virtual T *addItem( T *item )
|
||||
{
|
||||
need_sorting = 1;
|
||||
|
||||
return PtrList<T>::addItem( item );
|
||||
}
|
||||
|
||||
virtual T *findItem( char *attrib )
|
||||
{
|
||||
sort();
|
||||
|
||||
return PtrListBaseSorted<T>::findItem( attrib );
|
||||
}
|
||||
|
||||
int needSort() { return need_sorting; }
|
||||
|
||||
void sort()
|
||||
{
|
||||
if ( need_sorting )
|
||||
_sort();
|
||||
|
||||
need_sorting = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int need_sorting;
|
||||
|
||||
virtual void _sort() = 0;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class PtrListQuickSorted : public PtrListSorted<T>
|
||||
{
|
||||
public:
|
||||
virtual void _sort()
|
||||
{
|
||||
if ( items == NULL || nitems <= 1 )
|
||||
return;
|
||||
|
||||
Qsort( 0, nitems - 1 );
|
||||
}
|
||||
|
||||
void swap( int a, int b )
|
||||
{
|
||||
T *tmp = items[ a ];
|
||||
items[ a ] = items[ b ];
|
||||
items[ b ] = tmp;
|
||||
}
|
||||
|
||||
void Qsort( int lo0, int hi0 )
|
||||
{
|
||||
int lo = lo0, hi = hi0;
|
||||
if ( hi0 > lo0 )
|
||||
{
|
||||
T *mid = enumItem( ( lo0 + hi0 ) / 2 );
|
||||
while ( lo <= hi )
|
||||
{
|
||||
while ( ( lo < hi0 ) && ( compareItem( items[ lo ], mid ) < 0 ) )
|
||||
lo++;
|
||||
|
||||
while ( ( hi > lo0 ) && ( compareItem( items[ hi ], mid ) > 0 ) )
|
||||
hi--;
|
||||
|
||||
if ( lo <= hi )
|
||||
{
|
||||
swap( lo, hi );
|
||||
lo++;
|
||||
hi--;
|
||||
}
|
||||
}
|
||||
|
||||
if ( lo0 < hi )
|
||||
Qsort( lo0, hi );
|
||||
|
||||
if ( lo < hi0 )
|
||||
Qsort( lo, hi0 );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
95
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder.cpp
Normal file
95
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
#include <windows.h>
|
||||
#include "c_encoder.h"
|
||||
|
||||
C_ENCODER::C_ENCODER(int ExtInfoSize) {
|
||||
SetName("Untyped Encoder");
|
||||
ExtendedInfoPtr = (T_EncoderIOVals *)malloc(ExtInfoSize);
|
||||
ExtendedInfoSize = ExtInfoSize;
|
||||
}
|
||||
|
||||
C_ENCODER::~C_ENCODER() {
|
||||
Close();
|
||||
if(ExtendedInfoPtr && ExtendedInfoSize) free(ExtendedInfoPtr);
|
||||
ExtendedInfoSize = 0;
|
||||
}
|
||||
|
||||
void C_ENCODER::Close() {
|
||||
ClearAttribs();
|
||||
}
|
||||
|
||||
void C_ENCODER::SetName(const char *name) {
|
||||
if (name) lstrcpyn(Name, name, C_ENCODER_NameLen);
|
||||
}
|
||||
|
||||
char *C_ENCODER::GetName() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
void C_ENCODER::Reset() {
|
||||
}
|
||||
|
||||
void C_ENCODER::ChangeSettings(const void *Settings) {
|
||||
if(ExtendedInfoPtr && ExtendedInfoSize && Settings && Settings != ExtendedInfoPtr) {
|
||||
memcpy(ExtendedInfoPtr,Settings,ExtendedInfoSize);
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void C_ENCODER::Create(const T_EncoderIOVals *Settings, const char *name) {
|
||||
if(name) SetName(name);
|
||||
ChangeSettings(Settings);
|
||||
}
|
||||
|
||||
void C_ENCODER::ClearAttribs() {
|
||||
for(int i = AttribList.size()-1; i >= 0; i--) {
|
||||
T_ATTRIB *myAttrib = AttribList[i];
|
||||
if(myAttrib->OutputVals) delete[] myAttrib->OutputVals;
|
||||
}
|
||||
|
||||
//AttribList.deleteAll();
|
||||
for (auto attrib : AttribList)
|
||||
{
|
||||
delete attrib;
|
||||
}
|
||||
AttribList.clear();
|
||||
}
|
||||
|
||||
void C_ENCODER::AddAttrib(const char *Text, const void *Attributes) {
|
||||
T_ATTRIB *myAttrib = new T_ATTRIB;
|
||||
if(Text!=NULL) {
|
||||
::strncpy((char *)&myAttrib->Text,Text,sizeof(myAttrib->Text));
|
||||
} else {
|
||||
::strncpy((char *)&myAttrib->Text,"<This should never appear here...>",sizeof(myAttrib->Text));
|
||||
}
|
||||
myAttrib->OutputVals = (T_EncoderIOVals *)Attributes;
|
||||
AttribList.push_back(myAttrib);
|
||||
}
|
||||
|
||||
int C_ENCODER::Encode(const void *inputbuf, const unsigned int inputbufsize, void *outputbuf, const unsigned int outputbufsize, int *inputamtused) {
|
||||
if((inputbuf != NULL) && (outputbuf != NULL) && (inputbufsize != 0) && (outputbufsize != 0) && (inputamtused != NULL)) {
|
||||
int numitems = (inputbufsize > outputbufsize) ? outputbufsize : inputbufsize;
|
||||
memcpy(outputbuf,inputbuf,numitems);
|
||||
*inputamtused = numitems;
|
||||
return numitems;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int C_ENCODER::GetNumAttribs() {
|
||||
return AttribList.size();
|
||||
}
|
||||
|
||||
int C_ENCODER::EnumAttrib(const int val, T_ATTRIB *buf) {
|
||||
if((val < 0)||(val >= AttribList.size())||(buf==NULL)) return 0;
|
||||
T_ATTRIB *myattrib = AttribList[val];
|
||||
if(myattrib==NULL) return 0;
|
||||
::memcpy(buf,myattrib,sizeof(T_ATTRIB));
|
||||
return 1;
|
||||
}
|
||||
|
||||
char * C_ENCODER::GetContentType() {
|
||||
|
||||
//if(strcmp(this->GetName(), "MP3 Encoder") == 0)
|
||||
return "audio/mpeg";
|
||||
|
||||
}
|
53
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder.h
Normal file
53
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef __C_ENCODER_H__
|
||||
#define __C_ENCODER_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
#define C_ENCODER_NameLen 1024
|
||||
|
||||
struct T_EncoderIOVals {
|
||||
unsigned int output_bitRate;
|
||||
};
|
||||
|
||||
struct T_ATTRIB {
|
||||
char Text[256];
|
||||
void *OutputVals;
|
||||
};
|
||||
|
||||
class C_ENCODER {
|
||||
private:
|
||||
char Name[C_ENCODER_NameLen];
|
||||
std::vector<T_ATTRIB*> AttribList;
|
||||
protected:
|
||||
T_EncoderIOVals *ExtendedInfoPtr;
|
||||
int ExtendedInfoSize;
|
||||
void SetName(const char *name);
|
||||
void ClearAttribs();
|
||||
void AddAttrib(const char *Text, const void *Attributes);
|
||||
public:
|
||||
C_ENCODER(int ExtInfoSize = 0);
|
||||
virtual ~C_ENCODER();
|
||||
|
||||
virtual void ChangeSettings(const void *Settings);
|
||||
virtual void Create(const T_EncoderIOVals *Settings, const char *name = NULL);
|
||||
virtual void Close();
|
||||
virtual void Reset();
|
||||
virtual char *GetName();
|
||||
virtual void *GetExtInfo(int *ExtInfoSize = NULL) {
|
||||
if(ExtInfoSize != NULL) *ExtInfoSize = ExtendedInfoSize;
|
||||
return ExtendedInfoPtr;
|
||||
}
|
||||
|
||||
virtual char * GetContentType();
|
||||
virtual int Encode(const void *inputbuf, const unsigned int inputbufsize, void *outputbuf, const unsigned int outputbufsize, int *inputamtused); /* all values are in BYTES! */
|
||||
|
||||
virtual int GetNumAttribs();
|
||||
virtual int EnumAttrib(const int val, T_ATTRIB *buf);
|
||||
|
||||
virtual bool UseNsvConfig() { return false; }
|
||||
};
|
||||
|
||||
#endif /* !__C_ENCODER_H__ */
|
84
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_aacp.cpp
Normal file
84
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_aacp.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include "c_encoder_aacp.h"
|
||||
#include "../../utils.h"
|
||||
|
||||
HINSTANCE C_ENCODER_AACP::hEncoderInstance = NULL;
|
||||
|
||||
C_ENCODER_AACP::C_ENCODER_AACP(HWND winamp) : C_ENCODER_NSV(sizeof(T_ENCODER_AACP_INFO)) {
|
||||
SetName("AAC+ Encoder");
|
||||
winampWnd = winamp;
|
||||
ConfigAudio3 = NULL;
|
||||
if(hEncoderInstance == NULL) {
|
||||
wchar_t dir[MAX_PATH] = {0};
|
||||
snwprintf(dir, MAX_PATH, L"%s\\enc_aacplus.dll", GetPluginDirectoryW(winamp));
|
||||
hEncoderInstance = LoadLibraryW(dir);
|
||||
}
|
||||
|
||||
if(hEncoderInstance) {
|
||||
void * CreateAudio3=(void *)GetProcAddress(hEncoderInstance, "CreateAudio3");
|
||||
void * GetAudioTypes3=(void *)GetProcAddress(hEncoderInstance, "GetAudioTypes3");
|
||||
void * ConfigAudio3=(void *)GetProcAddress(hEncoderInstance, "ConfigAudio3");
|
||||
void * SetWinampHWND=(void *)GetProcAddress(hEncoderInstance, "SetWinampHWND");
|
||||
SetEncoder(CreateAudio3,GetAudioTypes3,ConfigAudio3,SetWinampHWND);
|
||||
}
|
||||
|
||||
T_ENCODER_AACP_INFO * EncInfo = (T_ENCODER_AACP_INFO *)ExtendedInfoPtr;
|
||||
EncInfo->output_bitRate = AACP_DEFAULT_OUTPUTBITRATE;
|
||||
EncInfo->output_channelmode = AACP_DEFAULT_OUTPUTCHANNELMODE;
|
||||
EncInfo->output_quality = AACP_DEFAULT_OUTPUTQUALITY;
|
||||
EncInfo->output_samplerate = AACP_DEFAULT_OUTPUTSAMPLERATE;
|
||||
EncInfo->output_v2enable = AACP_DEFAULT_OUTPUTV2ENABLE;
|
||||
}
|
||||
|
||||
C_ENCODER_AACP::~C_ENCODER_AACP() {
|
||||
C_ENCODER_NSV::~C_ENCODER_NSV();
|
||||
}
|
||||
|
||||
static int cacheVal=0;
|
||||
bool C_ENCODER_AACP::isPresent(HWND winamp) {
|
||||
if(cacheVal!=0 && hEncoderInstance!=0) return cacheVal==2;
|
||||
bool ret=false;
|
||||
wchar_t dir[MAX_PATH] = {0};
|
||||
snwprintf(dir, MAX_PATH, L"%s\\enc_aacplus.dll", GetPluginDirectoryW(winamp));
|
||||
FILE * f = _wfopen(dir, L"rb");
|
||||
if (f) {
|
||||
fseek(f,0,2);
|
||||
if(ftell(f) > 0) ret=true;
|
||||
fclose(f);
|
||||
}
|
||||
cacheVal=ret?2:1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void C_ENCODER_AACP::FillAttribs() {
|
||||
T_ENCODER_AACP_INFO &EncInfo = *(T_ENCODER_AACP_INFO *)ExtendedInfoPtr;
|
||||
T_ENCODER_AACP_INFO *attribs = new T_ENCODER_AACP_INFO;
|
||||
*attribs = EncInfo;
|
||||
AddAttrib("",attribs);
|
||||
}
|
||||
|
||||
void C_ENCODER_AACP::FillConfFile(char * conf_file, char * section) {
|
||||
if(!section) section="audio_aacplus";
|
||||
|
||||
T_ENCODER_AACP_INFO &EncInfo = *(T_ENCODER_AACP_INFO *)ExtendedInfoPtr;
|
||||
|
||||
WritePrivateProfileInt("samplerate", EncInfo.output_samplerate, section, conf_file);
|
||||
WritePrivateProfileInt("channelmode", EncInfo.output_channelmode, section, conf_file);
|
||||
WritePrivateProfileInt("bitrate", EncInfo.output_bitRate * 1000, section, conf_file);
|
||||
WritePrivateProfileInt("v2enable", EncInfo.output_v2enable, section, conf_file);
|
||||
}
|
||||
|
||||
void C_ENCODER_AACP::ReadConfFile(char * conf_file, char * section) {
|
||||
if(!section) section="audio_aacplus";
|
||||
|
||||
T_ENCODER_AACP_INFO &EncInfo = *(T_ENCODER_AACP_INFO *)ExtendedInfoPtr;
|
||||
T_ENCODER_AACP_INFO *attribs = new T_ENCODER_AACP_INFO;
|
||||
*attribs = EncInfo;
|
||||
|
||||
attribs->output_samplerate = GetPrivateProfileInt(section,"samplerate",AACP_DEFAULT_OUTPUTSAMPLERATE,conf_file);
|
||||
attribs->output_channelmode = GetPrivateProfileInt(section,"channelmode",AACP_DEFAULT_OUTPUTCHANNELMODE,conf_file);
|
||||
attribs->output_bitRate = GetPrivateProfileInt(section,"bitrate",AACP_DEFAULT_OUTPUTBITRATE,conf_file)/1000;
|
||||
attribs->output_quality = GetPrivateProfileInt(section,"quality",AACP_DEFAULT_OUTPUTQUALITY,conf_file);
|
||||
attribs->output_v2enable = GetPrivateProfileInt(section,"v2enable",AACP_DEFAULT_OUTPUTV2ENABLE,conf_file);
|
||||
|
||||
ChangeSettings(attribs);
|
||||
}
|
37
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_aacp.h
Normal file
37
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_aacp.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef __C_ENCODER_AACP_H__
|
||||
#define __C_ENCODER_AACP_H__
|
||||
|
||||
#include "c_encoder_nsv.h"
|
||||
|
||||
struct T_ENCODER_AACP_INFO : public T_ENCODER_NSV_INFO
|
||||
{
|
||||
unsigned int output_quality;
|
||||
unsigned int output_samplerate;
|
||||
unsigned int output_channelmode;
|
||||
unsigned int output_v2enable;
|
||||
};
|
||||
|
||||
#define AACP_DEFAULT_OUTPUTCHANNELMODE 4
|
||||
#define AACP_DEFAULT_OUTPUTBITRATE 48
|
||||
#define AACP_DEFAULT_OUTPUTQUALITY 2
|
||||
#define AACP_DEFAULT_OUTPUTSAMPLERATE 44100
|
||||
#define AACP_DEFAULT_OUTPUTV2ENABLE 1
|
||||
|
||||
class C_ENCODER_AACP : public C_ENCODER_NSV {
|
||||
private:
|
||||
HWND winamp;
|
||||
protected:
|
||||
virtual void FillAttribs();
|
||||
public:
|
||||
static HINSTANCE hEncoderInstance;
|
||||
C_ENCODER_AACP(HWND hwnd = 0);
|
||||
virtual ~C_ENCODER_AACP();
|
||||
static bool isPresent(HWND winamp);
|
||||
virtual void ReadConfFile(char * conf_file, char * section=NULL);
|
||||
virtual void FillConfFile(char * conf_file, char * section=NULL);
|
||||
static void Unload() { if(hEncoderInstance) FreeLibrary(hEncoderInstance); hEncoderInstance=0; }
|
||||
virtual char * GetContentType() { return "audio/aacp"; }
|
||||
virtual HINSTANCE GetEncoderInstance() { return hEncoderInstance; }
|
||||
};
|
||||
|
||||
#endif /* !__C_ENCODER_AACP_H__ */
|
|
@ -0,0 +1,80 @@
|
|||
#include "c_encoder_fhgaac.h"
|
||||
#include "../../utils.h"
|
||||
|
||||
HINSTANCE C_ENCODER_FHGAAC::hEncoderInstance = NULL;
|
||||
|
||||
C_ENCODER_FHGAAC::C_ENCODER_FHGAAC(HWND winamp) : C_ENCODER_NSV(sizeof(T_ENCODER_FHGAAC_INFO)) {
|
||||
SetName("Fraunhofer Encoder");
|
||||
winampWnd = winamp;
|
||||
ConfigAudio3 = NULL;
|
||||
if(hEncoderInstance == NULL) {
|
||||
wchar_t dir[MAX_PATH] = {0};
|
||||
snwprintf(dir, MAX_PATH, L"%s\\enc_fhgaac.dll", GetPluginDirectoryW(winamp));
|
||||
hEncoderInstance = LoadLibraryW(dir);
|
||||
}
|
||||
|
||||
if(hEncoderInstance) {
|
||||
void * CreateAudio3=(void *)GetProcAddress(hEncoderInstance, "CreateAudio3");
|
||||
void * GetAudioTypes3=(void *)GetProcAddress(hEncoderInstance, "GetAudioTypes3");
|
||||
void * ConfigAudio3=(void *)GetProcAddress(hEncoderInstance, "ConfigAudio3");
|
||||
void * SetWinampHWND=(void *)GetProcAddress(hEncoderInstance, "SetWinampHWND");
|
||||
SetEncoder(CreateAudio3,GetAudioTypes3,ConfigAudio3,SetWinampHWND,1);
|
||||
}
|
||||
|
||||
T_ENCODER_FHGAAC_INFO * EncInfo = (T_ENCODER_FHGAAC_INFO *)ExtendedInfoPtr;
|
||||
EncInfo->output_bitRate = FHGAAC_DEFAULT_OUTPUTBITRATE;
|
||||
EncInfo->output_profile = FHGAAC_DEFAULT_OUTPUTPROFILE;
|
||||
EncInfo->output_surround = FHGAAC_DEFAULT_OUTPUTSURROUND;
|
||||
}
|
||||
|
||||
C_ENCODER_FHGAAC::~C_ENCODER_FHGAAC() {
|
||||
C_ENCODER_NSV::~C_ENCODER_NSV();
|
||||
}
|
||||
|
||||
static int cacheVal=0;
|
||||
bool C_ENCODER_FHGAAC::isPresent(HWND winamp) {
|
||||
if(cacheVal!=0 && hEncoderInstance!=0) return cacheVal==2;
|
||||
bool ret=false;
|
||||
wchar_t dir[MAX_PATH] = {0};
|
||||
snwprintf(dir, MAX_PATH, L"%s\\enc_fhgaac.dll", GetPluginDirectoryW(winamp));
|
||||
FILE * f = _wfopen(dir, L"rb");
|
||||
if (f) {
|
||||
fseek(f,0,2);
|
||||
if(ftell(f) > 0) ret=true;
|
||||
fclose(f);
|
||||
}
|
||||
cacheVal=ret?2:1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void C_ENCODER_FHGAAC::FillAttribs() {
|
||||
T_ENCODER_FHGAAC_INFO &EncInfo = *(T_ENCODER_FHGAAC_INFO *)ExtendedInfoPtr;
|
||||
T_ENCODER_FHGAAC_INFO *attribs = new T_ENCODER_FHGAAC_INFO;
|
||||
*attribs = EncInfo;
|
||||
AddAttrib("",attribs);
|
||||
}
|
||||
|
||||
void C_ENCODER_FHGAAC::FillConfFile(char * conf_file, char * section) {
|
||||
if(!section) section="audio_adtsaac";
|
||||
|
||||
T_ENCODER_FHGAAC_INFO &EncInfo = *(T_ENCODER_FHGAAC_INFO *)ExtendedInfoPtr;
|
||||
|
||||
WritePrivateProfileInt("profile", EncInfo.output_profile, section, conf_file);
|
||||
WritePrivateProfileInt("bitrate", EncInfo.output_bitRate, section, conf_file);
|
||||
WritePrivateProfileInt("surround", EncInfo.output_surround, section, conf_file);
|
||||
WritePrivateProfileInt("shoutcast", 1, section, conf_file);
|
||||
}
|
||||
|
||||
void C_ENCODER_FHGAAC::ReadConfFile(char * conf_file, char * section) {
|
||||
if(!section) section="audio_adtsaac";
|
||||
|
||||
T_ENCODER_FHGAAC_INFO &EncInfo = *(T_ENCODER_FHGAAC_INFO *)ExtendedInfoPtr;
|
||||
T_ENCODER_FHGAAC_INFO *attribs = new T_ENCODER_FHGAAC_INFO;
|
||||
*attribs = EncInfo;
|
||||
|
||||
attribs->output_profile = GetPrivateProfileInt(section,"profile",FHGAAC_DEFAULT_OUTPUTPROFILE,conf_file);
|
||||
attribs->output_bitRate = GetPrivateProfileInt(section,"bitrate",FHGAAC_DEFAULT_OUTPUTBITRATE,conf_file);
|
||||
attribs->output_surround = GetPrivateProfileInt(section,"surround",FHGAAC_DEFAULT_OUTPUTSURROUND,conf_file);
|
||||
|
||||
ChangeSettings(attribs);
|
||||
}
|
33
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_fhgaac.h
Normal file
33
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_fhgaac.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef __C_ENCODER_FHGAAC_H__
|
||||
#define __C_ENCODER_FHGAAC_H__
|
||||
|
||||
#include "c_encoder_nsv.h"
|
||||
|
||||
struct T_ENCODER_FHGAAC_INFO : public T_ENCODER_NSV_INFO
|
||||
{
|
||||
unsigned int output_profile;
|
||||
unsigned int output_surround;
|
||||
};
|
||||
|
||||
#define FHGAAC_DEFAULT_OUTPUTBITRATE 48
|
||||
#define FHGAAC_DEFAULT_OUTPUTPROFILE 0 // automatic
|
||||
#define FHGAAC_DEFAULT_OUTPUTSURROUND 0
|
||||
|
||||
class C_ENCODER_FHGAAC : public C_ENCODER_NSV {
|
||||
private:
|
||||
HWND winamp;
|
||||
protected:
|
||||
virtual void FillAttribs();
|
||||
public:
|
||||
static HINSTANCE hEncoderInstance;
|
||||
C_ENCODER_FHGAAC(HWND hwnd = 0);
|
||||
virtual ~C_ENCODER_FHGAAC();
|
||||
static bool isPresent(HWND winamp);
|
||||
virtual void ReadConfFile(char * conf_file, char * section=NULL);
|
||||
virtual void FillConfFile(char * conf_file, char * section=NULL);
|
||||
static void Unload() { if(hEncoderInstance) FreeLibrary(hEncoderInstance); hEncoderInstance=0; }
|
||||
virtual char * GetContentType() { return "audio/aacp"; }
|
||||
virtual HINSTANCE GetEncoderInstance() { return hEncoderInstance; }
|
||||
};
|
||||
|
||||
#endif /* !__C_ENCODER_AACP_H__ */
|
105
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_mp3dll.cpp
Normal file
105
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_mp3dll.cpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
#include "c_encoder_mp3dll.h"
|
||||
#include "../../utils.h"
|
||||
|
||||
T_ENCODER_MP3_INFO formatlist[] = {
|
||||
{8, 22050, 1, 44100, 2, 8}, {16, 22050, 1, 44100, 2, 8}, {24, 22050, 1, 44100, 2, 8},
|
||||
{32, 22050, 1, 44100, 2, 8}, {40, 22050, 1, 44100, 2, 8}, {48, 22050, 1, 44100, 2, 8},
|
||||
{48, 44100, 1, 44100, 2, 8}, {56, 22050, 1, 44100, 2, 8}, {56, 44100, 1, 44100, 2, 8},
|
||||
{64, 44100, 1, 44100, 2, 8}, {80, 44100, 1, 44100, 2, 8}, {96, 44100, 1, 44100, 2, 8},
|
||||
{112, 44100, 1, 44100, 2, 8}, {128, 44100, 1, 44100, 2, 8}, {40, 22050, 2, 44100, 2, 8},
|
||||
{48, 22050, 2, 44100, 2, 8}, {56, 22050, 2, 44100, 2, 8}, {64, 22050, 2, 44100, 2, 8},
|
||||
{80, 22050, 2, 44100, 2, 8}, {56, 44100, 2, 44100, 2, 8}, {64, 44100, 2, 44100, 2, 8},
|
||||
{80, 44100, 2, 44100, 2, 8}, {96, 44100, 2, 44100, 2, 8}, {112, 44100, 2, 44100, 2, 8},
|
||||
{128, 44100, 2, 44100, 2, 8}, {160, 44100, 2, 44100, 2, 8}, {192, 44100, 2, 44100, 2, 8},
|
||||
{224, 44100, 2, 44100, 2, 8}, {256, 44100, 2, 44100, 2, 8}, {320, 44100, 2, 44100, 2, 8}
|
||||
};
|
||||
|
||||
static unsigned int formatlist_numEntries = sizeof(formatlist) / sizeof(T_ENCODER_MP3_INFO);
|
||||
|
||||
C_ENCODER_MP3::C_ENCODER_MP3(void *init, void *params, void *encode, void *finish) : C_ENCODER(sizeof(T_ENCODER_MP3_INFO)) { //sizeof(T_ENCODER_LAMEMP3_INFO)
|
||||
SetName("MP3 Encoder");
|
||||
T_ENCODER_MP3_INFO &EncInfo = *((T_ENCODER_MP3_INFO *)ExtendedInfoPtr);
|
||||
Handle = NULL;
|
||||
has_encoded = 0;
|
||||
EncInfo = formatlist[MP3_DEFAULT_ATTRIBNUM];
|
||||
hMutex = CreateMutex(NULL,TRUE,NULL);
|
||||
ReleaseMutex(hMutex);
|
||||
|
||||
lame_init = (lame_t (__cdecl *)(void))init;
|
||||
lame_init_params = (int (__cdecl *)(lame_global_flags *))params;
|
||||
lame_encode_buffer_interleaved = (int (__cdecl *)(lame_global_flags *, short int pcm[], int num_samples, char *mp3buffer, int mp3buffer_size))encode;
|
||||
lame_encode_flush = (int (__cdecl *)(lame_global_flags *, char *mp3buffer, int size))finish;
|
||||
}
|
||||
|
||||
C_ENCODER_MP3::~C_ENCODER_MP3() {
|
||||
WaitForSingleObject(hMutex,INFINITE);
|
||||
CloseHandle(hMutex);
|
||||
hMutex = NULL;
|
||||
C_ENCODER::~C_ENCODER();
|
||||
}
|
||||
|
||||
void C_ENCODER_MP3::Close() {
|
||||
C_ENCODER::Close();
|
||||
if(lame_init != NULL) {
|
||||
if(has_encoded && lame_encode_flush) {
|
||||
char buf[1024] = {0};
|
||||
lame_encode_flush(Handle,(char *)buf,sizeof(buf));
|
||||
}
|
||||
//delete Handle; caused crash !! needs looking at
|
||||
Handle = NULL;
|
||||
has_encoded = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void C_ENCODER_MP3::Reset() {
|
||||
T_ENCODER_MP3_INFO &EncInfo = *(T_ENCODER_MP3_INFO *)ExtendedInfoPtr;
|
||||
if(WaitForSingleObject(hMutex,INFINITE) != WAIT_OBJECT_0) return;
|
||||
Close();
|
||||
if(lame_init != NULL && EncInfo.input_sampleRate != 0 && EncInfo.input_numChannels != 0) {
|
||||
if(EncInfo.output_sampleRate != 0 && EncInfo.output_bitRate != 0 && Handle == NULL) {
|
||||
has_encoded = 0;
|
||||
Handle = lame_init();
|
||||
Handle->samplerate_in = EncInfo.input_sampleRate;
|
||||
Handle->num_channels = 2; // always process as 2 channels as it resolves issues with soundcard input in mono mode (which is padded to stereo)
|
||||
Handle->samplerate_out = EncInfo.output_sampleRate;
|
||||
Handle->mode = EncInfo.output_numChannels == 2 ? (MPEG_mode)0 : (MPEG_mode)3;
|
||||
Handle->brate = EncInfo.output_bitRate;
|
||||
Handle->VBR = vbr_off;
|
||||
Handle->write_lame_tag = 0;
|
||||
Handle->write_id3tag_automatic = 0;
|
||||
Handle->quality = EncInfo.QualityMode;
|
||||
if(Handle->quality < 0 || Handle->quality > 9) Handle->quality = 8;
|
||||
lame_init_params(Handle);
|
||||
} else {
|
||||
Handle = NULL;
|
||||
}
|
||||
for(unsigned int i = 0; i < formatlist_numEntries; i++) {
|
||||
char textbuf[256];
|
||||
formatlist[i].QualityMode = EncInfo.QualityMode;
|
||||
snprintf(textbuf,sizeof(textbuf),"%dkbps, %dHz, %s",formatlist[i].output_bitRate,formatlist[i].output_sampleRate,(formatlist[i].output_numChannels == 1 ? "Mono" : "Stereo"));
|
||||
T_ENCODER_MP3_INFO *attribs = new T_ENCODER_MP3_INFO;
|
||||
*attribs = formatlist[i];
|
||||
AddAttrib((char *)&textbuf,attribs);
|
||||
}
|
||||
}
|
||||
ReleaseMutex(hMutex);
|
||||
}
|
||||
|
||||
int C_ENCODER_MP3::Encode(const void *inputbuf, const unsigned int inputbufsize, void *outputbuf, const unsigned int outputbufsize, int *inputamtused) {
|
||||
if((inputbuf != NULL) && (outputbuf != NULL) && (inputbufsize != 0) && (outputbufsize != 0) && (inputamtused != NULL) && (Handle != NULL)) {
|
||||
if(WaitForSingleObject(hMutex,INFINITE) != WAIT_OBJECT_0) return 0;
|
||||
int outputamtused = 0;
|
||||
if(lame_encode_buffer_interleaved) {
|
||||
outputamtused = lame_encode_buffer_interleaved(Handle, (short *)inputbuf, inputbufsize / (2 * sizeof(short)), (char *)outputbuf, outputbufsize);
|
||||
if(outputamtused < 0) {
|
||||
ReleaseMutex(hMutex);
|
||||
return 0;
|
||||
}
|
||||
has_encoded = 1;
|
||||
}
|
||||
*inputamtused = inputbufsize;
|
||||
ReleaseMutex(hMutex);
|
||||
return outputamtused;
|
||||
}
|
||||
return 0;
|
||||
}
|
51
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_mp3dll.h
Normal file
51
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_mp3dll.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
#ifndef __C_ENCODER_MP3DLL_H__
|
||||
#define __C_ENCODER_MP3DLL_H__
|
||||
|
||||
#include "c_encoder.h"
|
||||
#include "../lame/include/lame.h"
|
||||
#include "../lame/libmp3lame/lame_global_flags.h"
|
||||
#include <windows.h>
|
||||
|
||||
// Defaults for this encoder
|
||||
#define MP3_DEFAULT_INPUTSAMPLERATE 44100
|
||||
#define MP3_DEFAULT_INPUTNUMCHANNELS 2
|
||||
#define MP3_DEFAULT_OUTPUTSAMPLERATE 44100
|
||||
#define MP3_DEFAULT_OUTPUTNUMCHANNELS 2
|
||||
#define MP3_DEFAULT_OUTPUTBITRATE 96
|
||||
|
||||
#define MP3_DEFAULT_ATTRIBNUM 22
|
||||
|
||||
struct T_ENCODER_MP3_INFO {
|
||||
int output_bitRate;
|
||||
int output_sampleRate;
|
||||
int output_numChannels;
|
||||
int input_sampleRate;
|
||||
int input_numChannels;
|
||||
int QualityMode;
|
||||
};
|
||||
|
||||
#define HBE_STREAM lame_global_flags *
|
||||
|
||||
class C_ENCODER_MP3 : public C_ENCODER {
|
||||
private:
|
||||
HANDLE hMutex;
|
||||
lame_t Handle;
|
||||
int has_encoded;
|
||||
protected:
|
||||
lame_t (*lame_init)(void);
|
||||
int (*lame_init_params)(lame_global_flags *);
|
||||
int (*lame_encode_buffer_interleaved)(lame_global_flags *, short int pcm[], int num_samples, char *mp3buffer, int mp3buffer_size);
|
||||
int (*lame_encode_flush)(lame_global_flags *, char *mp3buffer, int size);
|
||||
|
||||
public:
|
||||
C_ENCODER_MP3(void *init, void *params, void *encode, void *finish);
|
||||
virtual ~C_ENCODER_MP3();
|
||||
|
||||
virtual void Close();
|
||||
virtual void Reset();
|
||||
|
||||
virtual int Encode(const void *inputbuf, const unsigned int inputbufsize, void *outputbuf, const unsigned int outputbufsize, int *inputamtused); /* all values are in BYTES! */
|
||||
};
|
||||
|
||||
#endif /* !__C_ENCODER_MP3_H__ */
|
151
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_nsv.cpp
Normal file
151
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_nsv.cpp
Normal file
|
@ -0,0 +1,151 @@
|
|||
#include "c_encoder_nsv.h"
|
||||
#include "../../utils.h"
|
||||
#include <mmsystem.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static char * configfile;
|
||||
static unsigned int configfourcc;
|
||||
static HWND (*ConfigAudio3)(HWND intParent, HINSTANCE hinst, unsigned int outt, char *configfile);
|
||||
static HINSTANCE encoderDllInstance;
|
||||
static HWND cfgwnd=NULL;
|
||||
C_ENCODER_NSV::C_ENCODER_NSV(int ExtInfoSize) : C_ENCODER(ExtInfoSize) {
|
||||
hMutex = CreateMutex(NULL,TRUE,NULL);
|
||||
ReleaseMutex(hMutex);
|
||||
CreateAudio3 = NULL;
|
||||
ConfigAudio3 = NULL;
|
||||
GetAudioTypes3 = NULL;
|
||||
SetWinampHWND = NULL;
|
||||
SetConfigItem = NULL;
|
||||
GetConfigItem = NULL;
|
||||
winampWnd = NULL;
|
||||
fourcc = 0;
|
||||
encoder = NULL;
|
||||
}
|
||||
|
||||
void C_ENCODER_NSV::SetEncoder(void * CreateAudio3, void * GetAudioTypes3, void * ConfigAudio3, void * SetWinampHWND, int encoderNum) {
|
||||
*(void **)&(this->CreateAudio3) = CreateAudio3;
|
||||
*(void **)&(this->GetAudioTypes3) = GetAudioTypes3;
|
||||
*(void **)&(this->ConfigAudio3) = ConfigAudio3;
|
||||
*(void **)&(this->SetWinampHWND) = SetWinampHWND;
|
||||
|
||||
if(this->SetWinampHWND) {
|
||||
this->SetWinampHWND(winampWnd);
|
||||
}
|
||||
|
||||
if(this->GetAudioTypes3) {
|
||||
char name[C_ENCODER_NameLen];
|
||||
fourcc = this->GetAudioTypes3(encoderNum,name);
|
||||
}
|
||||
}
|
||||
|
||||
C_ENCODER_NSV::~C_ENCODER_NSV() {
|
||||
WaitForSingleObject(hMutex,INFINITE);
|
||||
|
||||
CloseHandle(hMutex);
|
||||
hMutex = NULL;
|
||||
C_ENCODER::~C_ENCODER();
|
||||
}
|
||||
|
||||
void C_ENCODER_NSV::Close() {
|
||||
C_ENCODER::Close();
|
||||
|
||||
if(encoder)
|
||||
delete encoder;
|
||||
encoder = NULL;
|
||||
}
|
||||
|
||||
void C_ENCODER_NSV::Reset() {
|
||||
if(WaitForSingleObject(hMutex,INFINITE) != WAIT_OBJECT_0) return;
|
||||
|
||||
Close();
|
||||
|
||||
if(!configfile) {
|
||||
configfile = GetSCIniFile(winampWnd);
|
||||
}
|
||||
|
||||
FillConfFile(configfile);
|
||||
|
||||
int nch = ((T_ENCODER_NSV_INFO*)ExtendedInfoPtr)->input_numChannels;
|
||||
int srate = ((T_ENCODER_NSV_INFO*)ExtendedInfoPtr)->input_sampleRate;
|
||||
if (CreateAudio3) {
|
||||
const int bps = 16; /* I think this is always the case. */
|
||||
encoder = CreateAudio3(nch,srate,bps,mmioFOURCC('P','C','M',' '),&fourcc,configfile);
|
||||
}
|
||||
else encoder = NULL;
|
||||
|
||||
/* I think (in that I havn't found anything to the contrary) that in the CreateAudio3 call, the encoder
|
||||
* reads all its settings from the conf_file and never touches them again. Hence, this is safe. Ahem.
|
||||
*/
|
||||
FillAttribs();
|
||||
ReleaseMutex(hMutex);
|
||||
}
|
||||
|
||||
int C_ENCODER_NSV::Encode(const void *inputbuf, const unsigned int inputbufsize, void *outputbuf, const unsigned int outputbufsize, int *inputamtused) {
|
||||
|
||||
if(WaitForSingleObject(hMutex,INFINITE) != WAIT_OBJECT_0) return 0;
|
||||
int ret=0;
|
||||
if(encoder && (inputbuf != NULL) && (outputbuf != NULL) && (inputbufsize != 0) && (outputbufsize != 0) && (inputamtused != NULL)) {
|
||||
ret = encoder->Encode(0,(void *)inputbuf,inputbufsize,inputamtused,outputbuf,outputbufsize);
|
||||
} else
|
||||
*inputamtused = inputbufsize; /* we havn't got the dll, so just say everything is ok? */
|
||||
|
||||
ReleaseMutex(hMutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK configure_dlgproc(HWND intDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) {
|
||||
|
||||
switch(uMsg) {
|
||||
case WM_INITDIALOG:
|
||||
if(configfourcc == mmioFOURCC('A','D','T','S')) {
|
||||
SetWindowTextW(intDlg, LocalisedString(IDS_FHGAAC_ENCODER, NULL, 0));
|
||||
}
|
||||
#ifdef USE_OGG
|
||||
else if(configfourcc == mmioFOURCC('O','G','G',' ')) {
|
||||
SetWindowTextW(intDlg, LocalisedString(IDS_OGG_CONFIG_TITLE, NULL, 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
cfgwnd=ConfigAudio3(intDlg, encoderDllInstance, configfourcc, configfile);
|
||||
|
||||
if(cfgwnd) {
|
||||
RECT r;
|
||||
GetWindowRect(GetDlgItem(intDlg,IDC_GO_HERE),&r);
|
||||
ScreenToClient(intDlg,(LPPOINT)&r);
|
||||
SetWindowPos(cfgwnd,NULL,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
|
||||
ShowWindow(cfgwnd,SW_SHOWNA);
|
||||
InvalidateRect(intDlg,NULL,FALSE);
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
if(LOWORD(wParam) == IDCANCEL) EndDialog(intDlg,0);
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
DestroyWindow(cfgwnd);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void C_ENCODER_NSV::Configure(HWND parent, HINSTANCE hDllInstance) {
|
||||
if(ConfigAudio3) {
|
||||
configfourcc = fourcc;
|
||||
if(!configfile) {
|
||||
configfile = GetSCIniFile(winampWnd);
|
||||
}
|
||||
|
||||
::ConfigAudio3 = this->ConfigAudio3;
|
||||
::encoderDllInstance = GetEncoderInstance();
|
||||
|
||||
if(WaitForSingleObject(hMutex,INFINITE) != WAIT_OBJECT_0) return;
|
||||
FillConfFile(configfile);
|
||||
ReleaseMutex(hMutex);
|
||||
|
||||
LocalisedDialogBox(hDllInstance,IDD_NSVCONFIG,parent,::configure_dlgproc);
|
||||
|
||||
if(WaitForSingleObject(hMutex,INFINITE) != WAIT_OBJECT_0) return;
|
||||
ReadConfFile(configfile);
|
||||
Reset();
|
||||
ReleaseMutex(hMutex);
|
||||
}
|
||||
}
|
76
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_nsv.h
Normal file
76
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_nsv.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* This is an abstract class to use the NSV style of encoder.
|
||||
*/
|
||||
|
||||
#ifndef __C_ENCODER_NSV_H__
|
||||
#define __C_ENCODER_NSV_H__
|
||||
|
||||
#include "c_encoder.h"
|
||||
#include "enc_if.h"
|
||||
#include <windows.h>
|
||||
#include <Shlobj.h>
|
||||
#include "../../Resource/resource.h"
|
||||
|
||||
struct T_ENCODER_NSV_INFO {
|
||||
unsigned int output_bitRate;
|
||||
unsigned int input_numChannels;
|
||||
unsigned int input_sampleRate;
|
||||
};
|
||||
|
||||
class C_ENCODER_NSV : public C_ENCODER {
|
||||
private:
|
||||
HANDLE hMutex;
|
||||
protected:
|
||||
// These are exported by enc_*.dll
|
||||
AudioCoder* (*CreateAudio3)(int nch, int srate, int bps, unsigned int srct, unsigned int *outt, char *configfile);
|
||||
int (*GetAudioTypes3)(int idx, char *desc);
|
||||
HWND (*ConfigAudio3)(HWND hwndParent, HINSTANCE hinst, unsigned int outt, char *configfile);
|
||||
void (*SetWinampHWND)(HWND hwnd);
|
||||
int (*SetConfigItem)(unsigned int outt, char *item, char *data, char *configfile);
|
||||
int (*GetConfigItem)(unsigned int outt, char *item, char *data, int len, char *configfile);
|
||||
/* We don't need the rest of the exports
|
||||
AudioCoder *(*FinishAudio3)(char *fn, AudioCoder *c);
|
||||
void (*PrepareToFinish)(const char *filename, AudioCoder *coder);
|
||||
*/
|
||||
|
||||
// our encoder (the AudioCoder class is defined in enc_if.h)
|
||||
AudioCoder* encoder;
|
||||
|
||||
// the type of the output format
|
||||
unsigned int fourcc;
|
||||
|
||||
// fill up the attribute list (using AddAttrib)
|
||||
virtual void FillAttribs()=0;
|
||||
|
||||
// child classes MUST call this in their constructor
|
||||
// note: encoderNum defaults to 0 which resolves to the first encoder
|
||||
// in most enc_* but make sure to set this correctly for others
|
||||
virtual void SetEncoder(void * CreateAudio3, void * GetAudioTypes3, void * ConfigAudio3, void * SetWinampHWND, int encoderNum=0);
|
||||
|
||||
// this is used in Configure()
|
||||
virtual HINSTANCE GetEncoderInstance()=0;
|
||||
|
||||
// this is used for esternal encoders so they can be correctly localised
|
||||
HWND winampWnd;
|
||||
|
||||
public:
|
||||
C_ENCODER_NSV(int ExtInfoSize = sizeof(T_ENCODER_NSV_INFO));
|
||||
virtual ~C_ENCODER_NSV();
|
||||
|
||||
virtual void Close();
|
||||
virtual void Reset();
|
||||
|
||||
virtual int Encode(const void *inputbuf, const unsigned int inputbufsize, void *outputbuf, const unsigned int outputbufsize, int *inputamtused); /* all values are in BYTES! */
|
||||
|
||||
// show configuration dialog
|
||||
virtual void Configure(HWND parent,HINSTANCE hDllInstance);
|
||||
|
||||
virtual bool UseNsvConfig() { return true; };
|
||||
|
||||
// populate the configuration file with current settings
|
||||
virtual void FillConfFile(char * conf_file, char * section=NULL)=0;
|
||||
|
||||
// read the configuration file and change current settings
|
||||
virtual void ReadConfFile(char * conf_file, char * section=NULL)=0;
|
||||
};
|
||||
|
||||
#endif /* !__C_ENCODER_NSV_H__ */
|
117
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_ogg.cpp
Normal file
117
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_ogg.cpp
Normal file
|
@ -0,0 +1,117 @@
|
|||
#include "c_encoder_ogg.h"
|
||||
#include "../../utils.h"
|
||||
|
||||
HINSTANCE C_ENCODER_OGG::hEncoderInstance = NULL;
|
||||
|
||||
C_ENCODER_OGG::C_ENCODER_OGG(HWND winamp) : C_ENCODER_NSV(sizeof(T_ENCODER_OGG_INFO)) {
|
||||
SetName("OGG Vorbis Encoder");
|
||||
winampWnd = winamp;
|
||||
ConfigAudio3 = NULL;
|
||||
if(hEncoderInstance == NULL) {
|
||||
wchar_t dir[MAX_PATH] = {0};
|
||||
snwprintf(dir, MAX_PATH, L"%s\\enc_vorbis.dll", GetPluginDirectoryW(winamp));
|
||||
hEncoderInstance = LoadLibraryW(dir);
|
||||
}
|
||||
|
||||
if(hEncoderInstance) {
|
||||
void * CreateAudio3=(void *)GetProcAddress(hEncoderInstance, "CreateAudio3");
|
||||
void * GetAudioTypes3=(void *)GetProcAddress(hEncoderInstance, "GetAudioTypes3");
|
||||
void * ConfigAudio3=(void *)GetProcAddress(hEncoderInstance, "ConfigAudio3");
|
||||
void * SetWinampHWND=(void *)GetProcAddress(hEncoderInstance, "SetWinampHWND");
|
||||
SetEncoder(CreateAudio3,GetAudioTypes3,ConfigAudio3,SetWinampHWND);
|
||||
}
|
||||
|
||||
T_ENCODER_OGG_INFO * EncInfo = (T_ENCODER_OGG_INFO *)ExtendedInfoPtr;
|
||||
EncInfo->output_bitRate = OGG_DEFAULT_OUTPUTBITRATE;
|
||||
EncInfo->output_channelmode = OGG_DEFAULT_OUTPUTMODE;
|
||||
EncInfo->output_samplerate = OGG_DEFAULT_OUTPUTSAMPLERATE;
|
||||
}
|
||||
|
||||
C_ENCODER_OGG::~C_ENCODER_OGG() {
|
||||
C_ENCODER_NSV::~C_ENCODER_NSV();
|
||||
}
|
||||
|
||||
static int cacheVal=0;
|
||||
bool C_ENCODER_OGG::isPresent(HWND winamp) {
|
||||
if(cacheVal!=0 && hEncoderInstance!=0) return cacheVal==2;
|
||||
bool ret=false;
|
||||
wchar_t dir[MAX_PATH] = {0};
|
||||
snwprintf(dir, MAX_PATH, L"%s\\enc_vorbis.dll", GetPluginDirectoryW(winamp));
|
||||
FILE * f = _wfopen(dir, L"rb");
|
||||
if (f) {
|
||||
fseek(f,0,2);
|
||||
if(ftell(f) > 0) ret=true;
|
||||
fclose(f);
|
||||
}
|
||||
cacheVal=ret?2:1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void C_ENCODER_OGG::FillAttribs() {
|
||||
T_ENCODER_OGG_INFO &EncInfo = *(T_ENCODER_OGG_INFO *)ExtendedInfoPtr;
|
||||
T_ENCODER_OGG_INFO *attribs = new T_ENCODER_OGG_INFO;
|
||||
*attribs = EncInfo;
|
||||
AddAttrib("",attribs);
|
||||
}
|
||||
|
||||
void C_ENCODER_OGG::FillConfFile(char * conf_file, char * section) {
|
||||
if(!section) section="audio_ogg";
|
||||
|
||||
T_ENCODER_OGG_INFO &EncInfo = *(T_ENCODER_OGG_INFO *)ExtendedInfoPtr;
|
||||
configtype * cfg = new configtype;
|
||||
cfg->cfg_abr_use_max=0;
|
||||
cfg->cfg_abr_use_min=0;
|
||||
cfg->cfg_mode=0; //VBR
|
||||
cfg->cfg_vbrquality=EncInfo.output_quality;
|
||||
cfg->cfg_abr_nominal=EncInfo.output_bitRate;
|
||||
cfg->cfg_abr_max=EncInfo.output_bitRate;
|
||||
cfg->cfg_abr_min=EncInfo.output_bitRate;
|
||||
|
||||
if (conf_file) WritePrivateProfileStruct(section,"conf",cfg,sizeof(configtype),conf_file);
|
||||
}
|
||||
int setBitrate(float ql)
|
||||
{
|
||||
int br = 64;
|
||||
//ql = ql*10;
|
||||
// jkey: this is a pain in the ass,but the only
|
||||
// way i can figure out how to get the bitrate
|
||||
// outside of enc_vorbis.
|
||||
// Also quality enforcement is needed to prevent the
|
||||
// yp filling up with non standard bitrate streams.
|
||||
// although this is vbr and will be variable bitrate anyway.
|
||||
if(ql == 10 || (ql < 10 && ql > 9.5)){br=500;ql = 10.0f; return br;}
|
||||
if(ql == 9.0f || (ql < 10.0f && ql > 9.0f)){br=320;ql = 9.0f;return br;}
|
||||
if(ql == 8.0f || (ql < 9.0f && ql > 8.0f)){br=256;ql = 8.0f;return br;}
|
||||
if(ql == 7.0f || (ql < 8.0f && ql > 7.0f)){br=224;ql = 7.0f;return br;}
|
||||
if(ql == 6.0f || (ql < 7.0f && ql > 6.0f)){br=192;ql = 6.0f;return br;}
|
||||
if(ql == 5.0f || (ql < 6.0f && ql > 5.0f)){br=160;ql = 5.0f;return br;}
|
||||
if(ql == 4.0f || (ql < 5.0f && ql > 4.0f)){br=128;ql = 4.0f;return br;}
|
||||
if(ql == 3.0f || (ql < 4.0f && ql > 3.0f)){br=112;ql = 3.0f;return br;}
|
||||
if(ql == 2.0f || (ql < 3.0f && ql > 2.0f)){br=96;ql = 2.0f;return br;}
|
||||
if(ql == 1.0f || (ql < 2.0f && ql > 1.0f)){br=80;ql = 1.0f;return br;}
|
||||
if(ql == 0.0f || (ql < 1.0f && ql > 0.0f)){ br=64;ql = 0.0f;return br;}
|
||||
if(ql == -0.5f || (ql < 0.0f && ql > -0.5f)){br=56;ql = -0.5f;return br;}
|
||||
if(ql == -1.0f || ql < -0.5f){br=48;ql = -1.0f;return br;}
|
||||
return br;
|
||||
}
|
||||
void C_ENCODER_OGG::ReadConfFile(char * conf_file, char * section) {
|
||||
if(!section) section="audio_ogg";
|
||||
T_ENCODER_OGG_INFO &EncInfo = *(T_ENCODER_OGG_INFO *)ExtendedInfoPtr;
|
||||
T_ENCODER_OGG_INFO *attribs = new T_ENCODER_OGG_INFO;
|
||||
*attribs = EncInfo;
|
||||
configtype * cfg = new configtype;
|
||||
cfg->cfg_abr_use_max=0;
|
||||
cfg->cfg_abr_use_min=0;
|
||||
cfg->cfg_mode=0; //VBR
|
||||
cfg->cfg_vbrquality=0.0f;
|
||||
cfg->cfg_abr_nominal=64;
|
||||
cfg->cfg_abr_max=352;
|
||||
cfg->cfg_abr_min=32;
|
||||
|
||||
if (conf_file) GetPrivateProfileStruct(section,"conf",cfg,sizeof(configtype),conf_file);
|
||||
attribs->output_samplerate = OGG_DEFAULT_OUTPUTSAMPLERATE;
|
||||
attribs->output_channelmode = cfg->cfg_mode;
|
||||
attribs->output_quality = cfg->cfg_vbrquality;
|
||||
attribs->output_bitRate = setBitrate(attribs->output_quality*10);
|
||||
ChangeSettings(attribs);
|
||||
}
|
47
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_ogg.h
Normal file
47
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/c_encoder_ogg.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef __C_ENCODER_OGG_H__
|
||||
#define __C_ENCODER_OGG_H__
|
||||
|
||||
#include "c_encoder_nsv.h"
|
||||
//#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool cfg_abr_use_max,cfg_abr_use_min;
|
||||
UINT cfg_mode;
|
||||
|
||||
float cfg_vbrquality;
|
||||
UINT cfg_abr_nominal;
|
||||
UINT cfg_abr_max;
|
||||
UINT cfg_abr_min;
|
||||
} configtype;
|
||||
|
||||
struct T_ENCODER_OGG_INFO : public T_ENCODER_NSV_INFO
|
||||
{
|
||||
float output_quality;
|
||||
unsigned int output_samplerate;
|
||||
unsigned int output_channelmode;
|
||||
};
|
||||
|
||||
#define OGG_DEFAULT_OUTPUTMODE 0
|
||||
#define OGG_DEFAULT_OUTPUTBITRATE 192
|
||||
#define OGG_DEFAULT_OUTPUTSAMPLERATE 44100
|
||||
#define OGG_DEFAULT_OUTPUTQUALITY 2.0f
|
||||
|
||||
class C_ENCODER_OGG : public C_ENCODER_NSV {
|
||||
private:
|
||||
HWND winamp;
|
||||
protected:
|
||||
virtual void FillAttribs();
|
||||
public:
|
||||
static HINSTANCE hEncoderInstance;
|
||||
C_ENCODER_OGG(HWND hwnd = 0);
|
||||
virtual ~C_ENCODER_OGG();
|
||||
static bool isPresent(HWND winamp);
|
||||
virtual void ReadConfFile(char * conf_file, char * section=NULL);
|
||||
virtual void FillConfFile(char * conf_file, char * section=NULL);
|
||||
static void Unload() { if(hEncoderInstance) FreeLibrary(hEncoderInstance); hEncoderInstance=0; }
|
||||
virtual char * GetContentType() { return "audio/ogg"; }
|
||||
virtual HINSTANCE GetEncoderInstance() { return hEncoderInstance; }
|
||||
};
|
||||
|
||||
#endif /* !__C_ENCODER_OGG_H__ */
|
44
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/enc_if.h
Normal file
44
Src/Plugins/DSP/dsp_sc/sc2srclib/Encoders/enc_if.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
** enc_if.h - common encoder interface
|
||||
**
|
||||
** Copyright (C) 2001-2003 Nullsoft, Inc.
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied warranty.
|
||||
** In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
** applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the
|
||||
** original software. If you use this software in a product, an acknowledgment in the product
|
||||
** documentation would be appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as
|
||||
** being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _NSV_ENC_IF_H_
|
||||
#define _NSV_ENC_IF_H_
|
||||
class VideoCoder
|
||||
{
|
||||
public:
|
||||
VideoCoder() { }
|
||||
virtual int Encode(void *in, void *out, int *iskf)=0; // returns bytes in out
|
||||
virtual ~VideoCoder() { };
|
||||
};
|
||||
|
||||
class AudioCoder
|
||||
{
|
||||
public:
|
||||
AudioCoder() { }
|
||||
virtual int Encode(int framepos, void *in, int in_avail, int *in_used, void *out, int out_avail)=0; //returns bytes in out
|
||||
virtual ~AudioCoder() { };
|
||||
};
|
||||
|
||||
// unsigned int GetAudioTypes3(int idx, char *desc);
|
||||
// unsigned int GetVideoTypes3(int idx, char *desc);
|
||||
// AudioCoder *CreateAudio3(int nch, int srate, int bps, unsigned int srct, unsigned int *outt, char *configfile);
|
||||
// VideoCoder *CreateVideo3(int w, int h, double frt, unsigned int pixt, unsigned int *outt, char *configfile);
|
||||
// HWND ConfigAudio3(HWND hwndParent, HINSTANCE hinst, unsigned int outt, char *configfile);
|
||||
// HWND ConfigVideo3(HWND hwndParent, HINSTANCE hinst, unsigned int outt, char *configfile);
|
||||
|
||||
#endif //_NSV_ENC_IF_H_
|
254
Src/Plugins/DSP/dsp_sc/sc2srclib/Include/c_jobmanager.h
Normal file
254
Src/Plugins/DSP/dsp_sc/sc2srclib/Include/c_jobmanager.h
Normal file
|
@ -0,0 +1,254 @@
|
|||
#ifndef __C_JOBMANAGER_H__
|
||||
#define __C_JOBMANAGER_H__
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <wtypes.h>
|
||||
#include <winbase.h> // for mutex support
|
||||
#define T_MUTEX HANDLE
|
||||
#else // _WIN32
|
||||
#error "This won't compile under anything other than windows since I haven't implemented mutexing on anything else"
|
||||
#endif // _WIN32
|
||||
|
||||
template<class T> class C_JOBMANAGER {
|
||||
public:
|
||||
typedef int (*T_JOBHANDLER)(int state, int last_state, T *userData);
|
||||
private:
|
||||
struct T_JOB {
|
||||
int state;
|
||||
int last_state;
|
||||
int suspended;
|
||||
T *userData;
|
||||
};
|
||||
struct T_HANDLER {
|
||||
int state;
|
||||
int last_state;
|
||||
T_JOBHANDLER jobHandler;
|
||||
};
|
||||
std::vector<T_JOB*> JobList;
|
||||
std::vector<T_HANDLER*> HandlerList;
|
||||
T_MUTEX mutex;
|
||||
|
||||
protected:
|
||||
int waitForMutex() {
|
||||
#ifdef _WIN32
|
||||
if(WaitForSingleObject(mutex,INFINITE) == WAIT_OBJECT_0) return 1;
|
||||
#else // _WIN32
|
||||
// insert mutex magic here
|
||||
#endif // _WIN32
|
||||
return 0;
|
||||
}
|
||||
|
||||
void releaseMutex() {
|
||||
#ifdef _WIN32
|
||||
ReleaseMutex(mutex);
|
||||
#else // _WIN32
|
||||
// insert mutex magic here
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
public:
|
||||
C_JOBMANAGER() {
|
||||
#ifdef _WIN32
|
||||
mutex = CreateMutex(NULL,TRUE,NULL);
|
||||
ReleaseMutex(mutex);
|
||||
#else // _WIN32
|
||||
// insert mutex magic here
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
virtual ~C_JOBMANAGER() {
|
||||
waitForMutex();
|
||||
#ifdef _WIN32
|
||||
CloseHandle(mutex);
|
||||
mutex = NULL;
|
||||
#else // _WIN32
|
||||
// insert mutex magic here
|
||||
#endif // _WIN32
|
||||
|
||||
//JobList.deleteAll();
|
||||
for (auto job : JobList)
|
||||
{
|
||||
delete job;
|
||||
}
|
||||
JobList.clear();
|
||||
|
||||
//HandlerList.deleteAll();
|
||||
for (auto handler : HandlerList)
|
||||
{
|
||||
delete handler;
|
||||
}
|
||||
HandlerList.clear();
|
||||
}
|
||||
|
||||
T *operator[](int job) {
|
||||
if(!waitForMutex()) return NULL;
|
||||
T_JOB *j = JobList[job];
|
||||
T *val = NULL;
|
||||
if(j) val = j->userData;
|
||||
releaseMutex();
|
||||
return val;
|
||||
}
|
||||
|
||||
virtual int AddJob(int state, T *userData, int suspended = 0, int isUserUnique = 1) {
|
||||
if(!waitForMutex()) return -1;
|
||||
int n = JobList.size();
|
||||
if(isUserUnique && n) {
|
||||
for(int i = n-1; i >= 0; i--) {
|
||||
T_JOB *item = JobList[i];
|
||||
if(item) {
|
||||
if(item->userData == userData) {
|
||||
releaseMutex();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
T_JOB *job = new T_JOB;
|
||||
job->last_state = OUT_DISCONNECTED;
|
||||
job->state = state;
|
||||
job->suspended = suspended;
|
||||
job->userData = userData;
|
||||
JobList.push_back(job);
|
||||
releaseMutex();
|
||||
return n;
|
||||
}
|
||||
|
||||
virtual int GetJobState(int job) {
|
||||
int retval = -1;
|
||||
if(waitForMutex()) {
|
||||
int n = JobList.size();
|
||||
if(job < n && job >= 0) retval = JobList[job]->state;
|
||||
releaseMutex();
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
virtual void SetJobState(int job, int state) {
|
||||
if(!waitForMutex()) return;
|
||||
int n = JobList.size();
|
||||
if(job < n && job >= 0) JobList[job]->state = state;
|
||||
releaseMutex();
|
||||
}
|
||||
|
||||
virtual void SuspendJob(int job, int suspended) {
|
||||
if(!waitForMutex()) return;
|
||||
int n = JobList.size();
|
||||
if(job < n && job >= 0) JobList[job]->suspended = suspended;
|
||||
releaseMutex();
|
||||
}
|
||||
|
||||
virtual void DelJob(int job) {
|
||||
if(!waitForMutex()) return;
|
||||
int n = JobList.size();
|
||||
if(job < n && job >= 0) {
|
||||
delete JobList[job];
|
||||
JobList.erase(JobList.begin() + job);
|
||||
}
|
||||
releaseMutex();
|
||||
}
|
||||
|
||||
virtual void ClearJobs() {
|
||||
if(!waitForMutex())
|
||||
return;
|
||||
|
||||
//JobList.deleteAll();
|
||||
for (auto job : JobList)
|
||||
{
|
||||
delete job;
|
||||
}
|
||||
JobList.clear();
|
||||
|
||||
releaseMutex();
|
||||
}
|
||||
|
||||
virtual void AddHandler(int state, T_JOBHANDLER jobHandler) {
|
||||
if(!waitForMutex()) return;
|
||||
int n = HandlerList.size();
|
||||
for(int i = n-1; i >= 0; i--) {
|
||||
T_HANDLER *item = HandlerList[i];
|
||||
if(item) {
|
||||
if(item->state == state) {
|
||||
releaseMutex();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
T_HANDLER *handler = new T_HANDLER;
|
||||
handler->state = state;
|
||||
handler->jobHandler = jobHandler;
|
||||
HandlerList.push_back(handler);
|
||||
releaseMutex();
|
||||
}
|
||||
|
||||
virtual void DelHandler(int state) {
|
||||
if(!waitForMutex()) return;
|
||||
int n = HandlerList.size();
|
||||
for(int i = n-1; i >= 0; i--) {
|
||||
T_HANDLER *item = HandlerList[i];
|
||||
if(item) {
|
||||
if(item->state == state) {
|
||||
delete HandlerList[i];
|
||||
HandlerList.erase(HandlerList.begin() + i);
|
||||
releaseMutex();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
releaseMutex();
|
||||
}
|
||||
|
||||
virtual void ClearHandlers() {
|
||||
if(!waitForMutex())
|
||||
return;
|
||||
|
||||
//HandlerList.deleteAll();
|
||||
for (auto handler : HandlerList)
|
||||
{
|
||||
delete handler;
|
||||
}
|
||||
HandlerList.clear();
|
||||
|
||||
releaseMutex();
|
||||
}
|
||||
|
||||
virtual int GetNumJobs() {
|
||||
if(!waitForMutex()) return -1;
|
||||
int n = JobList.size();
|
||||
releaseMutex();
|
||||
return n;
|
||||
}
|
||||
|
||||
virtual int GetNumHandlers() {
|
||||
if(!waitForMutex()) return -1;
|
||||
int n = HandlerList.size();
|
||||
releaseMutex();
|
||||
return n;
|
||||
}
|
||||
|
||||
virtual void Run(int job) {
|
||||
if(!waitForMutex()) return;
|
||||
int nJ = JobList.size();
|
||||
int nH = HandlerList.size();
|
||||
if(job < nJ && job >= 0) {
|
||||
T_JOB *job_item = JobList[job];
|
||||
for(int i = nH-1; i >= 0; i--) {
|
||||
T_HANDLER *handler = HandlerList[i];
|
||||
if(handler) {
|
||||
if(handler->state == job_item->state) {
|
||||
if(!job_item->suspended) {
|
||||
int cur_state = job_item->state;
|
||||
job_item->state = handler->jobHandler(job_item->state,job_item->last_state,job_item->userData);
|
||||
job_item->last_state = cur_state;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
releaseMutex();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !__C_JOBMANAGER_H__
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef __C_SERIAL_JOBMANAGER_H__
|
||||
#define __C_SERIAL_JOBMANAGER_H__
|
||||
|
||||
#include "c_jobmanager.h"
|
||||
|
||||
template<class T> class C_SERIAL_JOBMANAGER : public C_JOBMANAGER<T> {
|
||||
private:
|
||||
int currentJob;
|
||||
public:
|
||||
C_SERIAL_JOBMANAGER() {
|
||||
currentJob = 0;
|
||||
}
|
||||
~C_SERIAL_JOBMANAGER() { }
|
||||
int GetCurrentJob() { return currentJob; }
|
||||
virtual void Run(int passes = 1) {
|
||||
int numPasses = passes;
|
||||
while(numPasses-- > 0) {
|
||||
C_JOBMANAGER<T>::Run(currentJob++);
|
||||
if(currentJob > GetNumJobs()) currentJob = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !__C_SERIAL_JOBMANAGER_H__
|
194
Src/Plugins/DSP/dsp_sc/sc2srclib/Include/c_shoutcast_2_output.h
Normal file
194
Src/Plugins/DSP/dsp_sc/sc2srclib/Include/c_shoutcast_2_output.h
Normal file
|
@ -0,0 +1,194 @@
|
|||
#ifndef __C_SHOUTCAST_2_OUTPUT_H__
|
||||
#define __C_SHOUTCAST_2_OUTPUT_H__
|
||||
|
||||
#include <time.h>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "c_serial_jobmanager.h"
|
||||
#include "../jnetlib/jnetlib.h"
|
||||
#include "../Encoders/c_encoder.h"
|
||||
#include "../Encoders/c_encoder_mp3dll.h"
|
||||
|
||||
#include "../lame/include/lame.h"
|
||||
#include "../lame/libmp3lame/lame_global_flags.h"
|
||||
#include "../uvAuth21/uvAuth21.h"
|
||||
|
||||
#ifdef USEAACP
|
||||
#include "../Encoders/c_encoder_aacp.h"
|
||||
#endif
|
||||
struct T_OUTPUT_CONFIG {
|
||||
char Name[32];
|
||||
char UserID[256];
|
||||
char Address[1024];
|
||||
u_short Port;
|
||||
char StationID[8];
|
||||
char Password[256]; // 4 - 8 for 1.8.2
|
||||
char cipherkey[32];// sc2 cipherkey
|
||||
int AutoRecon;
|
||||
int ReconTime;
|
||||
char Description[1024];
|
||||
char ServerURL[2048];
|
||||
int Genre1;
|
||||
int Genre2;
|
||||
char Genre3[1024];
|
||||
char ICQ[128];
|
||||
char AIM[512];
|
||||
char IRC[512];
|
||||
char content_type[11];
|
||||
int Public;
|
||||
int doTitleUpdate;
|
||||
int protocol;
|
||||
int DoUpload;
|
||||
char introfilepath[4096];
|
||||
char backupfile[4096];
|
||||
};
|
||||
|
||||
#define DEFAULT_ENCODER (C_ENCODER *)(-1)
|
||||
|
||||
#define OM_ENCODE 1
|
||||
#define OM_OUTPUT 2
|
||||
#define OM_OTHER 4
|
||||
#define OM_ALL (OM_ENCODE | OM_OUTPUT | OM_OTHER)
|
||||
|
||||
enum OUTPUTTYPE {
|
||||
OUTTYPE_SOURCE,
|
||||
OUTTYPE_TITLE,
|
||||
};
|
||||
|
||||
struct T_OUTPUT_INFO {
|
||||
unsigned int BytesSent; // how many bytes of content we've sent
|
||||
clock_t ConnectionTime; // time a socket connection occurred
|
||||
int Version; // server version
|
||||
int Caps; // server capabilities
|
||||
int Reconnect; // flag for the reconnection algorithm
|
||||
int ReconnectTime; // value used in conjunction with the reconnection algorithm
|
||||
int Succeeded; // had at least one successful connection (for reconnection alg.) -1 = password failure
|
||||
int sc2Suceeded;//sc2 version
|
||||
char ErrorMsg[1024];
|
||||
time_t ConnectedAt;
|
||||
wchar_t Title[1024];
|
||||
wchar_t Next[1024];
|
||||
char URL[1024];
|
||||
int introuploaded;
|
||||
int backupuploaded;
|
||||
};
|
||||
|
||||
struct T_OUTPUT {
|
||||
JNL_Connection Output;
|
||||
enum OUTPUTTYPE Type;
|
||||
int Bitrate; // this shouldn't be here, but it's the only way we can tell the shoutcast server the bitrate
|
||||
char * ContentType; //neither should this
|
||||
int SlowClose; // set to 1 to wait until all data is sent before closing the connection
|
||||
T_OUTPUT_CONFIG *Config;
|
||||
T_OUTPUT_INFO Info;
|
||||
int m_sendmetadata;
|
||||
int m_initdone;
|
||||
};
|
||||
|
||||
enum OUTPUTSTATE {
|
||||
OUT_ERROR, // not a true state, but is returned when GetState() is called with an invalid connection handle
|
||||
OUT_IDLE,
|
||||
OUT_CONNECT,
|
||||
OUT_REQUEST_CIPHER,
|
||||
OUT_RECV_CIPHER,
|
||||
OUT_SENDAUTH,
|
||||
OUT_RECVAUTHRESPONSE,
|
||||
OUT_SEND_MIME,
|
||||
OUT_RECV_MIME,
|
||||
OUT_SEND_BITRATE,
|
||||
OUT_RECV_BITRATE,
|
||||
OUT_SEND_BUFSIZE,
|
||||
OUT_RECV_BUFSIZE,
|
||||
OUT_SEND_MAX,
|
||||
OUT_RECV_MAX,
|
||||
OUT_SENDYP,
|
||||
OUT_RECVYP,
|
||||
OUT_SEND_INITFLUSH,
|
||||
OUT_RECV_INITFLUSH,
|
||||
OUT_SEND_INITSTANDBY,
|
||||
OUT_RECV_INITSTANDBY,
|
||||
OUT_SEND_INTRO,
|
||||
OUT_RECV_INTRO,
|
||||
OUT_SEND_BACKUP,
|
||||
OUT_RECV_BACKUP,
|
||||
OUT_SENDCONTENT,
|
||||
OUT_DISCONNECT,
|
||||
OUT_RECONNECT,
|
||||
OUT_TITLESENDUPDATE,
|
||||
};
|
||||
#define OUT_DISCONNECTED OUT_IDLE
|
||||
|
||||
class C_SHOUTCAST_2_OUTPUT {
|
||||
private:
|
||||
C_ENCODER *Encoder;
|
||||
int IOwnEncoder;
|
||||
C_SERIAL_JOBMANAGER<T_OUTPUT> OutputManager;
|
||||
HANDLE mutex;
|
||||
|
||||
protected:
|
||||
static int Output_Idle(int state, T_OUTPUT *userData);
|
||||
static int Output_Connect(int state, T_OUTPUT *userData);
|
||||
static int Output_Request_Cipher(int state, T_OUTPUT *userData);
|
||||
static int Output_Receive_Cipher(int state, T_OUTPUT *userData);
|
||||
static int Output_SendAuth(int state, T_OUTPUT *userData);
|
||||
static int Output_RecvAuthResponse(int state, T_OUTPUT *userData);
|
||||
static int Output_Send_Mime(int state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Mime(int state, T_OUTPUT *userData);
|
||||
static int Output_Send_Bitrate(int state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Bitrate(int state, T_OUTPUT *userData);
|
||||
static int Output_Send_Buf_Size(int state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Buf_Size(int state, T_OUTPUT *userData);
|
||||
static int Output_Send_Max_Size(int state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Max_Size(int state, T_OUTPUT *userData);
|
||||
static int Output_DUMMY(int state, T_OUTPUT *userData);
|
||||
static int Output_SendYP(int state, T_OUTPUT *userData);
|
||||
static int Output_RecvYP(int state, T_OUTPUT *userData);
|
||||
static int Output_Send_InitFlush(int state, T_OUTPUT *userData);
|
||||
static int Output_Recv_InitFlush(int state, T_OUTPUT *userData);
|
||||
static int Output_Send_InitStandby(int state, T_OUTPUT *userData);
|
||||
static int Output_Recv_InitStandby(int state, T_OUTPUT *userData);
|
||||
static int Output_Send_InitMeta(int state, T_OUTPUT *userData);
|
||||
static int Output_Recv_InitMeta(int state, T_OUTPUT *userData);
|
||||
static int Output_Send_Intro(int state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Intro(int state, T_OUTPUT *userData);
|
||||
static int Output_Send_Backup(int state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Backup(int state, T_OUTPUT *userData);
|
||||
|
||||
static int Output_SendContent(int state, T_OUTPUT *userData);
|
||||
static int Output_Disconnect(int state, T_OUTPUT *userData);
|
||||
static int Output_Reconnect(int state, T_OUTPUT *userData);
|
||||
static int Output_Title_SendUpdate(int state, T_OUTPUT *userData);
|
||||
static int Output_Title_SendUpdatev2(int state, T_OUTPUT *userData);
|
||||
// uvox21
|
||||
static char * createUvoxFrameClasstype(std::string typeString);
|
||||
static int createUvoxFrame(int length, char * payload_in,char * payload_out, char * classtype);
|
||||
static int parseUvoxFrame(char * payload_in,char * payload_out);
|
||||
static int checkUvoxFrameForError(char * pload_out,int state, T_OUTPUT *userData);
|
||||
|
||||
void (*lame_init)(void);
|
||||
void (*lame_init_params)(lame_global_flags *);
|
||||
int (*lame_encode_buffer_interleaved)(lame_global_flags *,short int pcm[],int num_samples, char *mp3buffer,int mp3buffer_size);
|
||||
int (*lame_encode_flush)(lame_global_flags *,char *mp3buffer, int size);
|
||||
|
||||
public:
|
||||
C_SHOUTCAST_2_OUTPUT();
|
||||
void SetLame(void *init, void *params, void *encode, void *finish);
|
||||
~C_SHOUTCAST_2_OUTPUT();
|
||||
int Run(int mode = 0, void *Input = NULL, int InputSize = 0);
|
||||
int AddOutput(T_OUTPUT_CONFIG *Config);
|
||||
void UpdateOutput(int Connection);
|
||||
void RemoveOutput(int Connection);
|
||||
void ConnectOutput(int Connection);
|
||||
void DisconnectOutput(int Connection, int withReconnect = 0, int reconnectTime = -1); // withReconnect of -1 will use the output config's setting
|
||||
void SetEncoder(C_ENCODER *encoder, int takeOwnership = 0);
|
||||
void UpdateTitle(wchar_t*Title,wchar_t*Next, int Connection,int titleseq);
|
||||
enum OUTPUTSTATE GetState(int Connection);
|
||||
T_OUTPUT_CONFIG *operator[](int Connection);
|
||||
T_OUTPUT_CONFIG *GetOutput(int Connection);
|
||||
C_ENCODER *GetEncoder();
|
||||
T_OUTPUT_INFO *GetOutputInfo(int Connection);
|
||||
int m_titleseq;
|
||||
};
|
||||
|
||||
#endif // !__C_SHOUTCAST_2_OUTPUT_H__
|
817
Src/Plugins/DSP/dsp_sc/sc2srclib/Include/shoutcast_output.h
Normal file
817
Src/Plugins/DSP/dsp_sc/sc2srclib/Include/shoutcast_output.h
Normal file
|
@ -0,0 +1,817 @@
|
|||
#ifndef __SHOUTCAST_OUTPUT_H__
|
||||
#define __SHOUTCAST_OUTPUT_H__
|
||||
|
||||
#include <time.h>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <list>
|
||||
#include <fstream>
|
||||
#include "c_serial_jobmanager.h"
|
||||
#include "../Components/wac_network/wac_network_connection_api.h"
|
||||
#include <WinSock2.h>
|
||||
|
||||
#include "../Encoders/c_encoder.h"
|
||||
#include "../Encoders/c_encoder_mp3dll.h"
|
||||
|
||||
#include "../lame/include/lame.h"
|
||||
#include "../lame/libmp3lame/lame_global_flags.h"
|
||||
#include "../uvAuth21/uvAuth21.h"
|
||||
|
||||
#define UV_SYNC_BYTE 0x5A
|
||||
#define UV_RESERVED 0x00
|
||||
#define UV_END 0x00
|
||||
#define UV_END_LEN 1
|
||||
#define UV_HEADER_LEN 6
|
||||
#define UV_META_LEN 6
|
||||
#define UV_FRAME_LEN 16384
|
||||
#define UV_MAX_DATA_LEN (UV_FRAME_LEN - UV_HEADER_LEN - UV_END_LEN)
|
||||
#define UV_MAX_META_LEN (UV_FRAME_LEN - UV_HEADER_LEN - UV_META_LEN - UV_END_LEN)
|
||||
#define UV_MAX_META_FRAGMENTS 32
|
||||
#define UV_MAX_TOTAL_META_LEN (UV_MAX_META_LEN * UV_MAX_META_FRAGMENTS)
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
bool parent;
|
||||
bool children;
|
||||
} SCgenres;
|
||||
static SCgenres genres[] = {{"Alternative", true, true},
|
||||
{"Adult Alternative", false},
|
||||
{"Britpop", false},
|
||||
{"Classic Alternative", false},
|
||||
{"College", false},
|
||||
{"Dancepunk", false},
|
||||
{"Dream Pop", false},
|
||||
{"Emo", false},
|
||||
{"Goth", false},
|
||||
{"Grunge", false},
|
||||
{"Hardcore", false},
|
||||
{"Indie Pop", false},
|
||||
{"Indie Rock", false},
|
||||
{"Industrial", false},
|
||||
{"LoFi", false},
|
||||
{"Modern Rock", false},
|
||||
{"New Wave", false},
|
||||
{"Noise Pop", false},
|
||||
{"Post Punk", false},
|
||||
{"Power Pop", false},
|
||||
{"Punk", false},
|
||||
{"Ska", false},
|
||||
{"Xtreme", false},
|
||||
|
||||
{"Blues", true, true},
|
||||
{"Acoustic Blues", false},
|
||||
{"Cajun and Zydeco", false},
|
||||
{"Chicago Blues", false},
|
||||
{"Contemporary Blues", false},
|
||||
{"Country Blues", false},
|
||||
{"Delta Blues", false},
|
||||
{"Electric Blues", false},
|
||||
|
||||
{"Classical", true, true},
|
||||
{"Baroque", false},
|
||||
{"Chamber", false},
|
||||
{"Choral", false},
|
||||
{"Classical Period", false},
|
||||
{"Early Classical", false},
|
||||
{"Impressionist", false},
|
||||
{"Modern", false},
|
||||
{"Opera", false},
|
||||
{"Piano", false},
|
||||
{"Romantic", false},
|
||||
{"Symphony", false},
|
||||
|
||||
{"Country", true, true},
|
||||
{"Alt Country", false},
|
||||
{"Americana", false},
|
||||
{"Bluegrass", false},
|
||||
{"Classic Country", false},
|
||||
{"Contemporary Bluegrass", false},
|
||||
{"Contemporary Country", false},
|
||||
{"Honky Tonk", false},
|
||||
{"Hot Country Hits", false},
|
||||
{"Western", false},
|
||||
|
||||
{"Decades", true, true},
|
||||
{"30s", false},
|
||||
{"40s", false},
|
||||
{"50s", false},
|
||||
{"60s", false},
|
||||
{"70s", false},
|
||||
{"80s", false},
|
||||
{"90s", false},
|
||||
{"00s", false},
|
||||
|
||||
{"Easy Listening", true, true},
|
||||
{"Exotica", false},
|
||||
{"Light Rock", false},
|
||||
{"Lounge", false},
|
||||
{"Orchestral Pop", false},
|
||||
{"Polka", false},
|
||||
{"Space Age Pop", false},
|
||||
|
||||
{"Electronic", true, true},
|
||||
{"Acid House", false},
|
||||
{"Ambient", false},
|
||||
{"Big Beat", false},
|
||||
{"Breakbeat", false},
|
||||
{"Dance", false},
|
||||
{"Demo", false},
|
||||
{"Disco", false},
|
||||
{"Downtempo", false},
|
||||
{"Drum and Bass", false},
|
||||
{"Dubstep", false},
|
||||
{"Electro", false},
|
||||
{"Garage", false},
|
||||
{"Hard House", false},
|
||||
{"House", false},
|
||||
{"IDM", false},
|
||||
{"Jungle", false},
|
||||
{"Progressive", false},
|
||||
{"Techno", false},
|
||||
{"Trance", false},
|
||||
{"Tribal", false},
|
||||
{"Trip Hop", false},
|
||||
|
||||
{"Folk", true, true},
|
||||
{"Alternative Folk", false},
|
||||
{"Contemporary Folk", false},
|
||||
{"Folk Rock", false},
|
||||
{"New Acoustic", false},
|
||||
{"Old Time", false},
|
||||
{"Traditional Folk", false},
|
||||
{"World Folk", false},
|
||||
|
||||
{"Inspirational", true, true},
|
||||
{"Christian", false},
|
||||
{"Christian Metal", false},
|
||||
{"Christian Rap", false},
|
||||
{"Christian Rock", false},
|
||||
{"Classic Christian", false},
|
||||
{"Contemporary Gospel", false},
|
||||
{"Gospel", false},
|
||||
{"Praise and Worship", false},
|
||||
{"Sermons and Services", false},
|
||||
{"Southern Gospel", false},
|
||||
{"Traditional Gospel", false},
|
||||
|
||||
{"International", true, true},
|
||||
{"African", false},
|
||||
{"Afrikaans", false},
|
||||
{"Arabic", false},
|
||||
{"Asian", false},
|
||||
{"Bollywood", false},
|
||||
{"Brazilian", false},
|
||||
{"Caribbean", false},
|
||||
{"Celtic", false},
|
||||
{"Creole", false},
|
||||
{"European", false},
|
||||
{"Filipino", false},
|
||||
{"French", false},
|
||||
{"German", false},
|
||||
{"Greek", false},
|
||||
{"Hawaiian and Pacific", false},
|
||||
{"Hebrew", false},
|
||||
{"Hindi", false},
|
||||
{"Indian", false},
|
||||
{"Islamic", false},
|
||||
{"Japanese", false},
|
||||
{"Klezmer", false},
|
||||
{"Korean", false},
|
||||
{"Mediterranean", false},
|
||||
{"Middle Eastern", false},
|
||||
{"North American", false},
|
||||
{"Russian", false},
|
||||
{"Soca", false},
|
||||
{"South American", false},
|
||||
{"Tamil", false},
|
||||
{"Turkish", false},
|
||||
{"Worldbeat", false},
|
||||
{"Zouk", false},
|
||||
|
||||
{"Jazz", true, true},
|
||||
{"Acid Jazz", false},
|
||||
{"Avant Garde", false},
|
||||
{"Big Band", false},
|
||||
{"Bop", false},
|
||||
{"Classic Jazz", false},
|
||||
{"Cool Jazz", false},
|
||||
{"Fusion", false},
|
||||
{"Hard Bop", false},
|
||||
{"Latin Jazz", false},
|
||||
{"Smooth Jazz", false},
|
||||
{"Swing", false},
|
||||
{"Vocal Jazz", false},
|
||||
{"World Fusion", false},
|
||||
|
||||
{"Latin", true, true},
|
||||
{"Bachata", false},
|
||||
{"Banda", false},
|
||||
{"Bossa Nova", false},
|
||||
{"Cumbia", false},
|
||||
{"Flamenco", false},
|
||||
{"Latin Dance", false},
|
||||
{"Latin Pop", false},
|
||||
{"Latin Rap and Hip Hop", false},
|
||||
{"Latin Rock", false},
|
||||
{"Mariachi", false},
|
||||
{"Merengue", false},
|
||||
{"Ranchera", false},
|
||||
{"Reggaeton", false},
|
||||
{"Regional Mexican", false},
|
||||
{"Salsa", false},
|
||||
{"Samba", false},
|
||||
{"Tango", false},
|
||||
{"Tejano", false},
|
||||
{"Tropicalia", false},
|
||||
|
||||
{"Metal", true, true},
|
||||
{"Black Metal", false},
|
||||
{"Classic Metal", false},
|
||||
{"Death Metal", false},
|
||||
{"Extreme Metal", false},
|
||||
{"Grindcore", false},
|
||||
{"Hair Metal", false},
|
||||
{"Heavy Metal", false},
|
||||
{"Metalcore", false},
|
||||
{"Power Metal", false},
|
||||
{"Progressive Metal", false},
|
||||
{"Rap Metal", false},
|
||||
{"Thrash Metal", false},
|
||||
|
||||
{"Misc", true, false},
|
||||
|
||||
{"New Age", true, true},
|
||||
{"Environmental", false},
|
||||
{"Ethnic Fusion", false},
|
||||
{"Healing", false},
|
||||
{"Meditation", false},
|
||||
{"Spiritual", false},
|
||||
|
||||
{"Pop", true, true},
|
||||
{"Adult Contemporary", false},
|
||||
{"Barbershop", false},
|
||||
{"Bubblegum Pop", false},
|
||||
{"Dance Pop", false},
|
||||
{"Idols", false},
|
||||
{"JPOP", false},
|
||||
{"KPOP", false},
|
||||
{"Oldies", false},
|
||||
{"Soft Rock", false},
|
||||
{"Teen Pop", false},
|
||||
{"Top 40", false},
|
||||
{"World Pop", false},
|
||||
|
||||
{"Public Radio", true, true},
|
||||
{"College", false},
|
||||
{"News", false},
|
||||
{"Sports", false},
|
||||
{"Talk", false},
|
||||
{"Weather", false},
|
||||
|
||||
{"R&B and Urban", true, false},
|
||||
{"Classic R&B", false},
|
||||
{"Contemporary R&B", false},
|
||||
{"Doo Wop", false},
|
||||
{"Funk", false},
|
||||
{"Motown", false},
|
||||
{"Neo Soul", false},
|
||||
{"Quiet Storm", false},
|
||||
{"Soul", false},
|
||||
{"Urban Contemporary", false},
|
||||
|
||||
{"Rap", true, true},
|
||||
{"Alternative Rap", false},
|
||||
{"Dirty South", false},
|
||||
{"East Coast Rap", false},
|
||||
{"Freestyle", false},
|
||||
{"Gangsta Rap", false},
|
||||
{"Hip Hop", false},
|
||||
{"Mixtapes", false},
|
||||
{"Old School", false},
|
||||
{"Turntablism", false},
|
||||
{"Underground Hip Hop", false},
|
||||
{"West Coast Rap", false},
|
||||
|
||||
{"Reggae", true, true},
|
||||
{"Contemporary Reggae", false},
|
||||
{"Dancehall", false},
|
||||
{"Dub", false},
|
||||
{"Pop Reggae", false},
|
||||
{"Ragga", false},
|
||||
{"Reggae Roots", false},
|
||||
{"Rock Steady", false},
|
||||
|
||||
{"Rock", true, true},
|
||||
{"Adult Album Alternative", false},
|
||||
{"British Invasion", false},
|
||||
{"Celtic Rock", false},
|
||||
{"Classic Rock", false},
|
||||
{"Garage Rock", false},
|
||||
{"Glam", false},
|
||||
{"Hard Rock", false},
|
||||
{"Jam Bands", false},
|
||||
{"JROCK", false},
|
||||
{"Piano Rock", false},
|
||||
{"Prog Rock", false},
|
||||
{"Psychedelic", false},
|
||||
{"Rock & Roll", false},
|
||||
{"Rockabilly", false},
|
||||
{"Singer and Songwriter", false},
|
||||
{"Surf", false},
|
||||
|
||||
{"Seasonal and Holiday", true, true},
|
||||
{"Anniversary", false},
|
||||
{"Birthday", false},
|
||||
{"Christmas", false},
|
||||
{"Halloween", false},
|
||||
{"Hanukkah", false},
|
||||
{"Honeymoon", false},
|
||||
{"Kwanzaa", false},
|
||||
{"Valentine", false},
|
||||
{"Wedding", false},
|
||||
{"Winter", false},
|
||||
|
||||
{"Soundtracks", true, true},
|
||||
{"Anime", false},
|
||||
{"Kids", false},
|
||||
{"Original Score", false},
|
||||
{"Showtunes", false},
|
||||
{"Video Game Music", false},
|
||||
|
||||
{"Talk", true, true},
|
||||
{"BlogTalk", false},
|
||||
{"Comedy", false},
|
||||
{"Community", false},
|
||||
{"Educational", false},
|
||||
{"Government", false},
|
||||
{"News", false},
|
||||
{"Old Time Radio", false},
|
||||
{"Other Talk", false},
|
||||
{"Political", false},
|
||||
{"Scanner", false},
|
||||
{"Spoken Word", false},
|
||||
{"Sports", false},
|
||||
{"Technology", false},
|
||||
|
||||
{"Themes", true, true},
|
||||
{"Adult", false},
|
||||
{"Best Of", false},
|
||||
{"Chill", false},
|
||||
{"Eclectic", false},
|
||||
{"Experimental", false},
|
||||
{"Female", false},
|
||||
{"Heartache", false},
|
||||
{"Instrumental", false},
|
||||
{"LGBT", false},
|
||||
{"Love and Romance", false},
|
||||
{"Party Mix", false},
|
||||
{"Patriotic", false},
|
||||
{"Rainy Day Mix", false},
|
||||
{"Reality", false},
|
||||
{"Sexy", false},
|
||||
{"Shuffle", false},
|
||||
{"Travel Mix", false},
|
||||
{"Tribute", false},
|
||||
{"Trippy", false},
|
||||
{"Work Mix", false}
|
||||
};
|
||||
|
||||
// pulled from nmrCommon\intTypes.h
|
||||
typedef unsigned char __uint8;
|
||||
typedef unsigned short __uint16;
|
||||
typedef unsigned int __uint32;
|
||||
typedef unsigned long long __uint64;
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
// this structure should be 16384 bytes in total size
|
||||
// and is defined in full size so that we know its ok
|
||||
struct uv2xHdr
|
||||
{ // uvox2 message
|
||||
__uint8 sync;
|
||||
__uint8 qos;
|
||||
__uint16 msgType;
|
||||
__uint16 msgLen;
|
||||
__uint8 m_data[UV_MAX_DATA_LEN];
|
||||
__uint8 end;
|
||||
};
|
||||
|
||||
struct uv2xMetadataHdr
|
||||
{ /* uvox 2 metadata header */
|
||||
__uint8 sync;
|
||||
__uint8 qos;
|
||||
__uint16 msgType;
|
||||
__uint16 msgLen;
|
||||
|
||||
__uint16 id; /* ID (cookie) identifying a metadata package */
|
||||
__uint16 span; /* Span of messages in the metadata package being assembled */
|
||||
__uint16 index; /* Index of the message in the metadata package being assembled */
|
||||
|
||||
__uint8 m_data[UV_MAX_META_LEN];
|
||||
__uint8 end;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#define MSG_AUTH 0x1001
|
||||
#define MSG_BROADCAST_SETUP 0x1002
|
||||
#define MSG_NEGOTIATE_BUFFER_SIZE 0x1003
|
||||
#define MSG_STANDBY 0x1004
|
||||
#define MSG_TERMINATE 0x1005
|
||||
#define MSG_FLUSH_CACHED_METADATA 0x1006
|
||||
#define MSG_LISTENER_AUTHENTICATION 0x1007
|
||||
#define MSG_MAX_PAYLOAD_SIZE 0x1008
|
||||
#define MSG_CIPHER 0x1009
|
||||
#define MSG_MIME_TYPE 0x1040
|
||||
#define MSG_FILE_TRANSFER_BEGIN 0x1050
|
||||
#define MSG_FILE_TRANSFER_DATA 0x1051
|
||||
|
||||
#define MSG_BROADCAST_INTERRUPTION 0x2001
|
||||
#define MSG_BROADCAST_TERMINATE 0x2002
|
||||
|
||||
#define MSG_ICYNAME 0x1100
|
||||
#define MSG_ICYGENRE 0x1101
|
||||
#define MSG_ICYURL 0x1102
|
||||
#define MSG_ICYPUB 0x1103
|
||||
|
||||
#define MSG_METADATA_CONTENTINFO 0x3000
|
||||
#define MSG_METADATA_URL 0x3001
|
||||
#define MSG_METADATA_XML 0x3901
|
||||
#define MSG_METADATA_XML_NEW 0x3902
|
||||
|
||||
// only id the start of the album art type as it's variable
|
||||
#define MSG_METADATA_ALBUMART 0x4000
|
||||
#define MSG_METADATA_STATION_ART 0x0000
|
||||
#define MSG_METADATA_PLAYING_ART 0x0100
|
||||
/*
|
||||
0x4 0x0xx Station logo
|
||||
0x4 0x1xx Album art
|
||||
|
||||
00 = image/jpeg
|
||||
01 = image/png
|
||||
02 = image/bmp
|
||||
03 = image/gif
|
||||
*/
|
||||
|
||||
#define MSG_METADATA_TIMEREMAINING 0x5001
|
||||
|
||||
#define MP3_DATA 0x7000
|
||||
#define VLB_DATA 0x8000
|
||||
#define AAC_LC_DATA 0x8001
|
||||
#define AACP_DATA 0x8003
|
||||
#define OGG_DATA 0x8004
|
||||
|
||||
struct T_OUTPUT_CONFIG {
|
||||
char Name[32];
|
||||
wchar_t DisplayName[32];
|
||||
char UserID[256];
|
||||
char Address[1024];
|
||||
u_short Port;
|
||||
char StationID[12];
|
||||
char Password[256]; // 4 - 8 for 1.8.2
|
||||
char cipherkey[64]; // sc2 cipherkey
|
||||
int AutoRecon;
|
||||
int ReconTime;
|
||||
char Description[1024];
|
||||
char ServerURL[2048];
|
||||
char Genre[256];
|
||||
char ICQ[128];
|
||||
char AIM[1024];
|
||||
char IRC[1024];
|
||||
int Public;
|
||||
int doTitleUpdate;
|
||||
int protocol;
|
||||
int protocol_retry;
|
||||
char Now[1024];
|
||||
char Next[1024];
|
||||
};
|
||||
|
||||
#define DEFAULT_ENCODER (C_ENCODER *)(-1)
|
||||
|
||||
#define OM_ENCODE 1
|
||||
#define OM_OUTPUT 2
|
||||
#define OM_OTHER 4
|
||||
#define OM_ALL (OM_ENCODE | OM_OUTPUT | OM_OTHER)
|
||||
|
||||
enum OUTPUTTYPE {
|
||||
OUTTYPE_SOURCE,
|
||||
OUTTYPE_TITLE,
|
||||
};
|
||||
|
||||
typedef unsigned long ARGB32;
|
||||
|
||||
struct T_OUTPUT_TITLE {
|
||||
wchar_t *Title;
|
||||
wchar_t *Song;
|
||||
wchar_t *Album;
|
||||
wchar_t *Artist;
|
||||
wchar_t *Genre;
|
||||
wchar_t *Comment;
|
||||
wchar_t *Year;
|
||||
std::vector<std::wstring> NextList;
|
||||
void *APIC[2];
|
||||
int APICLength[2];
|
||||
int APICType[2];
|
||||
|
||||
T_OUTPUT_TITLE() : Title(0), Song(0), Album(0), Artist(0), Genre(0), Comment(0), Year(0)
|
||||
{
|
||||
memset(APIC, 0, sizeof(void *) * 2);
|
||||
memset(APICLength, 0, sizeof(int) * 2);
|
||||
memset(APICType, 0, sizeof(int) * 2);
|
||||
}
|
||||
|
||||
|
||||
~T_OUTPUT_TITLE()
|
||||
{
|
||||
if (Title)
|
||||
{
|
||||
free(Title);
|
||||
Title = 0;
|
||||
}
|
||||
|
||||
if (Song)
|
||||
{
|
||||
free(Song);
|
||||
Song = 0;
|
||||
}
|
||||
|
||||
if (Album)
|
||||
{
|
||||
free(Album);
|
||||
Album = 0;
|
||||
}
|
||||
|
||||
if (Artist)
|
||||
{
|
||||
free(Artist);
|
||||
Artist = 0;
|
||||
}
|
||||
|
||||
if (Genre)
|
||||
{
|
||||
free(Genre);
|
||||
Genre = 0;
|
||||
}
|
||||
|
||||
if (Comment)
|
||||
{
|
||||
free(Comment);
|
||||
Comment = 0;
|
||||
}
|
||||
|
||||
if (Year)
|
||||
{
|
||||
free(Year);
|
||||
Year = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct T_OUTPUT_INFO {
|
||||
unsigned int BytesSent; // how many bytes of content we've sent
|
||||
clock_t ConnectionTime; // time a socket connection occurred
|
||||
int Version; // server version
|
||||
int Caps; // server capabilities
|
||||
int Reconnect; // flag for the reconnection algorithm
|
||||
int ReconnectTime; // value used in conjunction with the reconnection algorithm
|
||||
int Succeeded; // had at least one successful connection (for reconnection alg.) -1 = password failure
|
||||
int last_state; // using this as a means to allow for closing on errors but able to show a better message
|
||||
int Switching; // if we're doing an automatic protocol version change (from v2 to v1)
|
||||
char *ErrorMsg;
|
||||
time_t ConnectedAt;
|
||||
int meta_cached;
|
||||
int art_cached[2];
|
||||
unsigned short art_index[2];
|
||||
unsigned short art_cached_span[2];
|
||||
int art_cached_length[2];
|
||||
|
||||
// metadata information about the stream, etc
|
||||
wchar_t *Title;
|
||||
std::vector<std::wstring> NextList;
|
||||
wchar_t *Song;
|
||||
wchar_t *Album;
|
||||
wchar_t *Artist;
|
||||
wchar_t *Genre;
|
||||
wchar_t *Comment;
|
||||
wchar_t *Year;
|
||||
void *APIC[2];
|
||||
int APICLength[2];
|
||||
int APICType[2];
|
||||
|
||||
T_OUTPUT_INFO() : BytesSent(0), ConnectionTime(0), Version(0),
|
||||
Caps(0), Reconnect(0), ReconnectTime(0),
|
||||
Succeeded(0), last_state(0), Switching(0),
|
||||
ErrorMsg(0), ConnectedAt(0), meta_cached(0),
|
||||
Title(0), Song(0), Album(0), Artist(0),
|
||||
Genre(0), Comment(0), Year(0)
|
||||
{
|
||||
memset(art_cached, 0, sizeof(int) * 2);
|
||||
memset(art_index, 0, sizeof(unsigned short) * 2);
|
||||
memset(art_cached_span, 0, sizeof(unsigned short) * 2);
|
||||
memset(art_cached_length, 0, sizeof(int) * 2);
|
||||
|
||||
memset(APIC, 0, sizeof(void *) * 2);
|
||||
memset(APICLength, 0, sizeof(int) * 2);
|
||||
memset(APICType, 0, sizeof(int) * 2);
|
||||
}
|
||||
|
||||
~T_OUTPUT_INFO()
|
||||
{
|
||||
if (Title)
|
||||
{
|
||||
free(Title);
|
||||
Title = 0;
|
||||
}
|
||||
|
||||
if (Song)
|
||||
{
|
||||
free(Song);
|
||||
Song = 0;
|
||||
}
|
||||
|
||||
if (Album)
|
||||
{
|
||||
free(Album);
|
||||
Album = 0;
|
||||
}
|
||||
|
||||
if (Artist)
|
||||
{
|
||||
free(Artist);
|
||||
Artist = 0;
|
||||
}
|
||||
|
||||
if (Genre)
|
||||
{
|
||||
free(Genre);
|
||||
Genre = 0;
|
||||
}
|
||||
|
||||
if (Comment)
|
||||
{
|
||||
free(Comment);
|
||||
Comment = 0;
|
||||
}
|
||||
|
||||
if (Year)
|
||||
{
|
||||
free(Year);
|
||||
Year = 0;
|
||||
}
|
||||
|
||||
if (Succeeded == -2 && ErrorMsg) {
|
||||
free(ErrorMsg);
|
||||
ErrorMsg = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct T_OUTPUT {
|
||||
int Connection; // using this for the title update callback so the correct instance is updated
|
||||
void (*TitleCallback)(const int Connection, const int Mode);
|
||||
api_connection *Output;
|
||||
enum OUTPUTTYPE Type;
|
||||
int Bitrate; // this shouldn't be here, but it's the only way we can tell the shoutcast server the bitrate
|
||||
char *ContentType; // neither should this
|
||||
int SlowClose; // set to 1 to wait until all data is sent before closing the connection
|
||||
T_OUTPUT_CONFIG *Config;
|
||||
T_OUTPUT_INFO Info;
|
||||
|
||||
T_OUTPUT() : Connection(0), TitleCallback(0), Output(0), Type(OUTTYPE_SOURCE), Bitrate(0), ContentType(0), SlowClose(0), Config(0) {}
|
||||
};
|
||||
|
||||
enum OUTPUTSTATE {
|
||||
OUT_ERROR, // not a true state, but is returned when GetState() is called with an invalid connection handle
|
||||
OUT_DISCONNECTED,
|
||||
OUT_CONNECT,
|
||||
OUT_REQUEST_CIPHER,
|
||||
OUT_RECV_CIPHER,
|
||||
OUT_SENDAUTH,
|
||||
OUT_RECVAUTHRESPONSE,
|
||||
OUT_SEND_MIME,
|
||||
OUT_RECV_MIME,
|
||||
OUT_SEND_BITRATE,
|
||||
OUT_RECV_BITRATE,
|
||||
OUT_SEND_BUFSIZE,
|
||||
OUT_RECV_BUFSIZE,
|
||||
OUT_SEND_MAX,
|
||||
OUT_RECV_MAX,
|
||||
OUT_SENDYP,
|
||||
OUT_SEND_INITFLUSH,
|
||||
OUT_RECV_INITFLUSH,
|
||||
OUT_SEND_INITSTANDBY,
|
||||
OUT_RECV_INITSTANDBY,
|
||||
/*OUT_SEND_INTRO,
|
||||
OUT_RECV_INTRO,
|
||||
OUT_SEND_BACKUP,
|
||||
OUT_RECV_BACKUP,*/
|
||||
OUT_SENDCONTENT,
|
||||
OUT_DISCONNECT,
|
||||
OUT_RECONNECT,
|
||||
OUT_TITLESENDUPDATE,
|
||||
OUT_FAIL_CIPHER,
|
||||
OUT_SEND_METADATA,
|
||||
OUT_SEND_ARTWORK,
|
||||
};
|
||||
static void *mutex;
|
||||
|
||||
class SHOUTCAST_OUTPUT {
|
||||
private:
|
||||
C_ENCODER *Encoder;
|
||||
int IOwnEncoder;
|
||||
C_SERIAL_JOBMANAGER<T_OUTPUT> OutputManager;
|
||||
T_OUTPUT_TITLE metadata;
|
||||
|
||||
protected:
|
||||
static int Output_Disconnected(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Connect(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Request_Cipher(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Receive_Cipher(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_SendAuth(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_RecvAuthResponse(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Send_Mime(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Mime(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Send_Bitrate(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Bitrate(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Send_Buf_Size(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Buf_Size(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Send_Max_Size(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Max_Size(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_DUMMY(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_SendYP(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Send_InitFlush(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Recv_InitFlush(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Send_InitStandby(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Recv_InitStandby(int state, int last_state, T_OUTPUT *userData);
|
||||
/*static int Output_Send_Intro(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Intro(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Send_Backup(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Recv_Backup(int state, int last_state, T_OUTPUT *userData);*/
|
||||
static int Output_SendContent(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Disconnect(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Reconnect(int state, int last_state, T_OUTPUT *userData);
|
||||
|
||||
static int Output_Title_SendUpdate(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Send_Metadata(int state, int last_state, T_OUTPUT *userData);
|
||||
static int Output_Send_Artwork(int state, int last_state, T_OUTPUT *userData);
|
||||
|
||||
// uvox21
|
||||
static void createUvoxFrame(int length, char *payload_in, int type, T_OUTPUT *userData);
|
||||
static int createUvoxMetaFrame(int length, char *payload_in, int type,
|
||||
T_OUTPUT *userData, unsigned short id, unsigned short span = 1);
|
||||
static int parseUvoxFrame(char *payload_in, char *payload_out);
|
||||
static int checkUvoxFrameForError(char *pload_out, int state, T_OUTPUT *userData);
|
||||
|
||||
void (*lame_init)(void);
|
||||
void (*lame_init_params)(lame_global_flags *);
|
||||
int (*lame_encode_buffer_interleaved)(lame_global_flags *, short int pcm[], int num_samples, char *mp3buffer, int mp3buffer_size);
|
||||
int (*lame_encode_flush)(lame_global_flags *, char *mp3buffer, int size);
|
||||
|
||||
HINSTANCE libinst;
|
||||
|
||||
public:
|
||||
SHOUTCAST_OUTPUT();
|
||||
void SetLame(void *init, void *params, void *encode, void *finish);
|
||||
~SHOUTCAST_OUTPUT();
|
||||
int Run(int mode = 0, void *Input = NULL, int InputSize = 0, int SaveEncoder = -1);
|
||||
int AddOutput(int Connection, T_OUTPUT_CONFIG *Config, void (*TitleCallback)(const int Connection, const int Mode)=0);
|
||||
void UpdateOutput(int Connection);
|
||||
void RemoveOutput(int Connection);
|
||||
int ConnectOutput(int Connection);
|
||||
int DisconnectOutput(int Connection, int withReconnect = 0, int reconnectTime = -1); // withReconnect of -1 will use the output config's setting
|
||||
void SetEncoder(C_ENCODER *encoder, int takeOwnership = 0);
|
||||
|
||||
// we will attempt to cache the title information to save on duplication and
|
||||
// also to make it easier for the title to be re-sent on server disconnect
|
||||
void UpdateTitleCache(wchar_t *Title, std::vector<std::wstring> NextList, wchar_t *Song,
|
||||
wchar_t *Album, wchar_t *Artist, wchar_t *Genre, wchar_t *Comment,
|
||||
wchar_t* Year, int Connection, bool sendNext);
|
||||
void UpdateTitle(wchar_t *Title, std::vector<std::wstring> NextList,
|
||||
int Connection, bool sendNext, bool UseCache = true);
|
||||
|
||||
void UpdateArtwork(int Connection);
|
||||
void UpdateAlbumArtCache(void* APIC, int APIClength, int APICType, int Connection);
|
||||
int UpdateAlbumArt(int Connection);
|
||||
|
||||
enum OUTPUTSTATE GetState(int Connection);
|
||||
T_OUTPUT_CONFIG *operator[](int Connection);
|
||||
T_OUTPUT_CONFIG *GetOutput(int Connection);
|
||||
C_ENCODER *GetEncoder();
|
||||
T_OUTPUT_INFO *GetOutputInfo(int Connection);
|
||||
};
|
||||
static unsigned short mid = 1;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEBUG_STATE OutputDebugString(__FUNCTION__); OutputDebugString("\r\n");
|
||||
#else
|
||||
#define DEBUG_STATE
|
||||
#endif
|
||||
|
||||
#define STATE userData->Info.last_state = last_state
|
||||
#define LOCK if(WaitForSingleObject(mutex,INFINITE) == WAIT_OBJECT_0)
|
||||
#define UNLOCK ReleaseMutex(mutex);
|
||||
|
||||
extern char sourceVersion[64];
|
||||
extern HWND hMainDLG;
|
||||
#endif // !__SHOUTCAST_OUTPUT_H__
|
1323
Src/Plugins/DSP/dsp_sc/sc2srclib/lame/include/lame.h
Normal file
1323
Src/Plugins/DSP/dsp_sc/sc2srclib/lame/include/lame.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,184 @@
|
|||
#ifndef LAME_GLOBAL_FLAGS_H
|
||||
#define LAME_GLOBAL_FLAGS_H
|
||||
|
||||
#ifndef lame_internal_flags_defined
|
||||
#define lame_internal_flags_defined
|
||||
struct lame_internal_flags;
|
||||
typedef struct lame_internal_flags lame_internal_flags;
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum short_block_e {
|
||||
short_block_not_set = -1, /* allow LAME to decide */
|
||||
short_block_allowed = 0, /* LAME may use them, even different block types for L/R */
|
||||
short_block_coupled, /* LAME may use them, but always same block types in L/R */
|
||||
short_block_dispensed, /* LAME will not use short blocks, long blocks only */
|
||||
short_block_forced /* LAME will not use long blocks, short blocks only */
|
||||
} short_block_t;
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Control Parameters set by User. These parameters are here for
|
||||
* backwards compatibility with the old, non-shared lib API.
|
||||
* Please use the lame_set_variablename() functions below
|
||||
*
|
||||
*
|
||||
***********************************************************************/
|
||||
struct lame_global_struct {
|
||||
unsigned int class_id;
|
||||
|
||||
/* input description */
|
||||
unsigned long num_samples; /* number of samples. default=2^32-1 */
|
||||
int num_channels; /* input number of channels. default=2 */
|
||||
int samplerate_in; /* input_samp_rate in Hz. default=44.1 kHz */
|
||||
int samplerate_out; /* output_samp_rate.
|
||||
default: LAME picks best value
|
||||
at least not used for MP3 decoding:
|
||||
Remember 44.1 kHz MP3s and AC97 */
|
||||
float scale; /* scale input by this amount before encoding
|
||||
at least not used for MP3 decoding */
|
||||
float scale_left; /* scale input of channel 0 (left) by this
|
||||
amount before encoding */
|
||||
float scale_right; /* scale input of channel 1 (right) by this
|
||||
amount before encoding */
|
||||
|
||||
/* general control params */
|
||||
int analysis; /* collect data for a MP3 frame analyzer? */
|
||||
int write_lame_tag; /* add Xing VBR tag? */
|
||||
int decode_only; /* use lame/mpglib to convert mp3 to wav */
|
||||
int quality; /* quality setting 0=best, 9=worst default=5 */
|
||||
MPEG_mode mode; /* see enum in lame.h
|
||||
default = LAME picks best value */
|
||||
int force_ms; /* force M/S mode. requires mode=1 */
|
||||
int free_format; /* use free format? default=0 */
|
||||
int findReplayGain; /* find the RG value? default=0 */
|
||||
int decode_on_the_fly; /* decode on the fly? default=0 */
|
||||
int write_id3tag_automatic; /* 1 (default) writes ID3 tags, 0 not */
|
||||
|
||||
int nogap_total;
|
||||
int nogap_current;
|
||||
|
||||
int substep_shaping;
|
||||
int noise_shaping;
|
||||
int subblock_gain; /* 0 = no, 1 = yes */
|
||||
int use_best_huffman; /* 0 = no. 1=outside loop 2=inside loop(slow) */
|
||||
|
||||
/*
|
||||
* set either brate>0 or compression_ratio>0, LAME will compute
|
||||
* the value of the variable not set.
|
||||
* Default is compression_ratio = 11.025
|
||||
*/
|
||||
int brate; /* bitrate */
|
||||
float compression_ratio; /* sizeof(wav file)/sizeof(mp3 file) */
|
||||
|
||||
|
||||
/* frame params */
|
||||
int copyright; /* mark as copyright. default=0 */
|
||||
int original; /* mark as original. default=1 */
|
||||
int extension; /* the MP3 'private extension' bit.
|
||||
Meaningless */
|
||||
int emphasis; /* Input PCM is emphased PCM (for
|
||||
instance from one of the rarely
|
||||
emphased CDs), it is STRONGLY not
|
||||
recommended to use this, because
|
||||
psycho does not take it into account,
|
||||
and last but not least many decoders
|
||||
don't care about these bits */
|
||||
int error_protection; /* use 2 bytes per frame for a CRC
|
||||
checksum. default=0 */
|
||||
int strict_ISO; /* enforce ISO spec as much as possible */
|
||||
|
||||
int disable_reservoir; /* use bit reservoir? */
|
||||
|
||||
/* quantization/noise shaping */
|
||||
int quant_comp;
|
||||
int quant_comp_short;
|
||||
int experimentalY;
|
||||
int experimentalZ;
|
||||
int exp_nspsytune;
|
||||
|
||||
int preset;
|
||||
|
||||
/* VBR control */
|
||||
vbr_mode VBR;
|
||||
float VBR_q_frac; /* Range [0,...,1[ */
|
||||
int VBR_q; /* Range [0,...,9] */
|
||||
int VBR_mean_bitrate_kbps;
|
||||
int VBR_min_bitrate_kbps;
|
||||
int VBR_max_bitrate_kbps;
|
||||
int VBR_hard_min; /* strictly enforce VBR_min_bitrate
|
||||
normaly, it will be violated for analog
|
||||
silence */
|
||||
|
||||
|
||||
/* resampling and filtering */
|
||||
int lowpassfreq; /* freq in Hz. 0=lame choses.
|
||||
-1=no filter */
|
||||
int highpassfreq; /* freq in Hz. 0=lame choses.
|
||||
-1=no filter */
|
||||
int lowpasswidth; /* freq width of filter, in Hz
|
||||
(default=15%) */
|
||||
int highpasswidth; /* freq width of filter, in Hz
|
||||
(default=15%) */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* psycho acoustics and other arguments which you should not change
|
||||
* unless you know what you are doing
|
||||
*/
|
||||
float maskingadjust;
|
||||
float maskingadjust_short;
|
||||
int ATHonly; /* only use ATH */
|
||||
int ATHshort; /* only use ATH for short blocks */
|
||||
int noATH; /* disable ATH */
|
||||
int ATHtype; /* select ATH formula */
|
||||
float ATHcurve; /* change ATH formula 4 shape */
|
||||
float ATH_lower_db; /* lower ATH by this many db */
|
||||
int athaa_type; /* select ATH auto-adjust scheme */
|
||||
float athaa_sensitivity; /* dB, tune active region of auto-level */
|
||||
short_block_t short_blocks;
|
||||
int useTemporal; /* use temporal masking effect */
|
||||
float interChRatio;
|
||||
float msfix; /* Naoki's adjustment of Mid/Side maskings */
|
||||
|
||||
int tune; /* 0 off, 1 on */
|
||||
float tune_value_a; /* used to pass values for debugging and stuff */
|
||||
|
||||
float attackthre; /* attack threshold for L/R/M channel */
|
||||
float attackthre_s; /* attack threshold for S channel */
|
||||
|
||||
|
||||
struct {
|
||||
void (*msgf) (const char *format, va_list ap);
|
||||
void (*debugf) (const char *format, va_list ap);
|
||||
void (*errorf) (const char *format, va_list ap);
|
||||
} report;
|
||||
|
||||
/************************************************************************/
|
||||
/* internal variables, do not set... */
|
||||
/* provided because they may be of use to calling application */
|
||||
/************************************************************************/
|
||||
|
||||
int lame_allocated_gfp; /* is this struct owned by calling
|
||||
program or lame? */
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* more internal variables are stored in this structure: */
|
||||
/**************************************************************************/
|
||||
lame_internal_flags *internal_flags;
|
||||
|
||||
|
||||
struct {
|
||||
int mmx;
|
||||
int amd3dnow;
|
||||
int sse;
|
||||
|
||||
} asm_optimizations;
|
||||
};
|
||||
|
||||
int is_lame_global_flags_valid(const lame_global_flags * gfp);
|
||||
|
||||
#endif /* LAME_GLOBAL_FLAGS_H */
|
1636
Src/Plugins/DSP/dsp_sc/sc2srclib/shoutcast_output.cpp
Normal file
1636
Src/Plugins/DSP/dsp_sc/sc2srclib/shoutcast_output.cpp
Normal file
File diff suppressed because it is too large
Load diff
90
Src/Plugins/DSP/dsp_sc/sc2srclib/uvAuth21/uvAuth21.cpp
Normal file
90
Src/Plugins/DSP/dsp_sc/sc2srclib/uvAuth21/uvAuth21.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include "uvAuth21.h"
|
||||
|
||||
uvAuth21::uvAuth21(void) {
|
||||
}
|
||||
|
||||
uvAuth21::~uvAuth21(void) {
|
||||
}
|
||||
|
||||
string uvAuth21::encrypt(string user,string pass,string key) {
|
||||
string blob;
|
||||
uint8_t* username = (uint8_t*)user.data();
|
||||
uint8_t* password = (uint8_t*)pass.data();
|
||||
uint8_t* cipherkey = (uint8_t*)key.data();
|
||||
blob = XTEA_encipher(username,user.length(),cipherkey,key.length());
|
||||
blob += ':';
|
||||
blob += XTEA_encipher(password,pass.length(),cipherkey,key.length());
|
||||
return blob;
|
||||
}
|
||||
|
||||
const char * uvAuth21::encrypt(char * user,char * pass,char * key) {
|
||||
static string blob;
|
||||
uint8_t* username = (uint8_t*)user;
|
||||
uint8_t* password = (uint8_t*)pass;
|
||||
uint8_t* cipherkey = (uint8_t*)key;
|
||||
blob = XTEA_encipher(username,sizeof(user),cipherkey,sizeof(key));
|
||||
blob += ':';
|
||||
blob += XTEA_encipher(password,sizeof(pass),cipherkey,sizeof(key));
|
||||
return blob.c_str();
|
||||
}
|
||||
|
||||
// from wikipedia. Slightly modified to be 32/64 bit clean
|
||||
void uvAuth21::XTEA_encipher(__uint32* v, __uint32* k) {
|
||||
unsigned int num_rounds = 32;
|
||||
__uint32 v0=v[0], v1=v[1], i;
|
||||
__uint32 sum=0, delta=0x9E3779B9;
|
||||
for(i=0; i<num_rounds; i++) {
|
||||
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
|
||||
sum += delta;
|
||||
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
|
||||
}
|
||||
v[0]=v0; v[1]=v1;
|
||||
}
|
||||
|
||||
__uint32 uvAuth21::fourCharsToLong(__uint8 *s) {
|
||||
__uint32 l = 0;
|
||||
l |= s[0]; l <<= 8;
|
||||
l |= s[1]; l <<= 8;
|
||||
l |= s[2]; l <<= 8;
|
||||
l |= s[3];
|
||||
return l;
|
||||
}
|
||||
|
||||
std::vector<std::string> &uvAuth21::split(const std::string &s, char delim, std::vector<std::string> &elems) {
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
while(std::getline(ss, item, delim)) {
|
||||
elems.push_back(item);
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
std::vector<std::string> uvAuth21::dosplit(const std::string &s, char delim) {
|
||||
std::vector<std::string> elems;
|
||||
return split(s, delim, elems);
|
||||
}
|
||||
|
||||
std::string uvAuth21::XTEA_encipher(const __uint8* c_data,size_t c_data_cnt, const __uint8* c_key,size_t c_key_cnt) {
|
||||
std::ostringstream oss;
|
||||
std::vector<__uint8> key(c_key,c_key + c_key_cnt);
|
||||
std::vector<__uint8> data(c_data,c_data + c_data_cnt);
|
||||
|
||||
// key is always 128 bits
|
||||
while(key.size() < 16) key.push_back(XTEA_KEY_PAD); // pad key with zero
|
||||
__uint32 k[4] = { fourCharsToLong(&key[0]),fourCharsToLong(&key[4]),fourCharsToLong(&key[8]),fourCharsToLong(&key[12])};
|
||||
|
||||
// data is multiple of 64 bits
|
||||
size_t siz = data.size();
|
||||
while(siz % 8) { siz+=1; data.push_back(XTEA_DATA_PAD);} // pad data with zero
|
||||
|
||||
for(size_t x = 0; x < siz; x+=8) {
|
||||
__uint32 v[2];
|
||||
v[0] = fourCharsToLong(&data[x]);
|
||||
v[1] = fourCharsToLong(&data[x+4]);
|
||||
XTEA_encipher(v,k);
|
||||
oss << setw(8) << setfill('0') << hex << v[0];
|
||||
oss << setw(8) << setfill('0') << hex << v[1]; // hex values. uvox uses colon as seperator so we can't use chars for
|
||||
// fear of collision
|
||||
}
|
||||
return oss.str();
|
||||
}
|
34
Src/Plugins/DSP/dsp_sc/sc2srclib/uvAuth21/uvAuth21.h
Normal file
34
Src/Plugins/DSP/dsp_sc/sc2srclib/uvAuth21/uvAuth21.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../replicant\foundation\win-x86\types.h"
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
#include <assert.h>
|
||||
|
||||
#define XTEA_KEY_PAD 0
|
||||
#define XTEA_DATA_PAD 0
|
||||
#define __uint32 uint32_t
|
||||
#define __uint8 uint8_t
|
||||
|
||||
using namespace std;
|
||||
|
||||
class uvAuth21 {
|
||||
public:
|
||||
uvAuth21(void);
|
||||
string encrypt(string user, string password, string key);
|
||||
const char * encrypt(char * user,char * password,char * key);
|
||||
~uvAuth21(void);
|
||||
private:
|
||||
|
||||
protected:
|
||||
static void XTEA_encipher(__uint32* v, __uint32* k);
|
||||
static __uint32 fourCharsToLong(__uint8 *s);
|
||||
static string XTEA_encipher(const __uint8* c_data, size_t c_data_cnt, const __uint8* c_key, size_t c_key_cnt);
|
||||
static std::vector<std::string> dosplit(const std::string &s, char delim);
|
||||
static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue