Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View 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

View 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";
}

View 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__ */

View 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);
}

View 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__ */

View file

@ -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);
}

View 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__ */

View 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;
}

View 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__ */

View 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);
}
}

View 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__ */

View 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);
}

View 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__ */

View 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_

View 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__

View file

@ -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__

View 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__

View 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__

File diff suppressed because it is too large Load diff

View file

@ -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 */

File diff suppressed because it is too large Load diff

View 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();
}

View 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);
};