Merge branch 'community' into patch-1

This commit is contained in:
PythonTryHard 2024-09-30 01:12:33 +07:00 committed by GitHub
commit c50b171449
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
67 changed files with 4 additions and 12679 deletions

View File

@ -16,6 +16,10 @@ Building of the Winamp desktop client is currently based around Visual Studio 20
### Dependencies ### Dependencies
#### libdiscid
We take libdiscid from https://github.com/metabrainz/libdiscid/tree/v0.6.2, copy it in /Src/external_dependencies/libdiscid-0.6.2/
#### libvpx #### libvpx
We take libvpx from [https://github.com/ShiftMediaProject/libvpx](https://github.com/ShiftMediaProject/libvpx), modify it, and pack it to archive. We take libvpx from [https://github.com/ShiftMediaProject/libvpx](https://github.com/ShiftMediaProject/libvpx), modify it, and pack it to archive.

View File

@ -1,67 +0,0 @@
#include "DlgBase.h"
void DlgBase::MakeComboEdit(UINT id, DWORD s)
{
HWND w = GetDlgItem(wnd, id);
RECT r;
GetChildRect(id, r);
DestroyWindow(w);
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", 0, WS_CHILD | s, r.left - 1, r.top - 1, r.right - r.left, r.bottom - r.top, wnd, (HMENU)id, 0, 0);
}
void DlgBase::GetChildRect(UINT id, RECT& child)
{
RECT r_parent, r_child;
GetWindowRect(wnd, &r_parent);
GetWindowRect(GetDlgItem(wnd, id), &r_child);
int dx = r_parent.left;
int dy = r_parent.top;
if (!(GetWindowLong(wnd, GWL_STYLE)&WS_CHILD))
{
dy += GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME);
dx += GetSystemMetrics(SM_CXDLGFRAME);
}
child.left = r_child.left - dx;
child.right = r_child.right - dx;
child.top = r_child.top - dy;
child.bottom = r_child.bottom - dy;
}
void DlgBase::do_sizing(UINT wp, RECT * r)
{
UINT dx, dy;
dx = r->right - r->left;
dy = r->bottom - r->top;
if (dx < min_size_x_w)
{
switch (wp)
{
case WMSZ_BOTTOMLEFT:
case WMSZ_LEFT:
case WMSZ_TOPLEFT:
r->left = r->right - min_size_x_w;
break;
case WMSZ_BOTTOMRIGHT:
case WMSZ_RIGHT:
case WMSZ_TOPRIGHT:
r->right = r->left + min_size_x_w;
break;
}
}
if (dy < min_size_y_w)
{
switch (wp)
{
case WMSZ_BOTTOMLEFT:
case WMSZ_BOTTOM:
case WMSZ_BOTTOMRIGHT:
r->bottom = r->top + min_size_y_w;
break;
case WMSZ_TOPLEFT:
case WMSZ_TOP:
case WMSZ_TOPRIGHT:
r->top = r->bottom - min_size_y_w;
break;
}
}
}

View File

@ -1,118 +0,0 @@
#include <windows.h>
#include "main.h"
static void SetWindowRect(HWND w, RECT * r)
{
SetWindowPos(w, 0, r->left, r->top, r->right - r->left, r->bottom - r->top, SWP_NOZORDER | SWP_NOCOPYBITS);
}
class DlgBase
{
public:
BOOL isDialogMessage(MSG * m)
{
return wnd ? IsDialogMessage(wnd, m) : 0;
}
protected:
void endDialog(int x)
{
EndDialog(wnd, x);
}
void _do_size_x(RECT * r, UINT id, UINT wx, UINT min_x)
{
RECT r1 = {r->left, r->top, wx - min_x + r->right, r->bottom};
SetWindowRect(GetDlgItem(wnd, id), &r1);
}
void _do_size_xy(RECT * r, UINT id, UINT wx, UINT wy, UINT min_x, UINT min_y)
{
RECT r1 = {r->left, r->top, wx - min_x + r->right, wy - min_y + r->bottom};
SetWindowRect(GetDlgItem(wnd, id), &r1);
}
void _do_align_x_size_y(RECT * r, UINT id, UINT wx, UINT wy, UINT min_x, UINT min_y)
{
RECT r1 = {wx - min_x + r->left, r->top, wx - min_x + r->right, wy - min_y + r->bottom};
SetWindowRect(GetDlgItem(wnd, id), &r1);
}
void _do_align_x(RECT * r, UINT id, UINT wx, UINT min_x)
{
RECT r1 = {wx - min_x + r->left, r->top, wx - min_x + r->right, r->bottom};
SetWindowRect(GetDlgItem(wnd, id), &r1);
}
void _do_align_xy(RECT * r, UINT id, UINT wx, UINT wy, UINT min_x, UINT min_y)
{
RECT r1 = {wx - min_x + r->left, wy - min_y + r->top, wx - min_x + r->right, wy - min_y + r->bottom};
SetWindowRect(GetDlgItem(wnd, id), &r1);
}
#define do_size_x(id,r) _do_size_x(r,id,sx,min_size_x)
#define do_size_xy(id,r) _do_size_xy(r,id,sx,sy,min_size_x,min_size_y)
#define do_align_x_size_y(id,r) _do_align_x_size_y(r,id,sx,sy,min_size_x,min_size_y)
#define do_align_xy(id,r) _do_align_xy(r,id,sx,sy,min_size_x,min_size_y)
#define do_align_x(id,r) _do_align_x(r,id,sx,min_size_x)
HWND wnd;
UINT min_size_x, min_size_y;
UINT min_size_x_w, min_size_y_w;
void do_sizing(UINT wp, RECT * r);
void MakeComboEdit(UINT id, DWORD s);
void GetChildRect(UINT id, RECT& child);
virtual BOOL DlgProc(UINT msg, WPARAM wp, LPARAM lp) { return 0;};
static BOOL CALLBACK TheDialogProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{
DlgBase * p;
if (msg == WM_INITDIALOG)
{
p = (DlgBase*)lp;
SetWindowLong(wnd, DWL_USER, lp);
p->wnd = wnd;
RECT r;
GetClientRect(wnd, &r);
p->min_size_x = r.right;
p->min_size_y = r.bottom;
GetWindowRect(wnd, &r);
p->min_size_x_w = r.right - r.left;
p->min_size_y_w = r.bottom - r.top;
}
else p = (DlgBase*)GetWindowLong(wnd, DWL_USER);
BOOL rv = 0;
if (p)
{
rv = p->DlgProc(msg, wp, lp);
if (msg == WM_DESTROY)
{
p->wnd = 0;
SetWindowLong(wnd, DWL_USER, 0);
}
}
return rv;
}
HWND myCreateDialog(UINT id, HWND parent)
{
return CreateDialogParamT(hIns, (char*)id, parent, TheDialogProc, (long)this);
}
virtual void myProcessMessage(MSG * msg)
{
if (!IsDialogMessage(wnd, msg))
{
TranslateMessage(msg);
DispatchMessage(msg);
}
}
int myDialogBox(UINT id, HWND parent)
{
return DialogBoxParamT(hIns, (char*)id, parent, TheDialogProc, (long)this);
}
DlgBase() {
wnd = 0;
min_size_x = min_size_y = min_size_x_w = min_size_y_w = 0;
}
virtual ~DlgBase() {}
};

View File

@ -1,65 +0,0 @@
#include "main.h"
#include "decoder.h"
extern "C"
{
//returns handle!=0 if successful, 0 if error
//size will return the final nb of bytes written to the output, -1 if unknown
__declspec( dllexport ) intptr_t winampGetExtendedRead_openW(const wchar_t *fn, int *size, int *bps, int *nch, int *srate) {
VorbisFile * f = VorbisFile::Create(fn,false);
if(f) {
if(!*bps) *bps=16; // FUCKO HAX
Decoder * d = new Decoder();
d->Init(f, *bps, *nch, false, false);
*nch = (int)d->nch;
*srate = (int)d->sr;
*bps = (int)d->bps;
*size = (int)(f->Length() * (double)((*nch) * (*srate) * (*bps/8)));
return (intptr_t)d;
}
return 0;
}
__declspec( dllexport ) intptr_t winampGetExtendedRead_openW_float(const wchar_t *fn, int *size, int *bps, int *nch, int *srate) {
VorbisFile * f = VorbisFile::Create(fn,false);
if(f) {
Decoder * d = new Decoder();
d->Init(f, *bps, *nch, true, false);
*nch = (int)d->nch;
*srate = (int)d->sr;
*bps = (int)d->bps;
*size = (int)(f->Length() * (double)((*nch) * (*srate) * (*bps/8)));
return (intptr_t)d;
}
return 0;
}
//returns nb of bytes read. -1 if read error (like CD ejected). if (ret<len), EOF is assumed
__declspec( dllexport ) intptr_t winampGetExtendedRead_getData(intptr_t handle, char *dest, size_t len, int *killswitch) {
Decoder * d = (Decoder *)handle;
size_t used = 0;
for(;;) {
used += (UINT)d->Read((UINT)(len - used),dest + used);
if(used >= len) break;
if(!d->DoFrame()) break;
if(*killswitch) break;
if (used)
return used;
}
return used;
}
// return nonzero on success, zero on failure.
__declspec( dllexport ) int winampGetExtendedRead_setTime(intptr_t handle, int millisecs) {
Decoder * d = (Decoder *)handle;
d->Flush();
return !d->Seek(((double)millisecs) / 1000.0);
}
__declspec( dllexport ) void winampGetExtendedRead_close(intptr_t handle) {
Decoder * d = (Decoder *)handle;
d->Flush();
delete d->file;
delete d;
}
}

View File

@ -1,264 +0,0 @@
#include "main.h"
#include "api__in_vorbis.h"
#include "resource.h"
#include <strsafe.h>
/*static UINT xiphframes_ids[12]={IDB_BITMAP1,IDB_BITMAP2,IDB_BITMAP3,IDB_BITMAP4,IDB_BITMAP5,IDB_BITMAP6,IDB_BITMAP7,IDB_BITMAP8,IDB_BITMAP9,IDB_BITMAP10,IDB_BITMAP11,IDB_BITMAP12};
static HBITMAP xiphframes[12];*/
static UINT xiphframes_ids[12]={IDB_PNG1,IDB_PNG2,IDB_PNG3,IDB_PNG4,IDB_PNG5,IDB_PNG6,IDB_PNG7,IDB_PNG8,IDB_PNG9,IDB_PNG10,IDB_PNG11,IDB_PNG12};
static ARGB32 *xiphframes[12] = {0};
static HBITMAP xiphframesBmp[12] = {0};
static void slap(HWND wnd,int v)
{
long hi=GetWindowLong(wnd,4);
if (v) hi+=v*1000;
else hi=0;
SetWindowLong(wnd,4,hi);
}
static CfgInt cfg_rpm("rpm",0);
static int visible_rpm,visible_max_rpm;
static char show_rpm=0;
static DWORD last_visible_rpm;
ARGB32 * loadImg(const void * data, int len, int *w, int *h, bool ldata=false)
{
FOURCC imgload = svc_imageLoader::getServiceType();
int n = (int)mod.service->service_getNumServices(imgload);
for(int i=0; i<n; i++)
{
waServiceFactory *sf = mod.service->service_enumService(imgload,i);
if(sf)
{
svc_imageLoader * l = (svc_imageLoader*)sf->getInterface();
if(l)
{
if(l->testData(data,len))
{
ARGB32* ret;
if(ldata) ret = l->loadImageData(data,len,w,h);
else ret = l->loadImage(data,len,w,h);
sf->releaseInterface(l);
return ret;
}
sf->releaseInterface(l);
}
}
}
return NULL;
}
ARGB32 * loadRrc(int id, wchar_t * sec, int *w, int *h, bool data=false)
{
DWORD size=0;
HGLOBAL resourceHandle = WASABI_API_LOADRESFROMFILEW(sec, MAKEINTRESOURCEW(id), &size);
if(resourceHandle)
{
ARGB32* ret = loadImg(resourceHandle,size,w,h,data);
UnlockResource(resourceHandle);
return ret;
}
return NULL;
}
static LRESULT WINAPI XiphProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
{
switch(msg)
{
case WM_CREATE:
SetWindowLong(wnd,8,last_visible_rpm=GetTickCount());
SetTimer(wnd,666,10,0);
visible_rpm=-1;
visible_max_rpm=-1;
show_rpm=0;
break;
case WM_TIMER:
if (wp==666)
{
long low=GetWindowLong(wnd,0);
long hi=GetWindowLong(wnd,4);
long org=low&~0xFFFF;
int rpm=MulDiv(abs(hi),1000*60,12*0x10000);
DWORD t=GetTickCount();
DWORD ot=(DWORD)SetWindowLong(wnd,8,t);
bool redraw=0;
if (rpm>25) show_rpm=1;
if (cfg_rpm<rpm) cfg_rpm=rpm;
if (show_rpm && (t&~0x3F)!=(ot&~0x3F))
{
wchar_t foo[128] = {0};
if (visible_rpm<rpm || (visible_rpm>rpm && (t-last_visible_rpm)>333))
{
last_visible_rpm=t;
visible_rpm=rpm;
StringCchPrintfW(foo,128,WASABI_API_LNGSTRINGW(IDS_GAME_SPEED),rpm);
SetDlgItemTextW(GetParent(wnd),IDC_RPM,foo);
}
if (visible_max_rpm!=cfg_rpm)
{
visible_max_rpm=cfg_rpm;
StringCchPrintfW(foo,128,WASABI_API_LNGSTRINGW(IDS_BEST_RPM),(int)cfg_rpm);
SetDlgItemTextW(GetParent(wnd),IDC_RPM2,foo);
}
}
low+=hi*(t-ot);
while(low<0) low+=12*0x10000;
while(low>=12*0x10000) low-=12*0x10000;
{
int z=hi>>6;
if (z) hi-=z;
else if (hi>0) hi--;
else if (hi<0) hi++;
}
SetWindowLong(wnd,0,low);
SetWindowLong(wnd,4,hi);
if (redraw || (low&~0xFFFF)!=org)
{
RedrawWindow(wnd,0,0,RDW_INVALIDATE);
}
KillTimer(wnd,666);
SetTimer(wnd,666,10,0);
}
break;
case WM_LBUTTONDOWN:
slap(wnd,-1);
break;
case WM_RBUTTONDOWN:
slap(wnd,1);
break;
case WM_MBUTTONDOWN:
slap(wnd,0);
break;
case WM_PAINT:
{
int i=(GetWindowLong(wnd,0))>>16;
HDC dc = CreateCompatibleDC(0);
if (!xiphframesBmp[i])
{
int cur_w = 0, cur_h = 0;
xiphframes[i] = loadRrc(xiphframes_ids[i], L"PNG", &cur_w, &cur_h, true);
BITMAPINFO bmi = {0};
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = cur_w;
bmi.bmiHeader.biHeight = -cur_h;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
void *bits = 0;
if(xiphframesBmp[i]) DeleteObject(xiphframesBmp[i]);
xiphframesBmp[i] = CreateDIBSection(dc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
memcpy(bits, xiphframes[i], cur_w * cur_h * 4);
}
if (xiphframesBmp[i])
{
HGDIOBJ foo = SelectObject(dc, xiphframesBmp[i]);
HDC wdc = GetDC(wnd);
RECT r = {0};
GetClientRect(wnd, &r);
FillRect(wdc, &r, GetSysColorBrush(COLOR_3DFACE));
BLENDFUNCTION blendFn = {0};
blendFn.BlendOp = AC_SRC_OVER;
blendFn.SourceConstantAlpha = 255;
blendFn.AlphaFormat = AC_SRC_ALPHA;
AlphaBlend(wdc, 2, 2, r.right - 2, r.bottom - 2, dc, 0, 0, 63, 63, blendFn);
ReleaseDC(wnd, wdc);
SelectObject(dc, foo);
}
DeleteDC(dc);
}
break;
case WM_DESTROY:
{
for (int i = 0; i < ARRAYSIZE(xiphframes_ids); i++)
{
if(xiphframesBmp[i]) DeleteObject(xiphframesBmp[i]); xiphframesBmp[i] = 0;
if(xiphframes[i] && WASABI_API_MEMMGR) WASABI_API_MEMMGR->sysFree((void *)xiphframes[i]); xiphframes[i] = 0;
}
KillTimer(wnd,666);
break;
}
};
return DefWindowProc(wnd,msg,wp,lp);
}
static BOOL CALLBACK AboutProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
{
switch(msg)
{
case WM_INITDIALOG:
{
wchar_t tmp[1024] = {0}, tmp2[1024] = {0}, *t1 = tmp, *t2 = tmp2, text[1024] = {0};
SetWindowTextW(wnd,WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_VORBIS_DECODER_OLD,text,1024));
StringCchPrintfW(tmp,1024,WASABI_API_LNGSTRINGW(IDS_ABOUT_TEXT),mod.description,__DATE__);
// due to quirks with the more common resource editors, is easier to just store the string
// internally only with \n and post-process to be \r\n (as here) so it will appear correctly
// on new lines as is wanted (silly multiline edit controls)
while(t1 && *t1 && (t2 - tmp2 < 1024))
{
if(*t1 == L'\n')
{
*t2 = L'\r';
t2 = CharNextW(t2);
}
*t2 = *t1;
t1 = CharNextW(t1);
t2 = CharNextW(t2);
}
SetDlgItemTextW(wnd,IDC_ABOUT_TEXT,tmp2);
// fixes the incorrect selection of the text on dialog opening
PostMessage(GetDlgItem(wnd,IDC_ABOUT_TEXT),EM_SETSEL,-1,0);
return 1;
}
case WM_COMMAND:
if (wp==IDOK || wp==IDCANCEL)
{
do_cfg(1);
EndDialog(wnd,0);
}
break;
}
return 0;
}
void About(HWND hwndParent)
{
static char got_xiph;
if (!got_xiph)
{
WNDCLASS wc=
{
0,
XiphProc,
0,
12,
WASABI_API_LNG_HINST,
0,
LoadCursor(0,IDC_ARROW),
0,
0,
L"XIPH_CLASS",
};
RegisterClassW(&wc);
got_xiph=1;
}
WASABI_API_DIALOGBOXW(IDD_ABOUT,hwndParent,AboutProc);
}

View File

@ -1,21 +0,0 @@
#ifndef NULLSOFT_API_H
#define NULLSOFT_API_H
#include "../Agave/Config/api_config.h"
#include "../Agave/Language/api_language.h"
#include <api/application/api_application.h>
extern api_application *applicationApi;
#define WASABI_API_APP applicationApi
#include <api/service/svcs/svc_imgload.h>
#include <api/service/api_service.h>
#include <api/service/waServiceFactory.h>
#include <api/memmgr/api_memmgr.h>
extern api_memmgr *memmgrApi;
#define WASABI_API_MEMMGR memmgrApi
#endif

View File

@ -1,96 +0,0 @@
#define STRICT
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#include "c_string.h"
#include "../nu/ns_wc.h"
extern BOOL is_nt;
template<class myChar>
void string_base<myChar>::makespace(UINT s)
{
if (size<s)
{
int oldSize = size;
do size<<=1; while(size<s);
myChar *newPtr = (myChar*)realloc(ptr,size*sizeof(myChar));
if (!newPtr)
{
newPtr = (myChar*)malloc(size*sizeof(myChar));
if (newPtr)
{
memcpy(newPtr, ptr, oldSize*sizeof(myChar));
free(ptr);
ptr = newPtr;
}
else return ;
}
else ptr = newPtr;
}
}
void String::s_GetWindowText(HWND w)
{
Reset();
int len=GetWindowTextLengthA(w)+1;
GetWindowTextA(w,StringTempA(*this,len),len);
}
void StringW::s_GetWindowText(HWND w)
{
Reset();
int len=GetWindowTextLengthW(w)+1;
GetWindowTextW(w,StringTempW(*this,len),len);
}
void String::SetStringW(const WCHAR * c)
{
UINT len=(lstrlenW(c)+1)*2;
WideCharToMultiByteSZ(CP_ACP,0,c,-1,StringTempA(*this,len),len,0,0);
}
void StringW::SetStringA(const char * c)
{
UINT len=(UINT)strlen(c)+1;
MultiByteToWideCharSZ(CP_ACP,0,c,-1,StringTempW(*this,len),len);
}
void String::AddStringW(const WCHAR * c)
{
AddString(String(c));
}
void StringW::AddStringA(const char * c)
{
AddString(StringW(c));
}
void String::s_SetWindowText(HWND w)
{
SetWindowTextA(w,*this);
}
void StringW::s_SetWindowText(HWND w)
{
SetWindowTextW(w,*this);
}
StringPrintf::StringPrintf(const char * fmt,...)
{
va_list list;
va_start(list,fmt);
vsprintf(StringTempA(*this,1024),fmt,list);
va_end(list);
}
StringPrintfW::StringPrintfW(const WCHAR * fmt,...)
{
va_list list;
va_start(list,fmt);
vswprintf(StringTempW(*this,1024),1024,fmt,list);
va_end(list);
}
String::String(const StringW & z) {AddStringW(z);}

View File

@ -1,156 +0,0 @@
#pragma once
template <class myChar>
class string_base
{
private:
myChar * ptr;
UINT size,used;
void makespace(UINT s);
static UINT mylen(const myChar * p) {UINT r=0;while(p[r]) r++;return r;}
public:
void AddChar(myChar c)
{
makespace(used+2);
ptr[used++]=c;
ptr[used]=0;
}
string_base()
{
used=0;
size=128;
ptr=(myChar*)malloc(size*sizeof(myChar));
ptr[0]=0;
}
~string_base() { if (ptr) free(ptr);}
operator const myChar*() const {return ptr;}
const myChar & operator*() const {return *ptr;}
UINT Length() const {return used;}
void AddString(const myChar * c)
{
UINT d=mylen(c);
makespace(used+d+1);
memcpy(ptr+used,c,sizeof(myChar)*d);
used+=d;
ptr[used]=0;
}
void Reset() {Truncate(0);}
void Truncate(UINT x) {if (used>x) {used=x;ptr[x]=0;}}
void SetString(const myChar * s) {Reset();AddString(s);}
myChar * BufferStart(UINT n)
{
makespace(n+1);
memset(ptr,0,size);
return ptr;
}
inline void BufferDone() {used=mylen(ptr);}
void SetChar(UINT offset,myChar c)//hack for some ghey routines
{
if (!c) Truncate(offset);
else if (offset<used) ptr[offset]=c;
}
};
template<class myChar>
class StringTemp
{
private:
string_base<myChar> * parent;
myChar * data;
public:
StringTemp(string_base<myChar> & s,UINT siz) {parent=&s;data=s.BufferStart(siz);}
~StringTemp() {parent->BufferDone();}
operator myChar* () {return data;}
};
#define StringTempW StringTemp<WCHAR>
#define StringTempA StringTemp<char>
class StringW;
class String : public string_base<char>
{
public:
String() {}
String(HWND w) {s_GetWindowText(w);}
String(const char* z) {SetString(z);}
String(const WCHAR* z) {SetStringW(z);}
String(const String& z) {SetString(z);}
String(const StringW& z);
void AddStringW(const WCHAR * c);
void SetStringW(const WCHAR * c);
void s_GetWindowText(HWND w);
void s_SetWindowText(HWND w);
void operator=(const char * s) {SetString(s);}
void operator+=(const char * s) {AddString(s);}
void operator=(String & s) {SetString(s);}
void operator+=(String & s) {AddString(s);}
inline void s_GetDlgItemText(HWND w,UINT id) {s_GetWindowText(GetDlgItem(w,id));}
inline void s_SetDlgItemText(HWND w,UINT id) {s_SetWindowText(GetDlgItem(w,id));}
};
class StringW : public string_base<WCHAR>
{
public:
StringW() {}
StringW(HWND w) {s_GetWindowText(w);}
StringW(const WCHAR * z) {SetString(z);}
void AddStringA(const char * c);
void SetStringA(const char * c);
StringW(const char * z) {SetStringA(z);}
StringW(const StringW & z) {SetString(z);}
StringW(const String & z) {SetStringA(z);}
void s_GetWindowText(HWND w);
void s_SetWindowText(HWND w);
void operator=(const WCHAR * s) {SetString(s);}
void operator+=(const WCHAR * s) { if (s) AddString(s);}
void operator=(StringW & s) {SetString(s);}
void operator+=(StringW & s) {AddString(s);}
inline void s_GetDlgItemText(HWND w,UINT id) {s_GetWindowText(GetDlgItem(w,id));}
inline void s_SetDlgItemText(HWND w,UINT id) {s_SetWindowText(GetDlgItem(w,id));}
bool reg_read(const char *name);
void reg_write(const char *name);
};
class StringPrintf : public String
{
public:
StringPrintf(const char * fmt,...);
};
class StringPrintfW : public StringW
{
public:
StringPrintfW(const WCHAR * fmt,...);
};
template<class myChar>
class StringF2T : public string_base<myChar>
{
public:
StringF2T(const myChar * fn)
{
const myChar * ptr=fn,*dot=0,*src=fn;
while(ptr && *ptr)
{
if (*ptr=='\\' || *ptr=='/' || *ptr==':') src=ptr+1;
else if (*ptr=='.') dot=ptr;
ptr++;
}
while(src && *src && (!dot || src<dot)) AddChar(*(src++));
}
};
#define StringF2T_A StringF2T<char>
#define StringF2T_W StringF2T<WCHAR>

View File

@ -1,82 +0,0 @@
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <ogg/ogg.h>
#include <vorbis/vorbisfile.h>
static size_t callback_fread(void *ptr, size_t size, size_t nmemb, HANDLE hFile)
{
DWORD bw = 0;
ReadFile(hFile,ptr,(DWORD)(size*nmemb),&bw,0);
return bw/size;
}
static size_t callback_write(void * ptr, size_t size, size_t nmemb, HANDLE hFile)
{
DWORD bw = 0;
WriteFile(hFile,ptr,(DWORD)(size*nmemb),&bw,0);
return bw/size;
}
static int callback_fseek(HANDLE hFile, __int64 offset, int whence)
{
__int64 temp = offset;
SetFilePointer(hFile,*(DWORD*)&temp,((long*)&temp+1),whence);
return 0;
}
static int callback_fclose(HANDLE f)
{
return 0;
}
static __int64 callback_ftell(HANDLE hFile)
{
__int64 ret=0;
*(DWORD*)&ret = SetFilePointer(hFile,0,((long*)&ret+1),FILE_CURRENT);
return ret;
}
static void* callbacks[4]=
{
callback_fread,callback_fseek,callback_fclose,callback_ftell
};
namespace ogg_helper
{
int num_get_tracks(HANDLE hFile/*track_indexer::callback * out,reader * r*/)
{
SetFilePointer(hFile,0,0,FILE_BEGIN);
OggVorbis_File l_vf;
memset(&l_vf,0,sizeof(l_vf));
if (ov_open_callbacks(hFile,&l_vf,0,0,*(ov_callbacks*)callbacks))
{
return 0;
}
int rv = l_vf.links;
ov_clear(&l_vf);
return rv;
}
int query_chained_stream_offset(HANDLE hFile,int idx,__int64 * out_beginning,__int64 * out_end)
{
SetFilePointer(hFile,0,0,FILE_BEGIN);
OggVorbis_File l_vf;
memset(&l_vf,0,sizeof(l_vf));
if (ov_open_callbacks(hFile,&l_vf,0,0,*(ov_callbacks*)callbacks))
{
return 0;
}
int retval = 0;
if (idx>=0 && idx<l_vf.links)
{
retval = 1;
*out_beginning = l_vf.offsets[idx];
*out_end = l_vf.offsets[idx+1];
}
ov_clear(&l_vf);
return retval;
}
}

View File

@ -1,335 +0,0 @@
#include "main.h"
#include "api__in_vorbis.h"
#include "../nu/ns_wc.h"
#include <commctrl.h>
#include <shlobj.h>
#include "../winamp/wa_ipc.h"
#include "../nu/AutoChar.h"
#include <strsafe.h>
int mc6_dm_names_ids[]={IDS_LEAVE_AS_IS,IDS_REMAP_6_CHANNELS,IDS_DOWNMIX_TO_4_CHANNELS,IDS_DOWNMIX_TO_2_CHANNELS_DS,IDS_DOWNMIX_TO_2_CHANNELS_DS2,IDS_DOWNMIX_TO_MONO};
int mc6_map_names_id[]={IDS_CORRECT_FL_FC_FR_BL_BR_LFE,IDS_BROKEN_FL_FR_FC_BL_BR_LFE};
int32_t priority_tab[7]={THREAD_PRIORITY_IDLE,THREAD_PRIORITY_LOWEST,THREAD_PRIORITY_BELOW_NORMAL,THREAD_PRIORITY_NORMAL,THREAD_PRIORITY_ABOVE_NORMAL,THREAD_PRIORITY_HIGHEST,THREAD_PRIORITY_TIME_CRITICAL};
char* defaultDumpDir()
{
static char dumpdir[MAX_PATH] = {0};
if(FAILED(SHGetFolderPathA(NULL, CSIDL_MYMUSIC, NULL, SHGFP_TYPE_CURRENT, dumpdir)))
{
if(FAILED(SHGetFolderPathA(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, dumpdir)))
{
lstrcpynA(dumpdir, "C:\\", MAX_PATH);
}
}
return dumpdir;
}
CfgString
cfg_ssave_format("ssave_format","%filename%"),
cfg_dumpdir("dumpdir",defaultDumpDir());
CfgInt
cfg_http_bsize("http_bsize",0x10000),
cfg_fsave("fsave",0),
cfg_abr("abr",0),
cfg_proxy_mode("proxy_mode",2),
cfg_prebuf1("prebuf1",50),
cfg_prebuf2("prebuf2",75),
cfg_httpseek2("httpseek2",0),
cfg_fix0r("fix0r",1),
cfg_mc6_dm("mc6_dm",0),
cfg_mc6_map("_mc6_map",0),
cfg_remember_infosize("remember_infosize",1),
cfg_fullbuf("fullbuf",0),
cfg_cur_tab("cur_tab",0);
static int old_preamp;
CfgFont cfg_font("font");
static LOGFONT cfg_font_edit;
BOOL CALLBACK browseEnumProc(HWND hwnd, LPARAM lParam)
{
char cl[32] = {0};
GetClassNameA(hwnd, cl, ARRAYSIZE(cl));
if (!lstrcmpiA(cl, WC_TREEVIEWA))
{
PostMessage(hwnd, TVM_ENSUREVISIBLE, 0, (LPARAM)TreeView_GetSelection(hwnd));
return FALSE;
}
return TRUE;
}
static int CALLBACK browzaproc(HWND hwnd, UINT msg, LPARAM lp, LPARAM dat)
{
if (msg == BFFM_INITIALIZED)
{
SendMessageW(hwnd, BFFM_SETSELECTIONW, 1, (LPARAM)dat);
// this is not nice but it fixes the selection not working correctly on all OSes
EnumChildWindows(hwnd, browseEnumProc, 0);
}
return 0;
}
static void d_browza(HWND wnd,HWND bt,wchar_t* tx)
{
IMalloc* pMalloc=0;
SHGetMalloc(&pMalloc);
if (!pMalloc) return;
wchar_t dir[MAX_PATH] = {0};
GetWindowTextW(bt,dir,MAX_PATH);
BROWSEINFOW bi=
{
wnd,
0,
0,
tx,
BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE,
browzaproc,
(LPARAM)dir,
0
};
ITEMIDLIST* li=SHBrowseForFolderW(&bi);
if (li)
{
SHGetPathFromIDListW(li,dir);
SetWindowTextW(bt,dir);
pMalloc->Free(li);
}
pMalloc->Release();
}
static BOOL CALLBACK CfgProc1(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
{
switch(msg)
{
case WM_INITDIALOG:
{
wchar_t temp[128] = {0}, cfg_dialog_name[128] = {0};
StringCchPrintfW(cfg_dialog_name,128,WASABI_API_LNGSTRINGW(IDS_TITLE_PREFERENCES),
WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_VORBIS_DECODER_OLD, temp, 128));
SetWindowTextW(wnd,cfg_dialog_name);
SendDlgItemMessage(wnd,IDC_FULLBUF,BM_SETCHECK,cfg_fullbuf,0);
UINT n;
HWND w=GetDlgItem(wnd,IDC_MC6_DM);
for(n=0;n<sizeof(mc6_dm_names_ids)/sizeof(mc6_dm_names_ids[0]);n++)
{
SendMessageW(w,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(mc6_dm_names_ids[n]));
}
SendMessage(w,CB_SETCURSEL,cfg_mc6_dm,0);
w=GetDlgItem(wnd,IDC_MC6_MAP);
for(n=0;n<sizeof(mc6_map_names_id)/sizeof(mc6_map_names_id[0]);n++)
{
SendMessageW(w,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(mc6_map_names_id[n]));
}
SendMessage(w,CB_SETCURSEL,cfg_mc6_map,0);
SendDlgItemMessage(wnd,IDC_AVG_BR,BM_SETCHECK,cfg_abr,0);
SetDlgItemInt(wnd,IDC_HTTP_BSIZE,cfg_http_bsize>>10,0);
if (cfg_fsave) SendDlgItemMessage(wnd,IDC_FSAVE,BM_SETCHECK,1,0);
if (cfg_fix0r) SendDlgItemMessage(wnd,IDC_FIX0R,BM_SETCHECK,1,0);
cfg_dumpdir.s_SetDlgItemText(wnd,IDC_STREAM_SAVE);
w=GetDlgItem(wnd,IDC_PROXY);
SendMessageW(w,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(IDS_NEVER));
SendMessageW(w,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(IDS_PORT_80_ONLY));
SendMessageW(w,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(IDS_ALWAYS));
SendMessage(w,CB_SETCURSEL,cfg_proxy_mode,0);
w=GetDlgItem(wnd,IDC_SLIDER1);
SendMessage(w,TBM_SETRANGE,0,MAKELONG(1,100));
SendMessage(w,TBM_SETPOS,1,cfg_prebuf1);
w=GetDlgItem(wnd,IDC_SLIDER2);
SendMessage(w,TBM_SETRANGE,0,MAKELONG(1,100));
SendMessage(w,TBM_SETPOS,1,cfg_prebuf2);
cfg_ssave_format.s_SetDlgItemText(wnd,IDC_SSAVE_FMT);
SendMessage(wnd,WM_COMMAND,MAKEWPARAM(IDC_FSAVE,BN_CLICKED),(LPARAM)GetDlgItem(wnd,IDC_FSAVE));
}
return 1;
case WM_COMMAND:
switch(LOWORD(wp))
{
case IDC_STREAM_SAVE:
d_browza(wnd,(HWND)lp,WASABI_API_LNGSTRINGW(IDS_SELECT_OUTPUT_DIRECTORY));
break;
case IDC_SSAVE_FMT_DEF:
SetDlgItemText(wnd,IDC_SSAVE_FMT,L"%filename%");
break;
case IDC_FSAVE:
{
int checked = IsDlgButtonChecked(wnd,IDC_FSAVE);
EnableWindow(GetDlgItem(wnd,IDC_STREAM_SAVE),checked);
EnableWindow(GetDlgItem(wnd,IDC_SSAVE_FMT),checked);
EnableWindow(GetDlgItem(wnd,IDC_SSAVE_FMT_DEF),checked);
}
break;
case IDOK:
case IDCANCEL:
{
if (LOWORD(wp) == IDOK)
{
cfg_fullbuf=(int)SendDlgItemMessage(wnd,IDC_FULLBUF,BM_GETCHECK,0,0);
cfg_mc6_dm=(int)SendDlgItemMessage(wnd,IDC_MC6_DM,CB_GETCURSEL,0,0);
cfg_mc6_map=(int)SendDlgItemMessage(wnd,IDC_MC6_MAP,CB_GETCURSEL,0,0);
cfg_abr=(int)SendDlgItemMessage(wnd,IDC_AVG_BR,BM_GETCHECK,0,0);
cfg_dumpdir.s_GetDlgItemText(wnd,IDC_STREAM_SAVE);
cfg_http_bsize=GetDlgItemInt(wnd,IDC_HTTP_BSIZE,0,0)<<10;
cfg_fsave=(int)SendDlgItemMessage(wnd,IDC_FSAVE,BM_GETCHECK,0,0);
cfg_fix0r=(int)SendDlgItemMessage(wnd,IDC_FIX0R,BM_GETCHECK,0,0);
cfg_proxy_mode=(int)SendDlgItemMessage(wnd,IDC_PROXY,CB_GETCURSEL,0,0);
cfg_prebuf1=(int)SendDlgItemMessage(wnd,IDC_SLIDER1,TBM_GETPOS,0,0);
cfg_prebuf2=(int)SendDlgItemMessage(wnd,IDC_SLIDER2,TBM_GETPOS,0,0);
cfg_ssave_format.s_GetDlgItemText(wnd,IDC_SSAVE_FMT);
}
do_cfg(1);
EndDialog(wnd,(LOWORD(wp) == IDOK));
}
break;
}
break;
}
const int controls[] =
{
IDC_SLIDER1,
IDC_SLIDER2,
};
if (FALSE != WASABI_API_APP->DirectMouseWheel_ProcessDialogMessage(wnd, msg, wp, lp, controls, ARRAYSIZE(controls)))
{
return TRUE;
}
return 0;
}
extern HANDLE hThread;//hack
void Config(HWND p)
{
if (WASABI_API_DIALOGBOXPARAMW(IDD_CONFIG,p,CfgProc1,0))
{
if (hThread) PostMessage(mod.hMainWindow,WM_USER,0,243);
}
}
int CfgVar::read_int(const char *inifile, const char *section,const char * name,int def)
{
return GetPrivateProfileIntA(section, name, def, inifile);
}
void CfgVar::write_int(const char *inifile, const char *section, const char * name,int val)
{
char temp[32] = {0};
StringCchPrintfA(temp, 32, "%d", val);
WritePrivateProfileStringA(section, name, temp, inifile);
}
void CfgVar::write_struct(const char *inifile, const char *section, const char * name, void * ptr,UINT size)
{
WritePrivateProfileStructA("in_vorbis", name, ptr, size, INI_FILE);
}
bool CfgVar::read_struct(const char *inifile, const char *section, const char * name,void * ptr,UINT size)
{
return !!GetPrivateProfileStructA("in_vorbis", name, ptr, size, INI_FILE);
}
void do_cfg(int s)
{
#define CFG_VERSION 0x10204
if (!s)
{
if (CfgVar::read_int(INI_FILE, "in_vorbis", "version",0)==CFG_VERSION)
CfgVar::ReadConfig();
}
else
{
CfgVar::WriteConfig();
CfgVar::write_int(INI_FILE, "in_vorbis", "version",CFG_VERSION);
}
}
CfgVar * CfgVar::list=0;
void CfgVar::ReadConfig()
{
CfgVar * p=list;
while(p)
{
p->Read(p->name);
p=p->next;
}
}
void CfgVar::WriteConfig()
{
CfgVar * p=list;
while(p)
{
p->Write(p->name);
p=p->next;
}
}
bool StringW::reg_read(const char * name)
{
char utf8_data[2048] = {0};
wchar_t utf16_data[2048] = {0};
GetPrivateProfileStringA("in_vorbis", name, "@default@", utf8_data, 2048, INI_FILE);
if (!strcmp("@default@", utf8_data))
return false;
MultiByteToWideCharSZ(CP_UTF8, 0, utf8_data, -1, utf16_data, 2048);
SetString(utf16_data);
return true;
}
void StringW::reg_write(const char * name)
{
WritePrivateProfileStringA("in_vorbis", name, AutoChar((const WCHAR *)*this, CP_UTF8), INI_FILE);
}
void CfgString::Read(const char * name)
{
reg_read(name);
}
void CfgString::Write(const char * name)
{
StringW temp;
if (temp.reg_read(name))
{
if (wcscmp(temp,*this)) reg_write(name);
}
else
{
if (wcscmp(def,*this)) reg_write(name);
}
}
void CfgInt::Write(const char * name)
{
if (read_int(INI_FILE, "in_vorbis", name,def)!=value) write_int(INI_FILE, "in_vorbis",name,value);
}
void CfgInt::Read(const char * name)
{
value=read_int(INI_FILE, "in_vorbis", name,def);
}

View File

@ -1,567 +0,0 @@
/* Winamp 3 Player core api v0.1
** (c)2000 nullsoft jcf/ct/dk
** Notes:
** Keep in mind that this header file is subject to change prior to the
** release of Winamp 3. The ability to configure plug-ins has yet to be
** added and is the first and foremost concern of the engineering team.
*/
#ifndef __CORE_API_H
#define __CORE_API_H
/*
// Visual C 6 makes big unaligned dlls. the following will correct it
#ifndef _DEBUG
// release optimizations
// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers)
#pragma optimize("gsy",on)
#pragma comment(linker,"/RELEASE")
// set the 512-byte alignment
#pragma comment(linker,"/opt:nowin98")
#endif
*/
// Use Assert in your code to catch errors that shouldn't happen, when compiled in release mode, they are #defined out
#ifndef ASSERT
#ifdef _DEBUG
#define ASSERT(x) if (!(x)) MessageBox(NULL,"ASSERT FAILED: " #x,"ASSERT FAILED in " __FILE__ ,MB_OK|MB_ICONSTOP);
#else
#define ASSERT(x)
#endif
#endif
/* CLASS DESCRIPTIONS */
/* WReader
** File reader module class, ie. opens and reads files, streams
*/
class WReader;
/* WInputInfo
** Class that returns information (length, title, metadata) about a specified file
*/
class WInputInfo;
/* WInfo_callback
** Player's interface that provides Winamp 3 core functions to your WInputInfo classes
*/
class WInfo_callback;
/* WInputSource
** Input Source manager base class, ie. decodes mp3's, wavs
*/
class WInputSource;
/* WOutputFilter
** Abstract base class for any Output Filter plug-in, ie. changes pitch, converts format, outputs to speakers
*/
class WOutputFilter;
/* WPlayer_callback
** Player's interface that provides Winamp 3 core functions to your Input Sources and Output Filter plug-ins
** (Getting a reader for opening a file, sending stuff about what's going on to the Winamp 3 core)
*/
class WPlayer_callback;
class WPlayer_callback
{
public:
/* GetReader
** Allows your Input Source and Output Filter plugins to request a reader from Winamp,
** so you don't have to worry about opening files or streams
*/
virtual WReader *GetReader(char *url)=0;
/* The 3 following functions allows your Input Source and Output Filter plugins to send error/warning/status
** messages back to the Winamp 3 core
*/
/* Error
** playback should stop (soundcard driver error, etc)
*/
virtual void Error(char *reason)=0;
/* Warning
** warning (something recoverable, like file not found, etc)
*/
virtual void Warning(char *warning)=0;
/* Status
** status update (nothing really wrong)
*/
virtual void Status(char *status)=0;
/* TitleChange
** should be called if the current file titlename changes during the decoding
*/
virtual void TitleChange(char *new_title)=0;
/* InfoChange
** should be called if the infos about the current file changes during the decoding
*/
virtual void InfoChange(char *new_info_str, int new_length)=0;
/* UrlChange
** should be called if the current file associated URL changes during the decoding
*/
virtual void UrlChange(char *new_url)=0;
};
class WInfo_callback
{
public:
/* GetReader
** Allows your WInfo classes to request a reader from Winamp
** so you don't have to worry about opening files or streams
*/
virtual WReader *GetReader(char *url)=0;
};
class WInputInfo
{
public:
/* WInputInfo
** WInputInfo constructor
*/
WInputInfo(){ };
/* m_info
** Filled by Winamp. Pointer to WInputInfo callback function
*/
WInfo_callback *m_info;
/* Open
** Called by Winamp to request informations about a specified media (file, url, etc...)
** returns 0 if succesful, 1 if not
**
** You must open, get all information and close the specified file here and store
** the useful information into member elements for quick access by other functions
*/
virtual int Open(char *url) { return 1; }
/* GetTitle
** Called by Winamp to get the decoded title about the file opened
** i.e. id3 title name, etc...
*/
virtual void GetTitle(char *buf, int maxlen) { if (maxlen>0) buf[0]=0; };
/* GetInfoString
** Called by Winamp to get extra informations about the file opened
** i.e. "160kbps stereo 44Khz" for MP3 files,"4 channels" for MOD files,etc...
*/
virtual void GetInfoString(char *buf, int maxlen) { if (maxlen>0) buf[0]=0; };
/* GetLength
** Called by Winamp to retrieves media type length in milliseconds
** returns -1 if length is undefined/infinite
*/
virtual int GetLength(void) { return -1; };
/* GetMetaData
** Fetches metadata by attribute name (Artist, Album, Bitrate, etc...)
** attribute names are non case-sensitive.
** returns size of data
*/
virtual int GetMetaData(char *name, char *data, int data_len) { if (data&&data_len>0) *data=0; return 0; }
/* ~WInputInfo
** WInputInfo virtual destructor
*/
//virtual ~WInputInfo() { };
virtual void Release(int)=0;
};
/* WINAMP Output Filter NOTIFY MESSAGES
** Messages returned to notify Output Filter plug-ins of events
*/
typedef enum {
/* WOFNM_FILETITLECHANGE
** Sent when the song changes
** param1=new filename song
** param2=new title song
*/
WOFNM_FILETITLECHANGE=1024,
/* WOFNM_ENDOFDECODE
** Sent when decoding ends
*/
WOFNM_ENDOFDECODE,
} WOutputFilterNotifyMsg;
class WOutputFilter
{
protected:
/* WOutputFilter
** WOutputFilter constructor
*/
WOutputFilter() { m_next=NULL; };
public:
/* m_player
** Filled by Winamp. Pointer to Winamp 3 core player interface
*/
WPlayer_callback *m_player;
/* m_next
** Internally used by Winamp. Pointer to next activated Output Filter
*/
WOutputFilter *m_next;
/* ~WOutputFilter
** WOutputFilter destructor
*/
//virtual ~WOutputFilter() { };
virtual void Release(int)=0;
/* GetDescription
** Retrieves your plug-in's text description
*/
virtual char *GetDescription() { return "Unknown"; };
/* ProcessSamples
** Render data as it receives it
** sampledata: Data to process
** bytes: number of bytes to process
** bps: Bits per sample (8 or 16)
** nch: Number of channels (1 or 2)
** srate: Sample rate in Hz
** killswitch: Will be set to 1 by winamp if stop if requested. Poll the pointed value very often to
** make sure Winamp doesn't hang
**
** Returns the number of processed bytes or -1 if unable to open the device or an error occured.
**
** You have to open your device (ie. Directsound) the first time this function is called.
*/
virtual int ProcessSamples(char *sampledata, int bytes, int *bps, int *nch, int *srate, bool *killswitch) { return bytes; }
/* FlushSamples
** Flushes output buffers so that all is written
*/
virtual void FlushSamples(bool *killswitch) { };
/* Restart
** Called by Winamp after a seek
*/
virtual void Restart(void) { }
/* GetLatency
** Returns < 0 for a final output latency, > 0 for an additive
*/
virtual int GetLatency(void) { return 0; }
/* Pause
** Suspends output
*/
virtual void Pause(int pause) { }
/* ShutDown
** Completely stops output
**
** Close your device here (not in destructor)
*/
virtual void ShutDown(void) { }
/* SetVolume
** Sets the volume (0 to 255)
** return 1 if volume successfully modified
*/
virtual int SetVolume(int volume) { return 0; }
/* SetPan
** Sets Left-Right sound balance (-127 to 127)
** return 1 if pan successfully modified
*/
virtual int SetPan(int pan) { return 0; }
/* Notify
** Called by Winamp to notify what's going on
*/
virtual void Notify(WOutputFilterNotifyMsg msg, int data1, int data2) { }
};
class WInputSource
{
protected:
/* WInputSource
** WInputSource constructor
*/
WInputSource(){ };
public:
/* m_player
** Filled by Winamp. Pointer to Winamp 3 core interface
*/
WPlayer_callback *m_player;
/* GetDescription
** Retrieves your plug-in's text description
*/
virtual char *GetDescription() { return "Unknown"; };
/* UsesOutputFilters
** Returns whether or not the Output Filter pipeline can be used
*/
virtual int UsesOutputFilters(void) { return 1; }
/* Open
** Used to open and prepare input media type
*/
virtual int Open(char *url, bool *killswitch)=0;
/* GetSamples
** This function must fill bps, nch and srate.
** Here, you have to fill the sample_buffer with decoded data. Be sure to fill it with the specified
** size (bytes). Use an internal buffer, etc ...
**
** sample_buffer: buffer to put decoded data into
** bytes: size of the sample_buffer
** bps: Bits par sample (8 or 16)
** nch: Number of channels (1 or 2)
** srate: Sample rate in Hz
** killswitch: Will be set to 1 by winamp if stop if requested. Poll the pointed value very often to
** make sure Winamp doesn't hang
*/
virtual int GetSamples(char *sample_buffer, int bytes, int *bps, int *nch, int *srate, bool *killswitch)=0;
/* SetVolume
** Sets the volume (0 to 255)
** Return 1 if volume has been set
*/
virtual int SetVolume(int volume) { return 0; };
/* SetPan
** Sets Left-Right sound balance (-127 to 127)
** return 1 if pan successfully modified
*/
virtual int SetPan(int pan) { return 0; };
/* SetPosition
** Sets position in ms. returns 0 on success, 1 if seek impossible
*/
virtual int SetPosition(int)=0;
/* Pause
** Suspends input
*/
virtual void Pause(int pause) { };
/* GetPosition
** Retrieve position in milliseconds
*/
virtual int GetPosition(void) { return 0; }
/* GetTitle
** Called by Winamp to get the decoded title about the file opened
** i.e. stream name, id3 title name, etc...
*/
virtual void GetTitle(char *buf, int maxlen) { if(maxlen>0) buf[0]=0; };
/* GetInfoString
** Called by Winamp to get extra informations about the file openend
** i.e. "32kbps 44khz", etc...
*/
virtual void GetInfoString(char *buf, int maxlen) { if(maxlen>0) buf[0]=0; };
/* GetLength
** Called by Winamp to retrieves media type length in milliseconds
** returns -1 if length is undefined/infinite
*/
virtual int GetLength(void) { return -1; }
/* ~WInputSource
** ~WInputSource virtual destructor
*/
//virtual ~WInputSource() { };
virtual void Release(int)=0;
};
class WReader
{
protected:
/* WReader
** WReader constructor
*/
WReader() { }
public:
/* m_player
** Filled by Winamp. Pointer to Winamp 3 core interface
*/
WPlayer_callback *m_player;
/* GetDescription
** Retrieves your plug-in's text description
*/
virtual char *GetDescription() { return "Unknown"; };
/* Open
** Used to open a file, return 0 on success
*/
virtual int Open(char *url, bool *killswitch)=0;
/* Read
** Returns number of BYTES read (if < length then eof or killswitch)
*/
virtual int Read(char *buffer, int length, bool *killswitch)=0;
/* GetLength
** Returns length of the entire file in BYTES, return -1 on unknown/infinite (as for a stream)
*/
virtual int GetLength(void)=0;
/* CanSeek
** Returns 1 if you can skip ahead in the file, 0 if not
*/
virtual int CanSeek(void)=0;
/* Seek
** Jump to a certain absolute position
*/
virtual int Seek(int position, bool *killswitch)=0;
/* GetHeader
** Retrieve header. Used in read_http to retrieve the HTTP header
*/
virtual char *GetHeader(char *name) { return 0; }
/* ~WReader
** WReader virtual destructor
*/
//virtual ~WReader() { }
virtual void Release(int)=0;
};
/* DLL PLUGINS EXPORT STRUCTURES */
#define READ_VER 0x100
#define IN_VER 0x100
#define OF_VER 0x100
typedef struct
{
/* version
** Version revision number
*/
int version;
/* description
** Text description of the reader plug-in
*/
char *description;
/* create
** Function pointer to create a reader module
*/
WReader *(*create)();
/* ismine
** Determines whether or not a file should be read by this plug-in
*/
int (*ismine)(char *url);
} reader_source;
typedef struct
{
/* version
** Version revision number
*/
int version;
/* description
** Text description of the input plug-in
*/
char *description;
/* extension_list
** Defines all the supported filetypes by this input plug-in
** In semicolon delimited format ("ext;desc;ext;desc" etc).
*/
char *extension_list;
/* ismine
** called before extension checks, to allow detection of tone://,http://, etc
** Determines whether or not a file type should be decoded by this plug-in
*/
int (*ismine)(char *filename);
/* create
** Function pointer to create a decoder module
*/
WInputSource *(*create)(void);
/* createinfo
** Function pointer to create a decoder module information
*/
WInputInfo *(*createinfo)(void);
} input_source;
typedef struct
{
/* version
** Version revision number
*/
int version;
/* description
** Text description of the output plug-in
*/
char *description;
/* create
** Function pointer to create an Output Filter
*/
WOutputFilter *(*create)();
} output_filter;
#endif

View File

@ -1,459 +0,0 @@
#include "main.h"
#include "decoder.h"
#include <math.h>
#include <locale.h>
#pragma warning(disable:4244)
#include "shaper.h"
#include "api__in_vorbis.h"
Decoder::~Decoder() {if (shaper) delete shaper;}
extern CfgInt
cfg_mc6_dm, cfg_mc6_map;
/*
if (vorbis_cfg.use_hq_preamp)
{
sample *= pow(10., preamp_db/20);
//hard 6dB limiting
if (sample < -0.5)
sample = tanh((sample + 0.5) / (1-0.5)) * (1-0.5) - 0.5;
else if (sample > 0.5)
sample = tanh((sample - 0.5) / (1-0.5)) * (1-0.5) + 0.5;
} */
#if 0
static float q_tanh(float x)
{
double foo1, foo2;
foo1 = pow(2.71828182845904523536028747135266, x);
foo2 = 1.0 / foo1;
return (foo1 -foo2) / (foo1 + foo2);
}
#else
#define q_tanh tanh
#endif
float VorbisFile::GetGain()
{
float peak;
vorbis_comment * c;
float scale = 1.0f;
c = ov_comment(&vf, -1);
peak = 0.99f;
if (c)
{
if (AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain", false))
{
char * _peak = 0, *_gain = 0;
float gain = 0;
bool have_rg = 0;
float lwing_gain = 0;
char *gain1 = 0, *gain2 = 0, *peak1 = 0, *peak2 = 0;
gain1 = vorbis_comment_query(c, "replaygain_album_gain", 0);
if (!gain1) gain1 = vorbis_comment_query(c, "rg_audiophile", 0);
gain2 = vorbis_comment_query(c, "replaygain_track_gain", 0);
if (!gain2) gain2 = vorbis_comment_query(c, "rg_radio", 0);
peak1 = vorbis_comment_query(c, "replaygain_album_peak", 0);
peak2 = vorbis_comment_query(c, "replaygain_track_peak", 0);
switch (AGAVE_API_CONFIG->GetUnsigned(playbackConfigGroupGUID, L"replaygain_source", 0))
{
case 0: // track
_gain = gain2;
if (!_gain && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
_gain = gain1;
_peak = peak2;
if (!_peak && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
_peak = peak1;
break;
case 1: // album
_gain = gain1;
if (!_gain && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
_gain = gain2;
_peak = peak1;
if (!_peak && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
_peak = peak2;
break;
}
if (!_peak)
{
_peak = vorbis_comment_query(c, "rg_peak", 0);
}
_locale_t C_locale = WASABI_API_LNG->Get_C_NumericLocale();
if (_peak) peak = _atof_l(_peak, C_locale);
if (_gain) gain = _atof_l(_gain, C_locale);
if (!_peak && !_gain)
{
char * l = vorbis_comment_query(c, "lwing_gain", 0);
if (l)
{
lwing_gain = _atof_l(l, C_locale);
have_rg = 1;
}
}
else have_rg = 1;
if (!have_rg)
{
gain = AGAVE_API_CONFIG->GetFloat(playbackConfigGroupGUID, L"non_replaygain", -6.0f);
}
scale = powf(10, (gain) / 20.0f);
if (lwing_gain)
scale *= lwing_gain;
else if (have_rg)
switch (AGAVE_API_CONFIG->GetUnsigned(playbackConfigGroupGUID, L"replaygain_mode", 1))
{
case 1: // apply gain, but don't clip
if (scale*peak > 1.0) scale = 1.0 / peak;
break;
case 2: // normalize
scale = 1.0 / peak;
break;
case 3: // no clipping
if (peak > 1.0f)
scale = 1.0 / peak;
break;
}
}
}
return scale;
}
void Decoder::process_rg()
{
scale = file->GetGain();
}
void Decoder::setup_mc()
{
if (AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"mono", false))
nch = 1;
else if (src_nch == 6)
{
switch (cfg_mc6_dm)
{
case 2:
nch = 4;
break;
case 3:
case 4:
nch = 2;
break;
case 5:
nch = 1;
break;
}
if (nch > 2 && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"surround", true))
nch = 2;
}
}
void Decoder::Flush()
{
bptr = 0;
pcmbuf = 0;
data = 0;
pos = 0;
if (shaper) {delete shaper;shaper = 0;}
}
void Decoder::Init(VorbisFile * f, UINT _bits, UINT _nch, bool _useFloat, bool allowRG)
{
useFloat = _useFloat;
file = f;
vorbis_info * i = ov_info(&file->vf, -1);
if (allowRG)
process_rg();
else
scale = 1.0f;
if (useFloat)
{
dither = false;
bps = 32;
}
else
{
dither = AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"dither", true);
if (_bits)
bps = _bits;
else
bps = AGAVE_API_CONFIG->GetUnsigned(playbackConfigGroupGUID, L"bits", 16);
}
if (useFloat)
{
clipmin = -10000; // some arbitrarily large number
clipmax = 10000; // some arbitrarily large number
}
else
{
clipmin = - (1 << (bps - 1));
clipmax = (1 << (bps - 1)) - 1;
}
sr = i->rate;
nch = src_nch = i->channels;
Flush();
cur_link = file->vf.current_link;
if (_nch)
nch = _nch;
else
setup_mc();
}
UINT Decoder::DataAvailable()
{
return data * (bps >> 3);
}
int Decoder::DoFrame()
{
need_reopen = 0;
while (1)
{
data = ov_read_float(&file->vf, &pcmbuf, 576, 0);
if ((int)data <= 0)
{
if (data == OV_HOLE) {continue;}
data = 0;
return 0;
}
break;
}
pos = 0;
if (cur_link != file->vf.current_link)
{
vorbis_info* i = ov_info(&file->vf, -1);
if (sr != (UINT)i->rate || src_nch != (UINT)i->channels)
{
UINT old_nch = nch, old_sr = sr;
if (shaper) {delete shaper;shaper = 0;}
sr = i->rate;
src_nch = nch = i->channels;
setup_mc();
if (nch != old_nch || sr != old_sr)
{
need_reopen = 1;
}
}
process_rg();
cur_link = file->vf.current_link;
}
data *= nch;
return 1;
}
int Decoder::Read(UINT bytes, void * buf)
{
UINT wr = 0;
if (buf && bytes && data > 0)
{
char* out = (char*)buf;
UINT d;
double mul;
int ofs;
float * img;
d = bytes / (bps >> 3);
if (d > data) d = data;
if (!d) return 0;
data -= d;
if (useFloat)
{
mul = 1.0;
ofs = 0;
}
else
{
mul = (double)( (1 << ((bps) - 1)) - 1 );
ofs = (bps == 8) ? 0x80 : 0;
}
wr += d * (bps >> 3);
img = (float*)alloca(sizeof(float) * nch);
do
{
UINT cur_ch;
if (nch == 1 && src_nch > 0)
{
UINT c;
img[0] = 0;
for (c = 0;c < src_nch;c++)
{
img[0] += pcmbuf[c][pos];
}
img[0] /= (float)src_nch;
}
else if (nch == src_nch && !(nch == 6 && cfg_mc6_dm == 1))
{
UINT c;
for (c = 0;c < nch;c++)
{
img[c] = pcmbuf[c][pos];
}
}
else if (src_nch == 6)
{
UINT FL, FR, C;
if (cfg_mc6_map == 1)
{
FL = 0;
FR = 1;
C = 2;
}
else
{
FL = 0;
C = 1;
FR = 2;
}
if (nch == 6)
{ //remap order for correct 5.1 output
img[0] = pcmbuf[FL][pos];
img[1] = pcmbuf[FR][pos];
img[2] = pcmbuf[C][pos];
img[3] = pcmbuf[5][pos];
img[4] = pcmbuf[3][pos];
img[5] = pcmbuf[4][pos];
}
else if (nch == 2)
{
/*
FL FR C BL BR LFE
0 1 2 3 4 5
L,C,R,SL,SR,LFE
0 1 2 3 4 5
output:
FL FR C LFE BL BR
stereo:
Lt=L+0.707*(V-SL-SR+LFE)
Rt=R+0.707*(C+SL+SR+LFE)
Lt=L+0.707*(C+LFE)
Rt=R+0.707*(C+LFE)
SLt=SL
SRt=SR
*/
if (cfg_mc6_dm == 4) //ds2
{
const double a = pow(10., 1.5 / 20.), b = 1 / a;
img[0] = pcmbuf[FL][pos] + 0.707 * (pcmbuf[C][pos] - a * pcmbuf[3][pos] - b * pcmbuf[4][pos] + pcmbuf[5][pos]);
img[1] = pcmbuf[FR][pos] + 0.707 * (pcmbuf[C][pos] + b * pcmbuf[3][pos] + a * pcmbuf[4][pos] + pcmbuf[5][pos]);
}
else
{
img[0] = pcmbuf[FL][pos] + 0.707 * (pcmbuf[C][pos] - pcmbuf[3][pos] - pcmbuf[4][pos] + pcmbuf[5][pos]);
img[1] = pcmbuf[FR][pos] + 0.707 * (pcmbuf[C][pos] + pcmbuf[3][pos] + pcmbuf[4][pos] + pcmbuf[5][pos]);
}
}
else if (nch == 4)
{
img[0] = pcmbuf[FL][pos] + 0.707 * (pcmbuf[C][pos] + pcmbuf[5][pos]);
img[1] = pcmbuf[FR][pos] + 0.707 * (pcmbuf[C][pos] + pcmbuf[5][pos]);
img[2] = pcmbuf[3][pos];
img[3] = pcmbuf[4][pos];
}
}
for (cur_ch = 0;cur_ch < nch;cur_ch++)
{
float v = img[cur_ch];
int val;
v *= scale;
v *= mul;
if (dither)
{
if (!shaper)
{
//Shaper(int freq,int _nch,int min,int max,int _dtype,int pdf,double noiseamp);
shaper = new Shaper(sr, nch, clipmin, clipmax, 2, DITHER_TRIANGLE, 0);
}
// double peak=0;
val = shaper->do_shaping(v /*,&peak*/, cur_ch);
//shaper clips for us
}
else
{
val = (int)v;
if (val < clipmin) val = clipmin;
else if (val > clipmax) val = clipmax;
//1<<16 = 0x10000
}
val += ofs;
switch (bps)
{
case 8:
*(BYTE*)out = (UINT)val;
break;
case 16:
*(short*)out = val;
break;
case 24:
{
((BYTE*)out)[0] = (UINT)val;
((BYTE*)out)[1] = (UINT)val >> 8;
((BYTE*)out)[2] = (UINT)val >> 16;
}
break;
case 32:
if (useFloat)
{
*(float *)out = v;
}
else
{
//*(long*)out=val;
//break;
*(long*)out = 0;
}
break;
};
out += (bps >> 3);
d--;
}
pos++;
}
while (d);
}
return wr;
}
int VorbisFile::Seek(double p) { return ov_time_seek(&vf, p);}
int Decoder::Seek(double p)
{
Flush();
return file->Seek(p);
}
//char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count)
const char* VorbisFile::get_meta(const char* tag, UINT c)
{
return vorbis_comment_query(vf.seekable ? vf.vc + vf.current_link : vf.vc, (char*)tag, c);
}

View File

@ -1,41 +0,0 @@
class Shaper;
class Decoder
{
private:
void process_rg();
void setup_mc();
float* bptr;
float** pcmbuf;
Shaper * shaper;
UINT data,pos;
float scale;
int cur_link;
int cur_preamp;
int clipmin,clipmax;
public:
VorbisFile * file;
UINT nch,sr,kbps,bps,src_nch;
Decoder()
{
memset(this,0,sizeof(*this));
}
~Decoder();
int Seek(double p);
int Read(UINT bytes,void * buf);
void Flush();
void Init(VorbisFile * f, UINT _bits=0, UINT _nch=0, bool _useFloat=false, bool allowRG=true);
void wa2_setinfo(UINT cur_bitrate);
UINT DataAvailable();
int DoFrame();
bool need_reopen;
int play_init();
bool play_inited;
bool dither;
bool useFloat;
};

View File

@ -1,97 +0,0 @@
#include <windows.h>
#include "genres.h"
#include <shlwapi.h>
extern const wchar_t *INI_DIRECTORY;
static void file_init(wchar_t *file_path, wchar_t *fn)
{
PathCombineW(file_path, INI_DIRECTORY, fn);
}
static char eol[2]={13,10};
static char get_char(HANDLE f,BOOL * eof)
{
DWORD br=0;
char r=0;
ReadFile(f,&r,1,&br,0);
if (!br) *eof=1;
return r;
}
void genres_read(HWND wnd, wchar_t* fn)
{
char temp[MAX_GENRE] = {0};
char add[MAX_GENRE] = {0};
BOOL eof=0;
char c = 0;
wchar_t file_path[MAX_PATH] = {0};
HANDLE f;
file_init(file_path, fn);
f = CreateFileW(file_path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (f==INVALID_HANDLE_VALUE) return;
GetWindowTextA(wnd,add,MAX_GENRE);
while(!eof)
{
UINT ptr=0;
BOOL start=1;
while(ptr<MAX_GENRE-1)
{
c=get_char(f,&eof);
if (eof) break;
if (c==10 || c==13)
{
if (start) continue;
else break;
}
start=0;
temp[ptr++]=c;
}
if (ptr)
{
temp[ptr]=0;
SendMessage(wnd,CB_ADDSTRING,0, (LPARAM)temp);
if (add[0])
{
if (!_stricmp(add,temp)) add[0]=0;
}
}
}
CloseHandle(f);
if (add[0]) SendMessage(wnd,CB_ADDSTRING,0,(LPARAM)add);
}
void genres_write(HWND wnd, wchar_t* fn)
{
wchar_t file_path[MAX_PATH] = {0};
char temp[MAX_GENRE] = {0};
UINT max = 0,n = 0;
DWORD bw = 0;
HANDLE f;
{
char add[MAX_GENRE] = {0};
GetWindowTextA(wnd,add,MAX_GENRE);
if (!add[0]) return;
max=(UINT)SendMessage(wnd,CB_GETCOUNT,0,0);
for(n=0;n<max;n++)
{
SendMessage(wnd,CB_GETLBTEXT,n,(LPARAM)temp);
if (!_stricmp(temp,add)) return;
}
SendMessage(wnd,CB_ADDSTRING,0,(LPARAM)add);
}
file_init(file_path, fn);
f = CreateFileW(file_path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (f==INVALID_HANDLE_VALUE) return;
max=(UINT)SendMessage(wnd,CB_GETCOUNT,0,0);
for(n=0;n<max;n++)
{
SendMessage(wnd,CB_GETLBTEXT,n,(LPARAM)temp);
bw = 0; WriteFile(f,temp,(DWORD)strlen(temp),&bw,0);
bw = 0; WriteFile(f,eol,2,&bw,0);
}
CloseHandle(f);
}

View File

@ -1,16 +0,0 @@
#ifndef NULLSOFT_IN_VORBIS_GENRES_H
#define NULLSOFT_IN_VORBIS_GENRES_H
#ifdef __cplusplus
extern "C" {
#endif
void genres_read(HWND wnd, wchar_t* fn);
void genres_write(HWND wnd, wchar_t* fn);
#define MAX_GENRE 256
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,596 +0,0 @@
#include "api__in_vorbis.h"
#include "../../..\Components\wac_network\wac_network_http_receiver_api.h"
#include "rf.h"
#include "main.h"
#include "../Winamp/wa_ipc.h"
#include <api/service/waservicefactory.h>
#include "../nu/AutoWide.h"
#include "../nu/AutoChar.h"
extern CfgInt cfg_fix0r,cfg_httpseek2,cfg_proxy_mode,cfg_prebuf1,cfg_prebuf2,cfg_fsave,cfg_http_bsize;
#define CANSEEK
WORD *wdup(const char * src);//info.c
#define zeromem(x) memset(&x,0,sizeof(x))
class StreamSave
{
private:
ogg_sync_state oy_src;
ogg_stream_state os_src;
ogg_stream_state os_dst;
ogg_page og_src;
ogg_page og_dst;
ogg_packet op;
StringW tmp_fn;
BOOL is_temp;
BOOL got_streams,got_delta,use_fix0r;
ogg_int64_t pcm_delta;
int packets,serial;
HANDLE hFile;
public:
StreamSave()
{
zeromem(oy_src);
zeromem(os_src);
zeromem(os_dst);
zeromem(og_src);
zeromem(og_dst);
zeromem(op);
got_streams=0;
got_delta=0;
pcm_delta=0;
hFile=0;
packets=0;
serial=0;
is_temp=1;
tmp_fn=cfg_dumpdir;
if (tmp_fn[tmp_fn.Length()-1]!='\\') tmp_fn.AddChar('\\');
tmp_fn+=StringPrintfW(L"oggtemp%u.foo",GetTickCount64()&0xFFFF);
hFile=CreateFileW(tmp_fn,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_HIDDEN,0);
if (hFile==INVALID_HANDLE_VALUE) hFile=0;
else
{
ogg_sync_init(&oy_src);
use_fix0r=cfg_fix0r;
}
};
void Write(void * ptr,UINT siz)
{
if (!hFile) return;
void * b=ogg_sync_buffer(&oy_src,siz);
memcpy(b,ptr,siz);
ogg_sync_wrote(&oy_src,siz);
while(ogg_sync_pageout(&oy_src,&og_src)>0)
{
if (!got_streams)
{
serial=ogg_page_serialno(&og_src);
ogg_stream_init(&os_src,serial);
ogg_stream_init(&os_dst,serial);
got_streams=1;
packets=0;
got_delta=0;
}
else if (serial!=ogg_page_serialno(&og_src))
{
if (got_streams)
{
/*while(ogg_stream_flush(&os_dst,&og_dst))
{
write_page(dst,&og_dst,&wb);
}*/
ogg_stream_clear(&os_src);
ogg_stream_clear(&os_dst);
}
serial=ogg_page_serialno(&og_src);
ogg_stream_init(&os_src,serial);
ogg_stream_init(&os_dst,serial);
packets=0;
got_delta=0;
}
ogg_stream_pagein(&os_src,&og_src);
while(ogg_stream_packetout(&os_src,&op)>0)
{
if (use_fix0r && !got_delta && packets>2 && op.granulepos>=0) //hack to fix saved streams
{
got_delta=1;
if (op.granulepos>4096*(packets-2)) pcm_delta=op.granulepos;
}
if (got_delta)
{
if (op.granulepos>=pcm_delta) op.granulepos-=pcm_delta;
else if (op.granulepos>0) op.granulepos=0;
}
ogg_stream_packetin(&os_dst,&op);
packets++;
}
while((packets==3 ? ogg_stream_flush(&os_dst,&og_dst) : ogg_stream_pageout(&os_dst,&og_dst))>0)
{
DWORD bw = 0;
WriteFile(hFile,og_dst.header,og_dst.header_len,&bw,0);
bw = 0; WriteFile(hFile,og_dst.body,og_dst.body_len,&bw,0);
}
}
}
void FixName(VorbisFile * vf,const char * streamname)
{
if (!hFile) return;
CloseHandle(hFile);
StringW fn(cfg_dumpdir);
if (fn[fn.Length()-1]!='\\') fn.AddChar('\\');
UINT n=fn.Length();
fn+=(wchar_t *)AutoWide(vf->get_meta("TITLE", 0), CP_UTF8);
UINT m=fn.Length();
while(n<m)
{
char * b="/\\:*?\"<>|";
while(b && *b)
{
if (fn[n]==*b) {fn.SetChar(n,'_');break;}
b++;
}
n++;
};
fn.AddStringA(".ogg");
if (!MoveFileW(tmp_fn,fn))
{
DeleteFileW(fn);
MoveFileW(tmp_fn,fn);
}
SetFileAttributesW(fn,FILE_ATTRIBUTE_NORMAL);
hFile=CreateFileW(fn,GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
if (hFile==INVALID_HANDLE_VALUE) {hFile=0;}
else SetFilePointer(hFile,0,0,FILE_END);
is_temp=0;
}
~StreamSave()
{
if (hFile)
{
/*if (got_streams)
{
while(ogg_stream_flush(&os_dst,&og_dst))
{
write_page(dst,&og_dst,&wb);
}
}*/
ogg_stream_clear(&os_src);
ogg_stream_clear(&os_dst);
SetFilePointer(hFile,0,0,FILE_CURRENT);
CloseHandle(hFile);
if (is_temp) DeleteFileW(tmp_fn);
}
ogg_sync_clear(&oy_src);
}
};
static const char * do_proxy(const char * url)
{
switch(cfg_proxy_mode)
{
default:
return 0;
case 1:
{
const char * p=strstr(url,"://");
if (!p) p=url;
while(p && *p && *p!=':' && *p!='/') p++;
if (p && *p==':')
{
if (atoi(p+1)!=80) return 0;
}
}
case 2:
{
char *x = (char *)SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GET_PROXY_STRING);
if (x == (char *)1 || !x || !*x)
return 0;
return x;
}
}
}
class VorbisFile_HTTP : public VorbisFile
{
protected:
api_httpreceiver *get;
UINT bsize;
uint64_t len;
UINT pos;
UINT seekpos;
BOOL can_seek;
StreamSave * saver;
virtual void Idle();
virtual int f_seek(__int64 offset,int whence);
virtual size_t f_read(UINT siz,void * ptr);
virtual UINT f_tell();
virtual UINT FileSize() {return len;}
bool is_live;
public:
virtual int GetType() {return TYPE_HTTP;}
virtual bool IsLive() {return is_live;}
bool http_init();
void do_prebuf() {VorbisFile::do_prebuf();fillbuf(bsize * cfg_prebuf1 / 100,0);}
VorbisFile_HTTP(UINT s, const wchar_t *u,bool is_info, bool hasauth) : VorbisFile(u,is_info), usedauth(hasauth)
{
get=0;
can_seek=0;
len=pos=seekpos=0;
bsize=s;
saver=0;
m_needs_auth=0;
lpinfo[0]=0;
force_lpinfo[0]=0;
is_live = false;
memset(dlg_realm, 0, sizeof(dlg_realm));
}
~VorbisFile_HTTP()
{
if (get)
{
waServiceFactory *sf = mod.service->service_getServiceByGuid(httpreceiverGUID);
if (sf)
sf->releaseInterface(get);
get=0;
}
if (saver) delete saver;
}
void fillbuf(UINT max,bool shutup);
size_t _http_read(char* ptr,size_t total);
int reconnect(UINT ofs);
virtual void post_init()
{
if (saver) saver->FixName(this,get->getheader("ice-name"));
}
static BOOL CALLBACK httpDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
int m_needs_auth;
char dlg_realm[256];
char lpinfo[256];
char force_lpinfo[256];
bool usedauth;
};
int VorbisFile_HTTP::reconnect(UINT ofs)
{
// get.reset_headers();
get->addheader("User-Agent: WinampOGG/5.24(MPEG stream compatible)");
get->addheader("Accept:*/*");
if (ofs>0) get->addheader(StringPrintf("Range: bytes=%u-",ofs));
get->connect(AutoChar(url));
Status(WASABI_API_LNGSTRINGW(IDS_CONNECTING));
int st=get->run();
if (st<0)
{
return 1;
}
return 0;
}
void VorbisFile_HTTP::fillbuf(UINT max,bool shutup)
{
if (len>0 && pos+max>len) max=len-pos;
while(!Aborting() && !abort_prebuf) //stop prebuffering if we wanna seek
{
if (!shutup)
{
Status(StringPrintfW(WASABI_API_LNGSTRINGW(IDS_PREBUFFERING), get->bytes_available()*100/bsize));
}
if (get->run()) break;
if (Aborting() || abort_prebuf || get->bytes_available()>=(int)max) break;
Sleep(2);
}
if (!shutup)
{
Status(0);
}
}
size_t VorbisFile_HTTP::_http_read(char* ptr,size_t total)
{
#ifdef CANSEEK
if (seekpos!=-1)
{
UINT sp=seekpos;
seekpos=-1;
if (sp!=pos)
{
if (sp>pos && sp<=pos+get->bytes_available())
{
get->get_bytes(0,sp-pos);
}
else
{
if (reconnect(sp))
{
return 0;//oh well...
}
}
pos=sp;
}
}
#endif
UINT wr=0;
while(!Aborting() && wr<total)
{
int st=get->run();
int d=get->get_bytes(ptr,(int)total-wr);
if (st && !d) break;
wr+=d;
ptr+=d;
pos+=d;
if ((len>0 && pos>=len) || wr>=total || Aborting()) break;
if (use_prebuf) fillbuf(bsize * cfg_prebuf2 / 100,0);
else Sleep(1);
}
return wr;
}
void VorbisFile_HTTP::Idle()
{
get->run();
Sleep(1);
get->run();
Sleep(1);
}
size_t VorbisFile_HTTP::f_read(UINT siz,void* ptr)
{
if (Aborting()) return 0;//fixme
int i=(int)_http_read((char*)ptr,siz);
if (i>0 && saver) saver->Write(ptr,i);
return i;
}
int VorbisFile_HTTP::f_seek(ogg_int64_t offset,int whence)
{
#ifdef CANSEEK
if (can_seek)
{
switch(whence)
{
case FILE_BEGIN:
seekpos=(int)offset;
break;
case FILE_END:
seekpos=len+(int)offset;
break;
case FILE_CURRENT:
seekpos=pos+(int)offset;
break;
}
if (seekpos>len) seekpos=len;
return 0;
}
else
#endif
return -1;
}
UINT VorbisFile_HTTP::f_tell()
{
#ifdef CANSEEK
if (can_seek)
{
if (seekpos!=-1) return seekpos;
else return pos;
}
else
#endif
return -1;
}
HWND GetDialogBoxParent()
{
HWND parent = (HWND)SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GETDIALOGBOXPARENT);
if (!parent || parent == (HWND)1)
return mod.hMainWindow;
return parent;
}
bool VorbisFile_HTTP::http_init()
{
if (mod.service)
{
waServiceFactory *sf = mod.service->service_getServiceByGuid(httpreceiverGUID);
if (sf) get = (api_httpreceiver *)sf->getInterface();
}
if (!get) return false;
get->open(API_DNS_AUTODNS, bsize, do_proxy(AutoChar(url)));
if (reconnect(0))
{
return 0;
}
#ifdef CANSEEK
// if (cfg_httpseek)
{
//need to get http headers first
while(!memcmp(get->getallheaders(),"\0\0",2))
{
if (get->run()<0 || Aborting())
{
int reply = get->getreplycode();
if ( reply == 401 )
{
api_connection *mcon=get->GetConnection();
if ( mcon && mcon->GetReceiveBytesAvailable())
{
char p[1024]="";
while ( mcon->GetReceiveBytesAvailable() )
{
char b[2048]="";
mcon->ReceiveLine(b,2048);
if ( *b )
{
char *t= strstr(b,"WWW-Authenticate:");
if ( t && *t )
{
char *y = strstr(t,"\"");
if ( y && *y )
{
y++;
if ( *y )
{
char *u = strstr(y,"\"");
if ( u && *u )
{
*u = 0;
wsprintfA(p,"%s",y);
}
}
}
}
}
}
if ( *p ) // found our realm
{
if (!force_lpinfo[0]) GetPrivateProfileStringA("HTTP-AUTH",p,"",force_lpinfo,sizeof(force_lpinfo),INI_FILE);
if (!force_lpinfo[0] || lpinfo[0] || usedauth )
{
lstrcpynA(dlg_realm,p,sizeof(dlg_realm));
if (!WASABI_API_DIALOGBOXPARAM(IDD_HTTPAUTH, GetDialogBoxParent(), httpDlgProc, (LPARAM)this))
{
force_lpinfo[0]=0;
}
else
{
WritePrivateProfileStringA("HTTP-AUTH",p,force_lpinfo,INI_FILE);
}
}
Status(WASABI_API_LNGSTRINGW(IDS_AUTH_REQUIRED));
m_needs_auth=1;
}
}
}
return 0;
}
//hg->get.wait(10);
Sleep(1);
}
len=get->content_length();
const char* poo=get->getheader("icy-name");
if (poo) stream_title=poo;
if (cfg_httpseek2 && len) can_seek=1;
is_live=(len<=0);
}
#endif
//if (hg->len==0 || hg->len==-1) hg->can_seek=0;
seekpos=-1;
if (cfg_fsave && !can_seek)
{
saver=new StreamSave;
}
return 1;
}
VorbisFile * VorbisFile::Create_HTTP(const char * url,bool is_info)
{
VorbisFile_HTTP * r=new VorbisFile_HTTP(cfg_http_bsize,AutoWide(url),is_info, false);
if (r)
{
if (!r->http_init())
{
int trys=0;
while ( r && r->m_needs_auth && trys++ < 2)
{
const char *p=strstr(url,"://");
if (p && *p)
{
p += 3;
if (p && *p)
{
char lurl[4096] = {0};
wsprintfA(lurl, "http://%s@%s", r->force_lpinfo, p);
delete r;
r = new VorbisFile_HTTP(cfg_http_bsize,AutoWide(lurl),is_info, true);
if (r && r->http_init())
{
return r;
}
}
}
}
delete r;
r=0;
}
}
return r;
}
BOOL CALLBACK VorbisFile_HTTP::httpDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
VorbisFile_HTTP *_this;
switch (uMsg)
{
case WM_INITDIALOG:
#ifdef WIN64
SetWindowLong(hwndDlg, GWLP_USERDATA, (LONG)lParam);
_this = (VorbisFile_HTTP*)(GetWindowLong(hwndDlg, GWLP_USERDATA));
#else
SetWindowLong(hwndDlg, GWL_USERDATA, (LONG)lParam);
_this = (VorbisFile_HTTP*)GetWindowLong(hwndDlg, GWL_USERDATA);
#endif
if (_this->force_lpinfo[0])
SetDlgItemTextA(hwndDlg,IDC_EDITAUTH,_this->force_lpinfo);
else SetDlgItemTextA(hwndDlg,IDC_EDITAUTH,_this->lpinfo);
SetDlgItemTextA(hwndDlg,IDC_REALM,_this->dlg_realm);
return 1;
case WM_COMMAND:
#ifdef WIN64
_this = (VorbisFile_HTTP*)GetWindowLong(hwndDlg, GWLP_USERDATA);
#else
_this = (VorbisFile_HTTP*)GetWindowLong(hwndDlg, GWL_USERDATA);
#endif
if (LOWORD(wParam) == IDOKAUTH)
{
char *p;
GetDlgItemTextA(hwndDlg,IDC_EDITAUTH,_this->force_lpinfo,sizeof(_this->force_lpinfo));
p = strstr(_this->force_lpinfo,"\r");
if ( p && *p ) *p=0;
p = strstr(_this->force_lpinfo,"\n");
if ( p && *p ) *p=0;
EndDialog(hwndDlg,1);
}
else if (LOWORD(wParam) == IDCANCELAUTH)
{
EndDialog(hwndDlg,0);
}
break;
}
return 0;
}

View File

@ -1,415 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Polish resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PLK)
#ifdef _WIN32
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
#pragma code_page(1250)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""version.rc2""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // Polish resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUT DIALOGEX 0, 0, 173, 113
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CONTROL "",IDC_CUSTOM1,"XIPH_CLASS",0x0,6,8,44,40
CTEXT "",IDC_RPM,7,56,45,8
CTEXT "",IDC_RPM2,4,64,51,8
LTEXT "",IDC_ABOUT_TEXT,58,8,110,85
DEFPUSHBUTTON "OK",IDCANCEL,117,93,50,14
END
IDD_HTTPAUTH DIALOGEX 0, 0, 154, 70
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Ogg Authentication"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LTEXT "Realm: ",IDC_STATIC,4,4,25,8
LTEXT "",IDC_REALM,37,4,113,8
LTEXT "Enter your login and password in the form of:\n\tlogin:password",IDC_STATIC,4,15,146,17
EDITTEXT IDC_EDITAUTH,4,35,146,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOKAUTH,4,52,50,13
PUSHBUTTON "Cancel",IDCANCELAUTH,100,53,50,13
END
IDD_INFO_DLG_NEW DIALOGEX 0, 0, 329, 238
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Ogg Vorbis Info"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LTEXT "File/URL :",-1,6,6,34,8
EDITTEXT IDC_URL,43,5,282,12,ES_AUTOHSCROLL | ES_READONLY
GROUPBOX "File / Stream Info",IDC_STATIC_MISC,224,20,101,120
EDITTEXT IDC_MISC,231,30,88,107,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER
GROUPBOX "Chained Streams",IDC_STATIC_CS,224,155,101,30
PUSHBUTTON "<= previous",IDC_PREV_STREAM,229,167,44,13
PUSHBUTTON "next =>",IDC_NEXT_STREAM,276,167,43,13
CONTROL "Hide special fields",IDC_HIDE_SPEC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,229,190,73,10
PUSHBUTTON "",IDC_MODE_TOGGLE,228,203,93,13
PUSHBUTTON "Close",IDCANCEL,273,220,48,13
END
IDD_INFO_PANEL_SIMPLE DIALOGEX 0, 0, 227, 218
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
GROUPBOX "Standard Tags",IDC_STATIC_STD,3,2,219,119
LTEXT "Title",IDC_STATIC,29,16,14,8
EDITTEXT IDC_TITLE,48,14,168,12,ES_AUTOHSCROLL
LTEXT "Artist",IDC_STATIC,27,32,16,8
EDITTEXT IDC_ARTIST,48,30,168,12,ES_AUTOHSCROLL
LTEXT "Album",IDC_STATIC,24,48,19,8
EDITTEXT IDC_ALBUM,48,46,124,12,ES_AUTOHSCROLL
LTEXT "Track:",IDC_STATIC_TRACK,175,48,21,8
EDITTEXT IDC_TRACK,198,46,18,12,ES_AUTOHSCROLL
LTEXT "Year",IDC_STATIC,28,64,16,8
EDITTEXT IDC_DATE,48,62,56,12,ES_AUTOHSCROLL
LTEXT "Genre",IDC_STATIC,117,64,22,8
COMBOBOX IDC_GENRE,140,62,77,68,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Comment",IDC_STATIC,13,80,29,8
EDITTEXT IDC_COMMENT,48,78,169,37,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL
GROUPBOX "Other",IDC_STATIC_TAGS,3,123,219,91
LISTBOX IDC_LIST,10,134,207,75,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
END
IDD_INFO_PANEL_ADVANCED DIALOGEX 0, 0, 227, 218
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LISTBOX IDC_LIST,3,3,219,212,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
END
IDD_INFO DIALOGEX 0, 0, 341, 164
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
GROUPBOX "Advanced",IDC_STATIC,0,0,341,164
CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,6,13,164,143
LTEXT "Name:",IDC_STATIC,175,13,22,8
EDITTEXT IDC_NAME,175,23,159,14,ES_AUTOHSCROLL
LTEXT "Value:",IDC_STATIC,175,39,21,8
EDITTEXT IDC_VALUE,175,49,159,90,ES_MULTILINE | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
PUSHBUTTON "Add New",IDC_BUTTON_ADD,176,142,50,13
PUSHBUTTON "Delete",IDC_BUTTON_DEL,230,142,50,13
PUSHBUTTON "Delete All",IDC_BUTTON_DELALL,284,142,50,13
END
IDD_CONFIG DIALOGEX 0, 0, 222, 261
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
GROUPBOX "Decoding",IDC_STATIC,4,4,214,93
CONTROL "Buffer full files from disk",IDC_FULLBUF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,17,89,10
CONTROL "Show average bitrate while playing",IDC_AVG_BR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,31,128,10
GROUPBOX "5.1-Channel Input Processing",IDC_STATIC,10,44,201,47
LTEXT "Apply conversion:",IDC_STATIC,16,58,72,8,0,WS_EX_RIGHT
COMBOBOX IDC_MC6_DM,95,56,110,96,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Source channel order:",IDC_STATIC,16,75,72,8,0,WS_EX_RIGHT
COMBOBOX IDC_MC6_MAP,95,73,110,96,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Streaming",IDC_STATIC,4,101,214,139
LTEXT "Buffer size",IDC_STATIC,10,115,34,8
EDITTEXT IDC_HTTP_BSIZE,48,113,28,12,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "KB",IDC_STATIC,80,115,9,8
GROUPBOX "Prebuffering:",IDC_STATIC,10,129,201,44
LTEXT "At start:",IDC_STATIC,16,142,31,8
CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,70,141,130,10
LTEXT "After underrun:",IDC_STATIC,16,153,54,8
CONTROL "",IDC_SLIDER2,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,70,152,130,10
LTEXT "0%",IDC_STATIC,71,161,13,8
LTEXT "50%",IDC_STATIC,122,161,18,8
LTEXT "100%",IDC_STATIC,185,161,20,8
LTEXT "Use Winamp's proxy server settings:",IDC_STATIC,10,179,120,8
COMBOBOX IDC_PROXY,134,177,77,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "",IDC_STATIC,10,191,201,43
CONTROL "Save streamed files to:",IDC_FSAVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,201,89,10
PUSHBUTTON "default",IDC_SSAVE_FMT_DEF,165,200,40,11
PUSHBUTTON "",IDC_STREAM_SAVE,15,215,105,13
EDITTEXT IDC_SSAVE_FMT,120,215,85,13,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,124,244,45,13
PUSHBUTTON "Cancel",IDCANCEL,173,244,45,13
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_ABOUT, DIALOG
BEGIN
LEFTMARGIN, 4
RIGHTMARGIN, 168
TOPMARGIN, 4
BOTTOMMARGIN, 107
END
IDD_HTTPAUTH, DIALOG
BEGIN
LEFTMARGIN, 4
RIGHTMARGIN, 150
TOPMARGIN, 4
BOTTOMMARGIN, 66
END
IDD_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 4
RIGHTMARGIN, 218
TOPMARGIN, 4
BOTTOMMARGIN, 257
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP9$(DISABLED) BITMAP "oggdrop\\120.bmp"
#else
IDB_BITMAP9 BITMAP "oggdrop\\120.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP8$(DISABLED) BITMAP "oggdrop\\119.bmp"
#else
IDB_BITMAP8 BITMAP "oggdrop\\119.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP7$(DISABLED) BITMAP "oggdrop\\118.bmp"
#else
IDB_BITMAP7 BITMAP "oggdrop\\118.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP6$(DISABLED) BITMAP "oggdrop\\117.bmp"
#else
IDB_BITMAP6 BITMAP "oggdrop\\117.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP5$(DISABLED) BITMAP "oggdrop\\116.bmp"
#else
IDB_BITMAP5 BITMAP "oggdrop\\116.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP4$(DISABLED) BITMAP "oggdrop\\115.bmp"
#else
IDB_BITMAP4 BITMAP "oggdrop\\115.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP3$(DISABLED) BITMAP "oggdrop\\114.bmp"
#else
IDB_BITMAP3 BITMAP "oggdrop\\114.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP2$(DISABLED) BITMAP "oggdrop\\113.bmp"
#else
IDB_BITMAP2 BITMAP "oggdrop\\113.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP12$(DISABLED) BITMAP "oggdrop\\123.bmp"
#else
IDB_BITMAP12 BITMAP "oggdrop\\123.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP11$(DISABLED) BITMAP "oggdrop\\122.bmp"
#else
IDB_BITMAP11 BITMAP "oggdrop\\122.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP10$(DISABLED) BITMAP "oggdrop\\121.bmp"
#else
IDB_BITMAP10 BITMAP "oggdrop\\121.bmp"
#endif
#endif
#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
#if defined(APSTUDIO_INVOKED)
IDB_BITMAP1$(DISABLED) BITMAP "oggdrop\\112.bmp"
#else
IDB_BITMAP1 BITMAP "oggdrop\\112.bmp"
#endif
#endif
/////////////////////////////////////////////////////////////////////////////
//
// PNG
//
IDB_PNG1 PNG "oggdrop\\112.png"
IDB_PNG2 PNG "oggdrop\\113.png"
IDB_PNG3 PNG "oggdrop\\114.png"
IDB_PNG4 PNG "oggdrop\\115.png"
IDB_PNG5 PNG "oggdrop\\116.png"
IDB_PNG6 PNG "oggdrop\\117.png"
IDB_PNG7 PNG "oggdrop\\118.png"
IDB_PNG8 PNG "oggdrop\\119.png"
IDB_PNG9 PNG "oggdrop\\120.png"
IDB_PNG10 PNG "oggdrop\\121.png"
IDB_PNG11 PNG "oggdrop\\122.png"
IDB_PNG12 PNG "oggdrop\\123.png"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_NULLSOFT_VORBIS_DECODER "Nullsoft Vorbis Decoder v%s"
65535 "{5C5BCA4E-279E-4867-8E24-58C8B186959A}"
END
STRINGTABLE
BEGIN
IDS_NULLSOFT_VORBIS_DECODER_OLD "Nullsoft Vorbis Decoder"
IDS_FILE_ERROR "file error"
IDS_LENGTH "Length: "
IDS_AVERAGE_BITRATE "Average bitrate: "
IDS_FILE_SIZE "File size: "
IDS_NOMINAL_BITRATE "Nominal bitrate: "
IDS_MIN_BITRATE "Min bitrate: "
IDS_MAX_BITRATE "Max bitrate: "
IDS_CHANNELS "Channels"
IDS_SAMPLING_RATE "Sampling rate"
IDS_SERIAL_NUMBER "Serial number"
IDS_VERSION "Version"
END
STRINGTABLE
BEGIN
IDS_VENDOR "Vendor"
IDS_TO_SIMPLE_MODE "<< to simple mode"
IDS_TO_ADVANCED_MODE "to advanced mode >>"
IDS_OGG_VORBIS_INFO "Ogg Vorbis info - %s"
IDS_BEST_RPM "Best: %u RPM"
IDS_LEAVE_AS_IS "leave as is"
IDS_REMAP_6_CHANNELS "remap 6 channels"
IDS_DOWNMIX_TO_4_CHANNELS "downmix to 4 channels"
IDS_DOWNMIX_TO_2_CHANNELS_DS "downmix to 2 channels (DS)"
IDS_DOWNMIX_TO_2_CHANNELS_DS2 "downmix to 2 channels (DS2)"
IDS_DOWNMIX_TO_MONO "downmix to mono"
IDS_CORRECT_FL_FC_FR_BL_BR_LFE "correct (FL FC FR BL BR LFE)"
IDS_BROKEN_FL_FR_FC_BL_BR_LFE "broken (FL FR FC BL BR LFE)"
END
STRINGTABLE
BEGIN
IDS_ABOUT_TEXT "%s\n© 2001-2023 Winamp SA\nWritten by: Peter Pawlowski\nBuild date: %hs\n\nThanks to:\n Craig Freer\n Tomi 'Nebularia' Jylhä-Ollila\n Jack Moffitt\n Szabolcs Péter"
IDS_TITLE_PREFERENCES "%s Preferences"
IDS_NEVER "never"
IDS_PORT_80_ONLY "port 80 only"
IDS_ALWAYS "always"
IDS_SELECT_OUTPUT_DIRECTORY "Select output directory:"
END
STRINGTABLE
BEGIN
IDS_CONNECTING "Connecting..."
IDS_PREBUFFERING "Prebuffering : %u%%"
IDS_AUTH_REQUIRED "Authentication Required"
IDS_OGG_FILES "Ogg Vorbis Files (*.OGG;*.OGA)"
IDS_NAME "Name"
IDS_VALUE "Value"
IDS_KBPS "kbps"
IDS_HZ "Hz"
IDS_GAME_SPEED "%u RPM"
IDS_BYTES "bytes"
IDS_FAMILY_STRING "Ogg Vorbis File"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -1,65 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29424.173
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "in_vorbis", "in_vorbis.vcxproj", "{7C58AC02-7941-42BE-8F97-9BF2064D6631}"
ProjectSection(ProjectDependencies) = postProject
{4FC28B55-2A14-43D5-86F7-201054F338A9} = {4FC28B55-2A14-43D5-86F7-201054F338A9}
{49238ED1-3146-49AB-9523-E9826EE4A0C8} = {49238ED1-3146-49AB-9523-E9826EE4A0C8}
{EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4} = {EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libogg", "..\libogg\libogg.vcxproj", "{4FC28B55-2A14-43D5-86F7-201054F338A9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vorbis_static", "..\libvorbis\win32\vorbis_static.vcxproj", "{49238ED1-3146-49AB-9523-E9826EE4A0C8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vorbisfile_static", "..\libvorbis\win32\vorbisfile_static.vcxproj", "{EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7C58AC02-7941-42BE-8F97-9BF2064D6631}.Debug|Win32.ActiveCfg = Debug|Win32
{7C58AC02-7941-42BE-8F97-9BF2064D6631}.Debug|Win32.Build.0 = Debug|Win32
{7C58AC02-7941-42BE-8F97-9BF2064D6631}.Release|Win32.ActiveCfg = Release|Win32
{7C58AC02-7941-42BE-8F97-9BF2064D6631}.Release|Win32.Build.0 = Release|Win32
{7C58AC02-7941-42BE-8F97-9BF2064D6631}.Debug|x64.ActiveCfg = Debug|x64
{7C58AC02-7941-42BE-8F97-9BF2064D6631}.Debug|x64.Build.0 = Debug|x64
{7C58AC02-7941-42BE-8F97-9BF2064D6631}.Release|x64.ActiveCfg = Release|x64
{7C58AC02-7941-42BE-8F97-9BF2064D6631}.Release|x64.Build.0 = Release|x64
{49238ED1-3146-49AB-9523-E9826EE4A0C8}.Debug|Win32.ActiveCfg = Debug|Win32
{49238ED1-3146-49AB-9523-E9826EE4A0C8}.Debug|Win32.Build.0 = Debug|Win32
{49238ED1-3146-49AB-9523-E9826EE4A0C8}.Release|Win32.ActiveCfg = Release|Win32
{49238ED1-3146-49AB-9523-E9826EE4A0C8}.Release|Win32.Build.0 = Release|Win32
{49238ED1-3146-49AB-9523-E9826EE4A0C8}.Debug|x64.ActiveCfg = Debug|x64
{49238ED1-3146-49AB-9523-E9826EE4A0C8}.Debug|x64.Build.0 = Debug|x64
{49238ED1-3146-49AB-9523-E9826EE4A0C8}.Release|x64.ActiveCfg = Release|x64
{49238ED1-3146-49AB-9523-E9826EE4A0C8}.Release|x64.Build.0 = Release|x64
{EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4}.Debug|Win32.ActiveCfg = Debug|Win32
{EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4}.Debug|Win32.Build.0 = Debug|Win32
{EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4}.Release|Win32.ActiveCfg = Release|Win32
{EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4}.Release|Win32.Build.0 = Release|Win32
{EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4}.Debug|x64.ActiveCfg = Debug|x64
{EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4}.Debug|x64.Build.0 = Debug|x64
{EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4}.Release|x64.ActiveCfg = Release|x64
{EC9475D2-FEE2-4F8C-9BB9-A11D5EB597C4}.Release|x64.Build.0 = Release|x64
{4FC28B55-2A14-43D5-86F7-201054F338A9}.Debug|Win32.ActiveCfg = Debug|Win32
{4FC28B55-2A14-43D5-86F7-201054F338A9}.Debug|Win32.Build.0 = Debug|Win32
{4FC28B55-2A14-43D5-86F7-201054F338A9}.Release|Win32.ActiveCfg = Release|Win32
{4FC28B55-2A14-43D5-86F7-201054F338A9}.Release|Win32.Build.0 = Release|Win32
{4FC28B55-2A14-43D5-86F7-201054F338A9}.Debug|x64.ActiveCfg = Debug|x64
{4FC28B55-2A14-43D5-86F7-201054F338A9}.Debug|x64.Build.0 = Debug|x64
{4FC28B55-2A14-43D5-86F7-201054F338A9}.Release|x64.ActiveCfg = Release|x64
{4FC28B55-2A14-43D5-86F7-201054F338A9}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3248659F-0FFC-4CF4-A9BC-F7D10C713D5D}
EndGlobalSection
EndGlobal

View File

@ -1,339 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7C58AC02-7941-42BE-8F97-9BF2064D6631}</ProjectGuid>
<RootNamespace>in_vorbis</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WA2;TAGZ_UNICODE;UNICODE_INPUT_PLUGIN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4090;4312;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0415</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>shlwapi.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;WA2;TAGZ_UNICODE;UNICODE_INPUT_PLUGIN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4090;4312;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0415</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>shlwapi.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;TAGZ_UNICODE;UNICODE_INPUT_PLUGIN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<DisableSpecificWarnings>4090;4312;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0415</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>shlwapi.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;TAGZ_UNICODE;UNICODE_INPUT_PLUGIN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<DisableSpecificWarnings>4090;4312;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0415</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>shlwapi.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\external_dependencies\openmpt-trunk\include\vorbis\win32\vorbisfile_static.vcxproj">
<Project>{ec9475d2-fee2-4f8c-9bb9-a11d5eb597c4}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\nsmkv\Lacing.cpp" />
<ClCompile Include="..\..\..\nsmkv\vint.cpp" />
<ClCompile Include="about.cpp" />
<ClCompile Include="chainedstream_parse.cpp" />
<ClCompile Include="config.cpp" />
<ClCompile Include="c_string.cpp" />
<ClCompile Include="decoder.cpp" />
<ClCompile Include="ExtendedRead.cpp" />
<ClCompile Include="genres.c" />
<ClCompile Include="http.cpp" />
<ClCompile Include="infobox.cpp" />
<ClCompile Include="info_.cpp" />
<ClCompile Include="localfile.cpp" />
<ClCompile Include="mkv_vorbis_decoder.cpp" />
<ClCompile Include="shaper.cpp" />
<ClCompile Include="vcedit.c" />
<ClCompile Include="wa2.cpp" />
<ClCompile Include="winnt_helper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="api__in_vorbis.h" />
<ClInclude Include="c_string.h" />
<ClInclude Include="decoder.h" />
<ClInclude Include="genres.h" />
<ClInclude Include="main.h" />
<ClInclude Include="mkv_vorbis_decoder.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="shaper.h" />
<ClInclude Include="vcedit.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="in_vorbis.rc" />
</ItemGroup>
<ItemGroup>
<Image Include="oggdrop\112.png" />
<Image Include="oggdrop\113.png" />
<Image Include="oggdrop\114.png" />
<Image Include="oggdrop\115.png" />
<Image Include="oggdrop\116.png" />
<Image Include="oggdrop\117.png" />
<Image Include="oggdrop\118.png" />
<Image Include="oggdrop\119.png" />
<Image Include="oggdrop\120.png" />
<Image Include="oggdrop\121.png" />
<Image Include="oggdrop\122.png" />
<Image Include="oggdrop\123.png" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,145 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="winnt_helper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wa2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="vcedit.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="shaper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mkv_vorbis_decoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="localfile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="infobox.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="info_.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="http.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="genres.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ExtendedRead.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="decoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="config.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="chainedstream_parse.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="c_string.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="about.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nsmkv\Lacing.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nsmkv\vint.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="api__in_vorbis.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="c_string.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="decoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="genres.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="main.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mkv_vorbis_decoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="shaper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="vcedit.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="oggdrop\112.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\113.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\114.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\115.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\116.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\117.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\118.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\119.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\120.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\121.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\122.png">
<Filter>Image Files</Filter>
</Image>
<Image Include="oggdrop\123.png">
<Filter>Image Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{7c471b36-309f-402b-a247-e640a094f9bc}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{735fc214-c8e5-4619-8c70-a184a8373c92}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{00aa1653-baa3-4e88-b6d1-fa408b0c4a85}</UniqueIdentifier>
</Filter>
<Filter Include="Image Files">
<UniqueIdentifier>{32126a2c-dd90-4901-a5e1-aee5b7363e37}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="in_vorbis.rc">
<Filter>Ressource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -1,658 +0,0 @@
//tag editor file i/o code, title formatting interface
#include "main.h"
#include "genres.h"
#include "../nu/AutoWide.h"
#include "../nu/AutoChar.h"
#include "../nu/ns_wc.h"
#include "api__in_vorbis.h"
#include <wchar.h>
#include <math.h>
#include <shlwapi.h>
#include "vcedit.h"
#include <strsafe.h>
#include "resource.h"
namespace ogg_helper //chainedstream_parse
{
int num_get_tracks(HANDLE hFile);
int query_chained_stream_offset(HANDLE hFile, int idx, __int64 * out_beginning, __int64 * out_end);
}
/*static void xfer(HANDLE src, HANDLE dst, __int64 size)
{
enum { BUFFER = 1024 * 1024 };
void * buffer = malloc((int)(BUFFER > size ? size : BUFFER));
while (size > 0)
{
int d = BUFFER;
if ((__int64)d > size) d = (int)size;
DWORD br = 0;
ReadFile(src, buffer, d, &br, 0);
WriteFile(dst, buffer, d, &br, 0);
size -= d;
}
}*/
static void seek64(HANDLE src, __int64 offset)
{
__int64 temp = offset;
SetFilePointer(src, *(DWORD*)&temp, ((long*)&temp + 1), FILE_BEGIN);
}
extern OSVERSIONINFO os_ver;
extern HANDLE hThread;
static DWORDLONG get_space(const wchar_t * url)
{
ULARGE_INTEGER free_space;
char zzz[4] = {(char)url[0], (char)url[1], (char)url[2], 0}; //"c:\";
free_space.QuadPart = 0;
if (os_ver.dwPlatformId == VER_PLATFORM_WIN32_NT || (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && LOWORD(os_ver.dwBuildNumber) > 1000))
{
static BOOL (WINAPI* pGetDiskFreeSpaceEx)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
if (!pGetDiskFreeSpaceEx)
{
pGetDiskFreeSpaceEx = (BOOL (WINAPI*)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER))GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetDiskFreeSpaceExA");
}
if (pGetDiskFreeSpaceEx)
{
ULARGE_INTEGER blah1, blah2;
pGetDiskFreeSpaceEx((LPCTSTR)zzz, &free_space, &blah1, &blah2);
}
}
if (!free_space.QuadPart)
{
DWORD spc, bps, nfc, tnc;
GetDiskFreeSpaceA(zzz, &spc, &bps, &nfc, &tnc);
free_space.QuadPart = UInt32x32To64(spc * bps, nfc);
}
return free_space.QuadPart;
}
bool sync_movefile(const wchar_t * src, const wchar_t * dst);
struct vcedit_param
{
HANDLE hFile;
__int64 remaining;
};
static size_t callback_fread(void *ptr, size_t size, size_t nmemb, vcedit_param * param)
{
int to_read = (int)(nmemb *size);
if (to_read > param->remaining) to_read = (int)param->remaining;
DWORD br = 0;
ReadFile(param->hFile, ptr, to_read, &br, 0);
param->remaining -= br;
return br / size;
}
static size_t callback_write(const void *ptr, size_t size, size_t nmemb, HANDLE hFile)
{
DWORD bw = 0;
WriteFile(hFile, ptr, (DWORD)(size*nmemb), &bw, 0);
return bw / size;
}
BOOL modify_file(const wchar_t* url, const vorbis_comment * comments, int links)
{ //also used for stream save fix
HANDLE dst = INVALID_HANDLE_VALUE;
int scream = 0;
StringW tmp;
winampGetExtendedFileInfoW_Cleanup();
tmp = url;
tmp += L".tmp";
HANDLE src = CreateFileW(url, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (src != INVALID_HANDLE_VALUE)
{
ULARGE_INTEGER src_size;
src_size.LowPart = GetFileSize(src, &src_size.HighPart);
if (src_size.QuadPart > get_space(url))
{ //shit happens... try default temp location
StringW tempdir;
GetTempPathW(MAX_PATH, StringTempW(tempdir, MAX_PATH));
if (get_space(tempdir) < src_size.QuadPart)
{ //oh well
CloseHandle(src);
src = INVALID_HANDLE_VALUE;
}
{
tmp = tempdir;
if (tmp[tmp.Length() - 1] != '\\') tmp.AddChar('\\');
StringCchPrintfW(StringTempW(tempdir, MAX_PATH), MAX_PATH, L"ogg%u_%u.tmp", GetTickCount(), GetCurrentProcessId());
tmp.AddString(tempdir);
}
}
dst = CreateFileW(tmp, GENERIC_WRITE | GENERIC_READ, 0, 0, CREATE_ALWAYS, 0, 0);
}
if (dst != INVALID_HANDLE_VALUE && src != INVALID_HANDLE_VALUE)
{
{
FILETIME ct;
GetFileTime(src, &ct, 0, 0);
SetFileTime(dst, &ct, 0, 0);
}
int num_links = ogg_helper::num_get_tracks(src);
if (num_links < links) scream = 1;
else
{
int cur_link;
for (cur_link = 0; cur_link < links && !scream; cur_link++)
{
__int64 stream_beginning, stream_end;
if (ogg_helper::query_chained_stream_offset(src, cur_link, &stream_beginning, &stream_end))
{
seek64(src, stream_beginning);
vcedit_state *vs;
vcedit_param param;
param.hFile = src;
param.remaining = stream_end - stream_beginning;
vs = vcedit_new_state();
if (vcedit_open_callbacks(vs, &param, (vcedit_read_func)callback_fread, (vcedit_write_func)callback_write) < 0)
{
scream = 1;
}
else
{
vorbis_comment * vc = vcedit_comments(vs);
vorbis_comment_clear(vc);
vorbis_comment_init(vc);
const vorbis_comment * vc_src = comments + cur_link;
int n;
for (n = 0;n < vc_src->comments;n++)
{
if (vc_src->user_comments[n])
vorbis_comment_add(vc, vc_src->user_comments[n]);
}
vcedit_write(vs, dst);
vcedit_clear(vs);
}
}
}
}
}
else scream = 1;
if (src != INVALID_HANDLE_VALUE) CloseHandle(src);
if (dst != INVALID_HANDLE_VALUE)
{
CloseHandle(dst);
if (scream)
{
DeleteFileW(tmp);
}
}
if (!scream)
{
BOOL f_sync;
EnterCriticalSection(&sync);
f_sync = !_wcsicmp(url, cur_file) && hThread; //check for i/o conflict with currently played file
LeaveCriticalSection(&sync);
if (f_sync)
{ //drat, it's now playing
scream = !sync_movefile(tmp, url);
}
else
{
if (!DeleteFileW(url)) scream = 1;
else
{
if (!MoveFileW(tmp, url))
{
if (!CopyFileW(tmp, url, 0)) scream = 1;
DeleteFileW(tmp);
}
}
}
}
if (scream) return 0;
else return 1;
}
wchar_t *wdup(const char * src)
{
return _wcsdup(StringW(src));
}
extern StringW stat_disp;
void GetFileInfo(const wchar_t *file, wchar_t *title, int *len)
{
VorbisFile* vf = 0;
BOOL is_cur_file = 0;
BOOL is_vf_local = 1;
if (title) *title = 0;
if (len) *len = -1;
if (!file || !*file)
{
file = cur_file;
is_cur_file = 1;
}
else if (!lstrcmpiW(file, cur_file))
{
is_cur_file = 1;
}
if (title && stat_disp.Length() > 0 && is_cur_file)
{
lstrcpynW(title, stat_disp, 256);
title = 0;
}
if (!len && !title) return ;
if (is_cur_file)
{
EnterCriticalSection(&sync);
if (theFile)
{
vf = theFile;
is_vf_local = 0;
}
else
LeaveCriticalSection(&sync);
}
if (!vf)
{
vf = VorbisFile::Create(file, 1);
if (!vf)
{
if (title)
{
lstrcpynW(title, PathFindFileNameW(file), 256);
wchar_t *blah = PathFindExtensionW(title);
*blah=0;
}
return ;
}
}
if (len)
{
*len = (int)(vf->Length() * 1000);
}
if (title)
{
const char *t = vf->get_meta("ARTIST", 0);
if (t)
{
MultiByteToWideCharSZ(CP_UTF8, 0, t, -1, title, 256);
t = vf->get_meta("TITLE", 0);
if (t)
{
StringCchCatW(title, 256, L" - ");
StringCchCatW(title, 256, AutoWide(t, CP_UTF8));
}
}
else
{
const char *t = vf->get_meta("TITLE", 0);
if (t)
MultiByteToWideCharSZ(CP_UTF8, 0, t, -1, title, 256);
else
{
lstrcpynW(title, PathFindFileNameW(file), 256);
wchar_t *blah = PathFindExtensionW(title);
*blah=0;
}
}
}
//q:
if (is_vf_local)
delete vf;
else
LeaveCriticalSection(&sync);
}
void w9x_itow(wchar_t *dest, int value, int destlen)
{
StringCchPrintfW(dest, destlen, L"%d", value);
}
void w9x_utow(wchar_t *dest, int value, int destlen)
{
StringCchPrintfW(dest, destlen, L"%u", value);
}
void w9x_htow(wchar_t *dest, int value, int destlen)
{
StringCchPrintfW(dest, destlen, L"%08x", value);
}
static void print_misc(VorbisFile * _vf,int link,wchar_t * out, int outlen)
{
OggVorbis_File * vf=&_vf->vf;
double t=ov_time_total(vf,link);
vorbis_info * vi=ov_info(vf,link);
vorbis_comment * vc=ov_comment(vf,link);
if (!vi || !vc) {WASABI_API_LNGSTRINGW_BUF(IDS_FILE_ERROR,out,outlen);return;}
wchar_t kbps_str[16] = {0};
WASABI_API_LNGSTRINGW_BUF(IDS_KBPS, kbps_str, 16);
wchar_t length[48]=L"", avgbitrate[48]=L"", filesize[48]=L"", nombitrate[48]=L"", maxbitrate[48]=L"", minbitrate[48]=L"";
if (t>0)
{
int h = (int)(t/3600.0);
int m = (int)(t/60.0)%60;
int s = (int)t%60;
if(h>0) StringCchPrintfW(length,48,L"%s%u:%02u:%02u\r\n",WASABI_API_LNGSTRINGW(IDS_LENGTH),h,m,s);
else if(m>0) StringCchPrintfW(length,48,L"%s%u:%02u\r\n",WASABI_API_LNGSTRINGW(IDS_LENGTH),m,s);
else if(s>0) StringCchPrintfW(length,48,L"%s%u\r\n",WASABI_API_LNGSTRINGW(IDS_LENGTH),s);
UINT fs=_vf->FileSize();
if (fs>0)
{
int kbps = (int)(((double)fs)/(t*125.0));
wchar_t tmp[32] = {0};
StringCchPrintfW(avgbitrate,48,L"%s%u %s\r\n",WASABI_API_LNGSTRINGW(IDS_AVERAGE_BITRATE),kbps,kbps_str);
int fs1=fs/1000000;
int fs2=(fs/1000)%1000;
int fs3=fs%1000;
if(fs1)
StringCchPrintfW(filesize,48,L"%s%u%03u%03u %s\r\n",WASABI_API_LNGSTRINGW(IDS_FILE_SIZE),fs1,fs2,fs3,WASABI_API_LNGSTRINGW_BUF(IDS_BYTES,tmp,32));
else if(fs2)
StringCchPrintfW(filesize,48,L"%s%u%03u %s\r\n",WASABI_API_LNGSTRINGW(IDS_FILE_SIZE),fs2,fs3,WASABI_API_LNGSTRINGW_BUF(IDS_BYTES,tmp,32));
else
StringCchPrintfW(filesize,48,L"%s%u %s\r\n",WASABI_API_LNGSTRINGW(IDS_FILE_SIZE),fs3,WASABI_API_LNGSTRINGW_BUF(IDS_BYTES,tmp,32));
}
}
if (vi->bitrate_nominal>0)
StringCchPrintfW(nombitrate,48,L"%s%u %s\r\n",WASABI_API_LNGSTRINGW(IDS_NOMINAL_BITRATE),vi->bitrate_nominal/1000,kbps_str);
if (vi->bitrate_lower>0)
StringCchPrintfW(minbitrate,48,L"%s%u %s\r\n",WASABI_API_LNGSTRINGW(IDS_MIN_BITRATE),vi->bitrate_lower/1000,kbps_str);
if (vi->bitrate_nominal>0)
StringCchPrintfW(maxbitrate,48,L"%s%u %s\r\n",WASABI_API_LNGSTRINGW(IDS_MAX_BITRATE),vi->bitrate_nominal/1000,kbps_str);
wchar_t tmp[32] = {0}, tmp2[32] = {0}, tmp3[32] = {0}, tmp4[32] = {0}, tmp5[32] = {0}, hzStr[8] = {0};
StringCchPrintfW(out,outlen,L"%s%s%s%s%s%s%s: %u\r\n%s: %u %s\r\n%s: %u\r\n%s: %u\r\n%s: \r\n%s",
length, avgbitrate, filesize, nombitrate, maxbitrate, minbitrate,
WASABI_API_LNGSTRINGW_BUF(IDS_CHANNELS,tmp,32),vi->channels,
WASABI_API_LNGSTRINGW_BUF(IDS_SAMPLING_RATE,tmp2,32),vi->rate, WASABI_API_LNGSTRINGW_BUF(IDS_HZ,hzStr,8),
WASABI_API_LNGSTRINGW_BUF(IDS_SERIAL_NUMBER,tmp3,32),ov_serialnumber(vf,link),
WASABI_API_LNGSTRINGW_BUF(IDS_VERSION,tmp4,32),vi->version,
WASABI_API_LNGSTRINGW_BUF(IDS_VENDOR,tmp5,32),(wchar_t*)AutoWide(vc->vendor,CP_UTF8));
}
static VorbisFile* last_vf = 0;
static wchar_t last_file[MAX_PATH] = {0};
static FILETIME ftLastWriteTime;
// is used to determine if the last write time of the file has changed when
// asked to get the metadata for the same cached file so we can update things
BOOL HasFileTimeChanged(const wchar_t *fn)
{
WIN32_FILE_ATTRIBUTE_DATA fileData = {0};
if (GetFileAttributesExW(fn, GetFileExInfoStandard, &fileData) == TRUE)
{
if(CompareFileTime(&ftLastWriteTime, &fileData.ftLastWriteTime))
{
ftLastWriteTime = fileData.ftLastWriteTime;
return TRUE;
}
}
return FALSE;
}
void UpdateFileTimeChanged(const wchar_t *fn)
{
WIN32_FILE_ATTRIBUTE_DATA fileData;
if (GetFileAttributesExW(fn, GetFileExInfoStandard, &fileData) == TRUE)
{
ftLastWriteTime = fileData.ftLastWriteTime;
}
}
// need to call this when we shut down just to make sure things are correctly cleaned up
//(the joys of caching for speed)
void winampGetExtendedFileInfoW_Cleanup(void)
{
if (last_vf)
{
delete last_vf;
last_vf = 0;
}
last_file[0] = 0;
}
static void CALLBACK winampGetExtendedFileInfoW_Timer(HWND hwnd, UINT uMsg, UINT_PTR eventId, DWORD elapsed)
{
// TODO need to do a better way of getting and caching the metadata
// this is _just_ a temp fix for the file being locked when it
// it really needs 'class Info' to be able to cache and read.
KillTimer(hwnd, eventId);
winampGetExtendedFileInfoW_Cleanup();
}
bool KeywordMatch(const char *mainString, const char *keyword)
{
return !_stricmp(mainString, keyword);
}
#define START_TAG_ALIAS(name, alias) if (KeywordMatch(data, name)) lookup=alias
#define TAG_ALIAS(name, alias) else if (KeywordMatch(data, name)) lookup=alias
extern "C" __declspec( dllexport ) int winampGetExtendedFileInfoW(const wchar_t *fn, const char *data, wchar_t *dest, int destlen)
{
if (!_stricmp(data, "type"))
{
dest[0] = '0';
dest[1] = 0;
return 1;
}
else if (!_stricmp(data, "rateable"))
{
dest[0] = '1';
dest[1] = 0;
return 1;
}
else if (!_stricmp(data, "streammetadata"))
{
return 0;
}
if (!fn || (fn && !fn[0])) return 0;
if (!_stricmp(data, "family"))
{
LPCWSTR e;
int pID = -1;
DWORD lcid;
e = PathFindExtensionW(fn);
if (L'.' != *e) return 0;
e++;
lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
if (CSTR_EQUAL == CompareStringW(lcid, NORM_IGNORECASE, e, -1, L"OGG", -1) ||
CSTR_EQUAL == CompareStringW(lcid, NORM_IGNORECASE, e, -1, L"OGA", -1)) pID = IDS_FAMILY_STRING;
if (pID != -1 && S_OK == StringCchCopyW(dest, destlen, WASABI_API_LNGSTRINGW(pID))) return 1;
return 0;
}
if (!_stricmp(data, "mime"))
{
StringCchCopyW(dest, destlen, L"audio/ogg");
return 1;
}
// attempt to cache/use a cached instance of VorbisFile to speed up metadata queries
// which is especially needed with large ogg files (like with a 4Mb embedded image!)
VorbisFile* vf = 0;
if(last_file[0] && !_wcsicmp(last_file, fn) && !HasFileTimeChanged(fn))
{
vf = last_vf;
}
else
{
// different file so clean up if there's a cached instance
if(last_vf)
{
delete last_vf;
last_vf = 0;
}
// open the new file and cache the current filename for subsequent query checks
vf = VorbisFile::Create(fn, 1);
lstrcpynW(last_file, fn, MAX_PATH);
}
if (!vf) return 0;
else last_vf = vf;
// TODO need to do a better way of getting and caching the metadata
// this is _just_ a temp fix for the file being locked when it
// it really needs 'class Info' to be able to cache and read.
SetTimer(mod.hMainWindow, 256, 2000, winampGetExtendedFileInfoW_Timer);
const char *lookup = 0;
if (!_stricmp(data, "length"))
{
int len = (int)(vf->Length() * 1000);
w9x_itow(dest, len, destlen);
return 1;
}
else if (!_stricmp(data, "bitrate"))
{
int br = vf->get_avg_bitrate();
w9x_itow(dest, br, destlen);
return 1;
}
else if (!_stricmp(data, "SERIALNUMBER"))
{
w9x_utow(dest, ov_serialnumber(&vf->vf, -1), destlen);
return 1;
}
else if (!_stricmp(data, "SERIALNUMBER_HEX"))
{
w9x_htow(dest, ov_serialnumber(&vf->vf, -1), destlen);
return 1;
}
else if (!_stricmp(data, "gain"))
{
float gain = 20.0f*(float)log10(vf->GetGain());
StringCchPrintfW(dest, destlen, L"%-+.2f dB", gain);
return 1;
}
else if(!_stricmp(data,"formatinformation"))
{
print_misc(vf,0,dest,destlen);
return 1;
}
TAG_ALIAS("title", "TITLE");
TAG_ALIAS("artist", "ARTIST");
TAG_ALIAS("album", "ALBUM");
TAG_ALIAS("genre", "GENRE");
TAG_ALIAS("comment", "COMMENT");
TAG_ALIAS("year", "DATE");
TAG_ALIAS("track", "TRACKNUMBER");
TAG_ALIAS("albumartist", "ALBUMARTIST");
TAG_ALIAS("composer", "COMPOSER");
TAG_ALIAS("disc", "DISCNUMBER");
TAG_ALIAS("publisher", "PUBLISHER");
TAG_ALIAS("conductor", "CONDUCTOR");
TAG_ALIAS("tool", "ENCODED-BY");
TAG_ALIAS("replaygain_track_gain", "REPLAYGAIN_TRACK_GAIN");
TAG_ALIAS("replaygain_track_peak", "REPLAYGAIN_TRACK_PEAK");
TAG_ALIAS("replaygain_album_gain", "REPLAYGAIN_ALBUM_GAIN");
TAG_ALIAS("replaygain_album_peak", "REPLAYGAIN_ALBUM_PEAK");
TAG_ALIAS("GracenoteFileID", "GRACENOTEFILEID");
TAG_ALIAS("GracenoteExtData", "GRACENOTEEXTDATA");
TAG_ALIAS("bpm", "BPM");
TAG_ALIAS("remixing", "REMIXING");
TAG_ALIAS("subtitle", "VERSION");
TAG_ALIAS("isrc", "ISRC");
TAG_ALIAS("category", "CATEGORY");
TAG_ALIAS("rating", "RATING");
TAG_ALIAS("producer", "PRODUCER");
if (!lookup)
return 0;
const char *value = vf->get_meta(lookup, 0);
if(KeywordMatch("comment",data)) {
if(!value || !*value) value = vf->get_meta("DESCRIPTION", 0);
}
if(KeywordMatch("year",data)) {
if(!value || !*value) value = vf->get_meta("YEAR", 0);
}
if(KeywordMatch("track",data)) {
if(!value || !*value) value = vf->get_meta("TRACK", 0);
}
if(KeywordMatch("albumartist",data)) {
if(!value || !*value) value = vf->get_meta("ALBUM ARTIST", 0);
if(!value || !*value) value = vf->get_meta("ENSEMBLE", 0);
}
if(KeywordMatch("publisher",data)) {
if(!value || !*value) value = vf->get_meta("ORGANIZATION", 0);
}
if(KeywordMatch("category",data)) {
if(!value || !*value) value = vf->get_meta("CONTENTGROUP", 0);
if(!value || !*value) value = vf->get_meta("GROUPING", 0);
}
if(KeywordMatch(data, "rating")) {
if(!value || !*value) value = vf->get_meta("RATING", 0);
if(value && *value) {
int rating = atoi(value);
// keeps things limited to our range of 0-100
if (rating >= 100) {
rating = 5;
}
// 1-100 case
else if (rating > 5 && rating < 100) {
rating /= 20;
// shift up by one rating when in next band
// 1-20 = 1, 21-40 = 2, 41-60 = 3, 61-80 = 4, 81-100 = 5
rating += ((atoi(value) - (rating * 20)) > 0);
}
// Remove support for old 1-10 range
/* or maybe we're dealing with a 1-10 range
else if (rating > 5) {
rating /= 2;
} */
// otherwise it is hopefully in the 0-5 range
else if (rating > 0 && rating <= 5) {
}
// otherwise just make sure and set zero
else {
rating = 0;
}
StringCchPrintfW(dest, destlen, L"%u", rating);
return 1;
}
}
if(value)
MultiByteToWideCharSZ(CP_UTF8, 0, value, -1, dest, destlen);
else
{
dest[0]=0;
return 1;
}
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,260 +0,0 @@
#include "main.h"
#include "../nu/AutoChar.h"
extern CfgInt cfg_fullbuf;
int VorbisFile::_f_close(void *) {return 0;}
int VorbisFile::_f_seek(void* rs,__int64 offset,int whence)
{
return ((VorbisFile*)rs)->f_seek(offset,whence);
}
size_t VorbisFile::_f_read(void* ptr,size_t size,size_t nmemb,void * rs)
{
return ((VorbisFile*)rs)->f_read((UINT)(size*nmemb),ptr);
}
long VorbisFile::_f_tell(void* rs)
{
return ((VorbisFile*)rs)->f_tell();
}
ov_callbacks VorbisFile::oc={_f_read,_f_seek,_f_close,_f_tell};
static __int64 Seek64(HANDLE hf, __int64 distance, DWORD MoveMethod)
{
LARGE_INTEGER li;
li.QuadPart = distance;
li.LowPart = SetFilePointer (hf, li.LowPart, &li.HighPart, MoveMethod);
if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
{
li.QuadPart = -1;
}
return li.QuadPart;
}
static __int64 FileSize64(HANDLE file)
{
LARGE_INTEGER position;
position.QuadPart=0;
position.LowPart = GetFileSize(file, (LPDWORD)&position.HighPart);
if (position.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
return INVALID_FILE_SIZE;
else
return position.QuadPart;
}
class VorbisFile_Local : public VorbisFile
{
private:
HANDLE hFile;
protected:
int f_seek(__int64 offset,int whence)
{
if(whence==SEEK_SET) offset+=baseoffs;
if (Seek64(hFile,offset,whence) != INVALID_SET_FILE_POINTER) return 0;
else return -1;
}
size_t f_read(UINT siz,void * ptr)
{
DWORD bw=0;
ReadFile(hFile,ptr,siz,&bw,0);
return bw;
}
UINT f_tell()
{
return (UINT)(SetFilePointer(hFile,0,0,FILE_CURRENT)-baseoffs);
}
UINT FileSize()
{
return (UINT)(FileSize64(hFile)-baseoffs);
}
public:
virtual int GetType() {return TYPE_LOCAL;}
VorbisFile_Local(HANDLE f,const wchar_t * u,bool is_info) : VorbisFile(u,is_info) {hFile=f;}
~VorbisFile_Local() {CloseHandle(hFile);}
};
class VorbisFile_Mem : public VorbisFile
{
BYTE * block;
UINT size,ptr;
protected:
int f_seek(__int64 offset,int whence)
{
switch(whence)
{
case SEEK_SET:
ptr=(UINT)(offset+baseoffs);
break;
case SEEK_CUR:
ptr+=(UINT)offset;
break;
case SEEK_END:
ptr=size+whence;
break;
}
if (ptr<=size) return 0;
else {ptr=size;return -1;}
}
size_t f_read(UINT siz,void * out)
{
UINT d=size-ptr;
if (d>siz) d=siz;
memcpy(out,block+ptr,d);
ptr+=d;
return d;
}
UINT f_tell()
{
return (UINT)(ptr-baseoffs);
}
UINT FileSize()
{
return (UINT)(size-baseoffs);
}
public:
virtual int GetType() {return TYPE_LOCAL;}
VorbisFile_Mem(HANDLE f,const wchar_t * u,bool is_info) : VorbisFile(u,is_info)
{
size=GetFileSize(f,0);
ptr=0;
block=(BYTE*)malloc(size);
DWORD br = 0;
ReadFile(f,block,size,&br,0);
CloseHandle(f);
}
~VorbisFile_Mem() {free(block);}
};
VorbisFile * VorbisFile::Create(const wchar_t *url, bool is_info)
{
VorbisFile * r;
if (PathIsURLW(url))
{
if (is_info) return 0;
r=Create_HTTP(AutoChar(url),is_info);
}
else
{
__int64 baseoffs=0;
HANDLE f=CreateFileW(url,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
if (f==INVALID_HANDLE_VALUE) return 0;
{
DWORD dw = 0, br = 0;
ReadFile(f,&dw,4,&br,0);
if(br==4 && dw=='SggO')
{
SetFilePointer(f,0,0,FILE_BEGIN);
}
else if(br==4 && dw=='FFIR')
{
//RIFF file
DWORD wavhdr = 0, nb = 0;
SetFilePointer(f,4,0,FILE_CURRENT);
ReadFile(f,&wavhdr,4,&nb,0);
if(nb!=4 || wavhdr!='EVAW')
{
goto abort;
}
//find data starting point
char tmp[1024] = {0};
ReadFile(f,&tmp,1024,&nb,0);
for(int i=0;i<1020;i++)
if(tmp[i]=='d'&&tmp[i+1]=='a'&&tmp[i+2]=='t'&&tmp[i+3]=='a')
{
baseoffs=i+12+8;
Seek64(f, baseoffs, FILE_BEGIN);
}
if(!baseoffs) goto abort;
}
else
{
abort:
CloseHandle(f);
return 0;
}
}
r=cfg_fullbuf ? (VorbisFile*)new VorbisFile_Mem(f,url,is_info) : (VorbisFile*)new VorbisFile_Local(f,url,is_info);
r->setBaseOffset(baseoffs);
}
if (r && !r->init())
{
delete r;
r=0;
}
return r;
}
bool VorbisFile::init()
{
if (ov_open_callbacks(this,&vf,0,0,oc)) return 0;
//TODO bitrate
UINT siz=FileSize();
double len=Length();
if (siz>0 && len>0)
{
UINT divisor = (UINT)(len*125.0);
if (divisor)
avg_kbps=siz/divisor;
}
post_init();
return 1;
}
int is_http(const char* url)
{
return (!_strnicmp(url,"http://",7) || !_strnicmp(url,"https://",8));
}
void VorbisFile::set_meta(const vorbis_comment * vc,int links)
{
if (links == vf.links)
{
int n;
for(n=0;n<links;n++)
{
vorbis_comment_clear(vf.vc+n);
/*
extern void vorbis_comment_init(vorbis_comment *vc);
extern void vorbis_comment_add(vorbis_comment *vc, char *comment);
extern void vorbis_comment_add_tag(vorbis_comment *vc,char *tag, char *contents);
extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count);
extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag);
extern void vorbis_comment_clear(vorbis_comment *vc);
*/
}
_ogg_free(vf.vc);
vf.vc = (vorbis_comment*) _ogg_calloc(links,sizeof(vorbis_comment));
for(n=0;n<links;n++)
{
vorbis_comment_init(vf.vc+n);
int c;
for(c=0;c<vc[n].comments;c++)
{
vorbis_comment_add(vf.vc+n,vc[n].user_comments[c]);
}
vf.vc[n].vendor = _strdup(vc[n].vendor);
}
}
}

View File

@ -1,220 +0,0 @@
#ifndef IN_VORBIS_MAIN_H
#define IN_VORBIS_MAIN_H
#define WINSOCK_API_LINKAGE
#ifndef STRICT
#define STRICT
#endif
#include <windows.h>
extern int (*warand)();
extern float (*warandf)();
inline void * z_malloc(int x)
{
void* foo=malloc(x);
if (foo) memset(foo,0,x);
return foo;
}
#include <shlwapi.h>
#include <malloc.h>
#define uitoa(x,y) _itoa(x,y,10)
#define atoui atoi
#include <vorbis\vorbisfile.h>
#include "c_string.h"
#include "../Winamp/in2.h"
extern In_Module mod;
#include "resource.h"
#define VER L"1.79"
#define _NAME "Nullsoft Vorbis Decoder"
extern "C"
{
extern const char *INI_FILE;
extern const wchar_t *INI_DIRECTORY;
}
class CfgVar
{
private:
String name;
CfgVar * next;
static CfgVar * list;
public:
static void ReadConfig();
static void WriteConfig();
//helpers
static bool read_struct(const char *inifile, const char *section, const char * name,void * ptr,UINT size);
static void write_struct(const char *inifile, const char *section, const char * name,void * ptr,UINT size);
static void write_int(const char *inifile, const char *section, const char * name,int val);
static int read_int(const char *inifile, const char *section,const char * name,int def);
protected:
CfgVar(const char * n) : name(n) {next=list;list=this;}
virtual void Read(const char * name)=0;
virtual void Write(const char * name)=0;
};
class CfgInt : private CfgVar
{
private:
int def,value;
public:
CfgInt(const char * name,int _def) : CfgVar(name) {value=def=_def;}
inline int operator=(int x) {value=x;return value;}
inline operator int() {return value;}
private:
virtual void Read(const char * name);
virtual void Write(const char * name);
};
class CfgString : private CfgVar, public StringW
{
private:
StringW def;
public:
CfgString(const char * name,const char * _def) : CfgVar(name), StringW(_def), def(_def) {}
private:
virtual void Read(const char * name);
virtual void Write(const char * name);
};
template<class T>
class CfgStructT : private CfgVar
{
public:
T data;
CfgStructT(const char * name) : CfgVar(name) {}
private:
void Read(const char * name) { read_struct(INI_FILE, "in_vorbis",name,&data,sizeof(data));}
void Write(const char * name) {if (IsValueDefault()) WritePrivateProfileStringA("in_vorbis", name, 0, INI_FILE); else write_struct(INI_FILE, "in_vorbis", name, &data, sizeof(data));}
protected:
virtual bool IsValueDefault() {return 0;}
};
class CfgFont : public CfgStructT<LOGFONT>
{
private:
void get_def(LOGFONT * f) {memset(f,0,sizeof(LOGFONT));GetObject(GetStockObject(DEFAULT_GUI_FONT),sizeof(LOGFONT),f);}
virtual bool IsValueDefault()
{
LOGFONT t;
get_def(&t);
return !memcmp(&data,&t,sizeof(LOGFONT));
}
public:
CfgFont(const char * name) : CfgStructT<LOGFONT>(name)
{
get_def(&data);
}
};
extern int32_t priority_tab[7];
extern HINSTANCE hIns;
extern CfgString cfg_ssave_format,cfg_dumpdir;
int is_http(const char* url);
class VorbisFile
{
protected:
virtual int f_seek(__int64 offset,int whence)=0;
virtual size_t f_read(UINT siz,void * ptr)=0;
virtual UINT f_tell()=0;
static int _f_close(void *);
static int _f_seek(void* rs,__int64 offset,int whence);
static size_t _f_read(void* ptr,size_t size,size_t nmemb,void * rs);
static long _f_tell(void* rs);
static ov_callbacks oc;
static VorbisFile * Create_HTTP(const char * url,bool is_info);
VorbisFile(const wchar_t * u, bool is_info) : url(u) {memset(&vf,0,sizeof(vf));stopping=0;abort_prebuf=0;avg_kbps=0;use_prebuf=0;primary=!is_info; baseoffs=0;}
bool init();
virtual void post_init() {};
UINT avg_kbps;
bool Aborting();
__int64 baseoffs;
public:
enum {TYPE_LOCAL,TYPE_HTTP};
virtual int GetType()=0;
virtual bool IsLive() {return 0;}
virtual void do_prebuf() {use_prebuf=1;abort_prebuf=0;};
StringW url;
String withlp;
String stream_title;
bool stopping,abort_prebuf,use_prebuf;
bool primary;//display status messages or not
OggVorbis_File vf;
UINT get_avg_bitrate()
{
if (avg_kbps>0) return avg_kbps;
vorbis_info * vi=ov_info(&vf,-1);
if (!vi) return 0;
return vi->bitrate_nominal/1000;
}
const char* get_meta(const char* tag,UINT c);
void set_meta(const vorbis_comment * vc,int links);
static VorbisFile * Create(const wchar_t * url,bool is_info);
double Length() {return ov_time_total(&vf,-1);}
double GetPos() {return ov_time_tell(&vf);}
int Seek(double p);
void Status(const wchar_t * zzz);
virtual UINT FileSize()=0;
virtual ~VorbisFile() {ov_clear(&vf);}
virtual void Idle() {Sleep(10);}
virtual void setBaseOffset(__int64 offs) { baseoffs=offs; }
float GetGain();
};
extern VorbisFile * theFile;
extern StringW cur_file;
extern CRITICAL_SECTION sync;
BOOL modify_file(const wchar_t* url,const vorbis_comment * comments,int links);
void winampGetExtendedFileInfoW_Cleanup(void);
void UpdateFileTimeChanged(const wchar_t *fn);
void do_cfg(int s);
bool KeywordMatch(const char *mainString, const char *keyword);
class Info
{
public:
Info(const wchar_t *filename);
~Info();
bool Save();
int Error() { return vc==0?1:0; }
int GetNumMetadataItems();
void EnumMetadata(int n,wchar_t *key,int keylen, wchar_t *val, int vallen);
void RemoveMetadata(wchar_t * key);
void RemoveMetadata(int n);
void SetMetadata(wchar_t *key, wchar_t *val);
void SetMetadata(int n, wchar_t *key, wchar_t *val);
void SetTag(int n,wchar_t *key); // changes the key name
private:
const wchar_t *filename;
vorbis_comment * vc;
int numstreams, stream;
};
// {B6CB4A7C-A8D0-4c55-8E60-9F7A7A23DA0F}
static const GUID playbackConfigGroupGUID =
{ 0xb6cb4a7c, 0xa8d0, 0x4c55, { 0x8e, 0x60, 0x9f, 0x7a, 0x7a, 0x23, 0xda, 0xf } };
#endif //IN_VORBIS_MAIN_H

View File

@ -1,194 +0,0 @@
#include "mkv_vorbis_decoder.h"
#include "../nsmkv/Lacing.h"
#include "../nsmkv/Cluster.h"
#include <math.h>
int MKVDecoderCreator::CreateAudioDecoder(const char *codec_id,
const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data,
unsigned int preferred_bits, unsigned int max_channels, bool floating_point,
ifc_mkvaudiodecoder **decoder)
{
if (!strcmp(codec_id, "A_VORBIS"))
{
MKVVorbis *vorbis = new MKVVorbis;
vorbis_info_init(&vorbis->info);
vorbis_comment_init(&vorbis->comment);
nsmkv::LacingState lacing_state;
if (nsmkv::Lacing::GetState(nsmkv::BlockBinary::XIPH_LACING, (const uint8_t *)track_entry_data->codec_private, track_entry_data->codec_private_len, &lacing_state))
{
const uint8_t *frame;
size_t frame_len;
uint16_t frame_number=0;
while (nsmkv::Lacing::GetFrame(frame_number, (const uint8_t *)track_entry_data->codec_private, track_entry_data->codec_private_len, &frame, &frame_len, &lacing_state))
{
ogg_packet packet = {const_cast<uint8_t *>(frame), (long)frame_len, (frame_number==0), 0, 0 /*-1?*/, vorbis->packet_number++};
int ret = vorbis_synthesis_headerin(&vorbis->info, &vorbis->comment, &packet);
if (ret != 0)
goto bail;
frame_number++;
}
if (vorbis_synthesis_init(&vorbis->dsp, &vorbis->info) == 0
&& vorbis_block_init(&vorbis->dsp, &vorbis->block) == 0)
{
vorbis->bps = preferred_bits?preferred_bits:16;
*decoder = vorbis;
return CREATEDECODER_SUCCESS;
}
}
bail:
delete vorbis;
return CREATEDECODER_FAILURE;
}
return CREATEDECODER_NOT_MINE;
}
#define CBCLASS MKVDecoderCreator
START_DISPATCH;
CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
END_DISPATCH;
#undef CBCLASS
MKVVorbis::MKVVorbis()
{
bps=16;
packet_number=0;
}
#define PA_CLIP_( val, min, max )\
{ val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); }
#if defined(_M_IX86)
static __inline long float_to_long(double t)
{
long r;
__asm fld t
__asm fistp r
return r;
}
#else
#define float_to_long(x) ((long)( x ))
#endif
inline static void clip(double &x, double a, double b)
{
double x1 = fabs (x - a);
double x2 = fabs (x - b);
x = x1 + (a + b);
x -= x2;
x *= 0.5;
}
static void Float32_To_Int24_Clip(void *destinationBuffer, void *sourceBuffer, size_t count, size_t channels, double gain)
{
float *src = (float*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
gain*=65536.*32768.;
while ( count-- )
{
/* convert to 32 bit and drop the low 8 bits */
double scaled = *src * gain;
clip( scaled, -2147483648., 2147483647.);
signed long temp = (signed long) scaled;
dest[0] = (unsigned char)(temp >> 8);
dest[1] = (unsigned char)(temp >> 16);
dest[2] = (unsigned char)(temp >> 24);
src++;
dest += 3*channels;
}
}
static void Float32_To_Int16_Clip(void *destinationBuffer, void *sourceBuffer, size_t count, size_t channels, double gain)
{
float *src = (float*)sourceBuffer;
signed short *dest = (signed short*)destinationBuffer;
gain*=32768.0;
while ( count-- )
{
long samp = float_to_long((*src) * gain/* - 0.5*/);
PA_CLIP_( samp, -0x8000, 0x7FFF );
*dest = (signed short) samp;
src ++;
dest += channels;
}
}
int MKVVorbis::DecodeBlock(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
{
uint8_t *out = (uint8_t *)outputBuffer;
ogg_packet packet = {(uint8_t *)inputBuffer, (long)inputBufferBytes, 0, 0, 0 -1, packet_number++};
int ret = vorbis_synthesis(&block, &packet);
if (ret == 0)
{
vorbis_synthesis_blockin(&dsp,&block);
long channels = info.channels;
float **pcm;
int samples = vorbis_synthesis_pcmout(&dsp, &pcm);
if (samples)
{
switch(bps)
{
case 16:
for(int i=0;i<channels;i++)
{
Float32_To_Int16_Clip(out, pcm[i], samples, channels, 1.0 /*gain*/);
out+=2;
}
break;
case 24:
for(int i=0;i<channels;i++)
{
Float32_To_Int24_Clip(out, pcm[i], samples, channels, 1.0 /*gain*/);
out+=3;
}
break;
}
}
*outputBufferBytes = samples*channels*bps/8;
// let the decoder know we're processed them
vorbis_synthesis_read(&dsp,samples);
return MKV_SUCCESS;
}
return MKV_FAILURE;
}
int MKVVorbis::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat)
{
*sampleRate = info.rate;
*channels = info.channels;
*bitsPerSample = bps;
*isFloat = false; // TODO
return MKV_SUCCESS;
}
void MKVVorbis::Flush()
{
vorbis_synthesis_restart(&dsp);
}
void MKVVorbis::Close()
{
// TODO: benski> verify
vorbis_info_clear(&info);
vorbis_comment_clear(&comment);
vorbis_dsp_clear(&dsp);
vorbis_block_clear(&block);
delete this;
}
#define CBCLASS MKVVorbis
START_DISPATCH;
//CB(OUTPUT_FRAME_SIZE, OutputFrameSize)
CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
CB(DECODE_BLOCK, DecodeBlock)
VCB(FLUSH, Flush)
VCB(CLOSE, Close)
END_DISPATCH;
#undef CBCLASS

View File

@ -1,41 +0,0 @@
#pragma once
#include "../in_mkv/ifc_mkvaudiodecoder.h"
#include "../in_mkv/svc_mkvdecoder.h"
#include <vorbis/codec.h>
// {6058D315-2F08-4b2f-903E-4C2E6B5EFFA9}
static const GUID mkv_vorbis_guid =
{ 0x6058d315, 0x2f08, 0x4b2f, { 0x90, 0x3e, 0x4c, 0x2e, 0x6b, 0x5e, 0xff, 0xa9 } };
class MKVDecoderCreator : public svc_mkvdecoder
{
public:
static const char *getServiceName() { return "Vorbis MKV Decoder"; }
static GUID getServiceGuid() { return mkv_vorbis_guid; }
int CreateAudioDecoder(const char *codec_id,
const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data,
unsigned int preferred_bits, unsigned int max_channels, bool floating_point,
ifc_mkvaudiodecoder **decoder);
protected:
RECVS_DISPATCH;
};
class MKVVorbis : public ifc_mkvaudiodecoder
{
public:
MKVVorbis();
int DecodeBlock(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes);
int GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat);
void Flush();
void Close();
//private:
unsigned int bps;
vorbis_info info;
vorbis_dsp_state dsp;
vorbis_block block;
vorbis_comment comment;
ogg_int64_t packet_number;
protected:
RECVS_DISPATCH;
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 817 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 753 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 705 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 755 B

View File

@ -1,177 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ogg.rc
//
#define IDS_NULLSOFT_VORBIS_DECODER_OLD 0
#define IDS_PLEASE_ENTER_TAG_NAME 1
#define IDS_TAG_NAME_CONTAINS_INVALID_CHARS 2
#define IDOKAUTH 3
#define IDS_ERASE_ALL_FIELDS_ON_LIST 3
#define IDCANCELAUTH 4
#define IDS_WARNING 4
#define IDS_FILE_ERROR 5
#define IDS_LENGTH 6
#define IDS_AVERAGE_BITRATE 7
#define IDS_FILE_SIZE 8
#define IDS_NOMINAL_BITRATE 9
#define IDS_MIN_BITRATE 10
#define IDS_MAX_BITRATE 11
#define IDS_CHANNELS 12
#define IDS_SAMPLING_RATE 13
#define IDS_SERIAL_NUMBER 14
#define IDS_VERSION 15
#define IDS_Vendor 16
#define IDS_VENDOR 16
#define IDS_TO_SIMPLE_MODE 17
#define IDS_TO_ADVANCED_MODE 18
#define IDS_OGG_VORBIS_INFO 19
#define IDS_WRITE_ERROR 20
#define IDS_BEST_RPM 21
#define IDS_ABOUT 22
#define IDS_LEAVE_AS_IS 24
#define IDS_REMAP_6_CHANNELS 25
#define IDS_DOWNMIX_TO_4_CHANNELS 26
#define IDS_DOWNMIX_TO_2_CHANNELS_DS 27
#define IDS_DOWNMIX_TO_2_CHANNELS_DS2 28
#define IDS_DOWNMIX_TO_MONO 29
#define IDS_CORRECT_FL_FC_FR_BL_BR_LFE 30
#define IDS_BROKEN_FL_FR_FC_BL_BR_LFE 31
#define IDS_IDLE 32
#define IDS_ABOUT_TEXT 32
#define IDS_LOWEST 33
#define IDS_BELOW_NORMAL 34
#define IDS_NORMAL 35
#define IDS_ABOVE_NORMAL 36
#define IDS_HIGHEST 37
#define IDS_TIME_CRITICAL 38
#define IDS_TITLE_PREFERENCES 39
#define IDS_DO_NOT_ENABLE_24_BIT_OUTPUT 40
#define IDS_ONE_TIME_FAQ_REMINDER 41
#define IDS_RUNNING_ON_NT_OS 42
#define IDS_RUNNING_ON_WIN9X 43
#define IDS_NEVER 44
#define IDS_PORT_80_ONLY 45
#define IDS_ALWAYS 46
#define IDS_SELECT_OUTPUT_DIRECTORY 47
#define IDS_DECODING 48
#define IDS_DISPLAY 49
#define IDS_STREAMING 50
#define IDS_CONNECTING 51
#define IDS_PREBUFFERING 52
#define IDS_AUTH_REQUIRED 53
#define IDS_OGG_FILES 54
#define IDS_NAME 55
#define IDS_VALUE 56
#define IDS_KBPS 57
#define IDS_STRING2 58
#define IDS_HZ 58
#define IDS_GAME_SPEED 59
#define IDS_STRING1 60
#define IDS_BYTES 60
#define IDS_FAMILY_STRING 61
#define IDC_CONFIG_TAB1 101
#define IDD_INFO_DLG 102
#define IDC_CONFIG_TAB2 102
#define IDC_CONFIG_TAB3 103
#define IDD_INFO_DLG1 104
#define IDC_CONFIG_TAB4 104
#define IDD_ABOUT 112
#define IDB_BITMAP1 115
#define IDB_BITMAP2 116
#define IDB_BITMAP3 117
#define IDB_BITMAP4 118
#define IDB_BITMAP5 119
#define IDB_BITMAP6 120
#define IDB_BITMAP7 121
#define IDB_BITMAP8 122
#define IDB_BITMAP9 123
#define IDB_BITMAP10 124
#define IDB_BITMAP11 125
#define IDB_BITMAP12 126
#define IDD_HTTPAUTH 128
#define IDD_INFO 131
#define IDD_DIALOG1 132
#define IDD_CONFIG 132
#define IDD_INFO_DLG_NEW 133
#define IDD_INFO_PANEL_ADVANCED 134
#define IDD_INFO_PANEL_SIMPLE 135
#define IDB_PNG1 136
#define IDB_PNG2 137
#define IDB_PNG3 138
#define IDB_PNG4 139
#define IDB_PNG5 140
#define IDB_PNG6 141
#define IDB_PNG7 142
#define IDB_PNG8 143
#define IDB_PNG9 144
#define IDB_PNG10 145
#define IDB_PNG11 146
#define IDB_PNG12 147
#define IDC_LIST 1001
#define IDC_NAME 1002
#define IDC_TITLE 1002
#define IDC_VALUE 1003
#define IDC_ARTIST 1003
#define IDC_HTTP_BSIZE 1004
#define IDC_ALBUM 1004
#define IDC_STREAM_SAVE 1005
#define IDC_GENRE 1005
#define IDC_FSAVE 1006
#define IDC_YEAR 1006
#define IDC_DATE 1006
#define IDC_CUSTOM1 1007
#define IDC_MISC 1007
#define IDC_AVG_BR 1008
#define IDC_FIX0R 1009
#define IDC_PROXY 1012
#define IDC_URL 1012
#define IDC_SLIDER1 1013
#define IDC_SLIDER2 1014
#define IDC_BUTTON_ADD 1015
#define IDC_BUTTON_DEL 1016
#define IDC_BUTTON_DELALL 1017
#define IDC_RPM 1018
#define IDC_RPM2 1019
#define IDC_MC6_DM 1020
#define IDC_MC6_MAP 1021
#define IDC_SSAVE_FMT 1022
#define IDC_SSAVE_FMT_DEF 1023
#define IDC_FULLBUF 1025
#define IDC_EDITAUTH 1026
#define IDC_REALM 1027
#define IDC_TRACK 1028
#define IDC_STATIC_MISC 1034
#define IDC_STATIC_TAGS 1035
#define IDC_STATIC_STD 1036
#define IDC_STATIC_TRACK 1037
#define IDC_SEPARATE 1038
#define IDC_DELETE_ALL 1039
#define IDC_RG 1040
#define IDC_RG_MODE 1041
#define IDC_NOCLIP 1042
#define IDC_HARDLIMIT 1043
#define IDC_PREAMP_STAT 1044
#define IDC_TAB 1045
#define IDC_MODE_TOGGLE 1053
#define IDC_NEXT_STREAM 1054
#define IDC_PREV_STREAM 1055
#define IDC_STATIC_CS 1056
#define IDC_HIDE_SPEC 1058
#define IDC_COMMENT 1060
#define IDC_ABOUT_TEXT 1061
#define IDC_OS_BLAH 1062
#define IDC_REMEMBER_INFOSIZE 1063
#define IDC_FONTNAME 1064
#define IDC_PREAMP_RG 1065
#define IDS_NULLSOFT_VORBIS_DECODER 65534
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 148
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1067
#define _APS_NEXT_SYMED_VALUE 105
#endif
#endif

View File

@ -1,108 +0,0 @@
#ifndef _RF_H_
#define _RF_H_
//based on Tempura specs.
//NOT compatible with WA3 alphas
class WReader
{
protected:
/* WReader
** WReader constructor
*/
WReader() : m_player(0) { }
public:
/* m_player
** Filled by Winamp. Pointer to Winamp 3 core interface
*/
/*WPlayer_callback*/ void *m_player; //PP: hack. read_file.dll doesn't call it at all. simply don't touch it
/* GetDescription
** Retrieves your plug-in's text description
*/
virtual char *GetDescription() { return "Unknown"; };
/* Open
** Used to open a file, return 0 on success
*/
virtual int Open(char *url, bool *killswitch)=0;
/* Read
** Returns number of BYTES read (if < length then eof or killswitch)
*/
virtual int Read(char *buffer, int length, bool *killswitch)=0;
/* GetLength
** Returns length of the entire file in BYTES, return -1 on unknown/infinite (as for a stream)
*/
virtual int GetLength(void)=0;
/* CanSeek
** Returns 1 if you can skip ahead in the file, 0 if not
*/
virtual int CanSeek(void)=0; //PP: currently available read_file.dll vesions can always seek in any direction
/* Seek
** Jump to a certain absolute position
*/
virtual int Seek(int position, bool *killswitch)=0;
/* GetHeader
** Retrieve header. Used in read_http to retrieve the HTTP header
*/
virtual char *GetHeader(char *name) { return 0; }
/* ~WReader
** WReader virtual destructor
*/
//virtual ~WReader() { }
virtual void Release(int) {};
//PP: hack - shut up linker when getting rid of evil CRT library; seems to work OK under Tempura
};
#define READ_VER 0x100
typedef struct
{
/* version
** Version revision number
*/
int version;
/* description
** Text description of the reader plug-in
*/
char *description;
/* create
** Function pointer to create a reader module
*/
WReader *(*create)();
/* ismine
** Determines whether or not a file should be read by this plug-in
*/
int (*ismine)(char *url);
} reader_source;
//exported symbol is:
//int readerSource(HINSTANCE,reader_source**);
/*
(not a part of Tempura specs)
int _stdcall gzip_writefile(char* path,void* buf,DWORD size) - writes a memory block to a GZIP file - in_midi calls it from file info box
other hacks:
recent versions understand file://... urls, can do partial file access (eg. "partial://00006666-66660000:c:\foo\bar.dat\zzz.wav" (zzz.wav is the "display name" + extension to make winamp select correct plug-in) and auto-detect CD drive letter (eg. #:\x.mp3 will scan all drives for that file; also works with partial:// )
you can (for an example) build a playlist which will play Unreal soundtrack directly from the game CD on any system
latest read_file.dll is bundled with the midi plug-in: http://www.blorp.com/~peter/zips/in_midi.zip
*/
#endif

View File

@ -1,245 +0,0 @@
#include "Shaper.h"
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028842
#endif
#define RANDBUFLEN 65536
#define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5)))
const int scoeffreq[] =
{
0, 48000, 44100, 37800, 32000, 22050, 48000, 44100
};
const int scoeflen[] =
{
1, 16, 20, 16, 16, 15, 16, 15
};
const int samp[] =
{
8, 18, 27, 8, 8, 8, 10, 9
};
const double shapercoefs[8][21] =
{
{
-1
}
, /* triangular dither */
{ -2.8720729351043701172, 5.0413231849670410156, -6.2442994117736816406, 5.8483986854553222656,
-3.7067542076110839844, 1.0495119094848632812, 1.1830236911773681641, -2.1126792430877685547,
1.9094531536102294922, -0.99913084506988525391, 0.17090806365013122559, 0.32615602016448974609,
-0.39127644896507263184, 0.26876461505889892578, -0.097676105797290802002, 0.023473845794796943665,
}, /* 48k, N=16, amp=18 */
{ -2.6773197650909423828, 4.8308925628662109375, -6.570110321044921875, 7.4572014808654785156,
-6.7263274192810058594, 4.8481650352478027344, -2.0412089824676513672, -0.7006359100341796875,
2.9537565708160400391, -4.0800385475158691406, 4.1845216751098632812, -3.3311812877655029297,
2.1179926395416259766, -0.879302978515625, 0.031759146600961685181, 0.42382788658142089844,
-0.47882103919982910156, 0.35490813851356506348, -0.17496839165687561035, 0.060908168554306030273,
}, /* 44.1k, N=20, amp=27 */
{ -1.6335992813110351562, 2.2615492343902587891, -2.4077029228210449219, 2.6341717243194580078,
-2.1440362930297851562, 1.8153258562088012695, -1.0816224813461303711, 0.70302653312683105469,
-0.15991993248462677002, -0.041549518704414367676, 0.29416576027870178223, -0.2518316805362701416,
0.27766478061676025391, -0.15785403549671173096, 0.10165894031524658203, -0.016833892092108726501,
}, /* 37.8k, N=16 */
{ -0.82901298999786376953, 0.98922657966613769531, -0.59825712442398071289, 1.0028809309005737305,
-0.59938216209411621094, 0.79502451419830322266, -0.42723315954208374023, 0.54492527246475219727,
-0.30792605876922607422, 0.36871799826622009277, -0.18792048096656799316, 0.2261127084493637085,
-0.10573341697454452515, 0.11435490846633911133, -0.038800679147243499756, 0.040842197835445404053,
}, /* 32k, N=16 */
{ -0.065229974687099456787, 0.54981261491775512695, 0.40278548002243041992, 0.31783768534660339355,
0.28201797604560852051, 0.16985194385051727295, 0.15433363616466522217, 0.12507140636444091797,
0.08903945237398147583, 0.064410120248794555664, 0.047146003693342208862, 0.032805237919092178345,
0.028495194390416145325, 0.011695005930960178375, 0.011831838637590408325,
}, /* 22.05k, N=15 */
{ -2.3925774097442626953, 3.4350297451019287109, -3.1853709220886230469, 1.8117271661758422852,
0.20124770700931549072, -1.4759907722473144531, 1.7210904359817504883, -0.97746700048446655273,
0.13790138065814971924, 0.38185903429985046387, -0.27421241998672485352, -0.066584214568138122559,
0.35223302245140075684, -0.37672343850135803223, 0.23964276909828186035, -0.068674825131893157959,
}, /* 48k, N=16, amp=10 */
{ -2.0833916664123535156, 3.0418450832366943359, -3.2047898769378662109, 2.7571926116943359375,
-1.4978630542755126953, 0.3427594602108001709, 0.71733748912811279297, -1.0737057924270629883,
1.0225815773010253906, -0.56649994850158691406, 0.20968692004680633545, 0.065378531813621520996,
-0.10322438180446624756, 0.067442022264003753662, 0.00495197344571352005,
}, /* 44.1k, N=15, amp=9 */
#if 0
{ -3.0259189605712890625, 6.0268716812133789062, -9.195003509521484375, 11.824929237365722656,
-12.767142295837402344, 11.917946815490722656, -9.1739168167114257812, 5.3712320327758789062,
-1.1393624544143676758, -2.4484779834747314453, 4.9719839096069335938, -6.0392003059387207031,
5.9359521865844726562, -4.903278350830078125, 3.5527443885803222656, -2.1909697055816650391,
1.1672389507293701172, -0.4903914332389831543, 0.16519790887832641602, -0.023217858746647834778,
}, /* 44.1k, N=20 */
#endif
};
#define POOLSIZE 97
Shaper::Shaper(int freq, int _nch, int min, int max, int _dtype, int pdf, double noiseamp)
{
int i;
float pool[POOLSIZE] = {0};
nch = _nch;
dtype = _dtype;
for (i = 1;i < 6;i++) if (freq == scoeffreq[i]) break;
/* if ((dtype == 3 || dtype == 4) && i == 6) {
fprintf(stderr,"Warning: ATH based noise shaping for destination frequency %dHz is not available, using triangular dither\n",freq);
}*/
if (dtype == 2 || i == 6) i = 0;
if (dtype == 4 && (i == 1 || i == 2)) i += 5;
shaper_type = i;
shapebuf = (double**)malloc(sizeof(double *) * nch);
shaper_len = scoeflen[shaper_type];
for (i = 0;i < nch;i++)
shapebuf[i] = (double*)calloc(shaper_len, sizeof(double));
shaper_clipmin = min;
shaper_clipmax = max;
randbuf = (REAL*)malloc(sizeof(REAL) * RANDBUFLEN);
for (i = 0;i < POOLSIZE;i++) pool[i] = warandf();
switch (pdf)
{
case DITHER_RECTANGLE: // rectangular
for (i = 0;i < RANDBUFLEN;i++)
{
float r;
int p;
p = warand() % POOLSIZE;
r = pool[p]; pool[p] = warandf();
randbuf[i] = (REAL)(noiseamp * (((double)r) - 0.5));
}
break;
case DITHER_TRIANGLE:
for (i = 0;i < RANDBUFLEN;i++)
{
float r1, r2;
int p;
p = warand() % POOLSIZE;
r1 = pool[p]; pool[p] = warandf();
p = warand() % POOLSIZE;
r2 = pool[p]; pool[p] = warandf();
randbuf[i] = (REAL)(noiseamp * ((((double)r1)) - (((double)r2))));
}
break;
#if 0
case DITHER_GAUSSIAN: // gaussian
for (i = 0;i < RANDBUFLEN;i++)
{
int sw = 0;
double t, u;
double r;
int p;
if (sw == 0)
{
sw = 1;
p = warand() % POOLSIZE;
r = ((double)pool[p]); pool[p] = warandf();
t = sqrt(-2 * log(1 - r));
p = warand() % POOLSIZE;
r = ((double)pool[p]); pool[p] = warandf();
u = 2 * M_PI * r;
randbuf[i] = noiseamp * t * cos(u);
}
else
{
sw = 0;
randbuf[i] = noiseamp * t * sin(u);
}
}
break;
#endif
}
randptr = 0;
// if (dtype == 0 || dtype == 1) return 1;
//return samp[shaper_type];
}
Shaper::~Shaper()
{
int i;
for (i = 0;i < nch;i++) free(shapebuf[i]);
free(shapebuf);
free(randbuf);
}
int Shaper::do_shaping(double s,/*double *peak,*/int ch)
{
double u, h;
int i;
if (dtype == 1)
{
s += randbuf[randptr++ & (RANDBUFLEN-1)];
if (s < shaper_clipmin)
{
//double d = (double)s / shaper_clipmin;
//*peak = *peak < d ? d : *peak;
s = shaper_clipmin;
}
if (s > shaper_clipmax)
{
//double d = (double)s / shaper_clipmax;
//*peak = *peak < d ? d : *peak;
s = shaper_clipmax;
}
return RINT(s);
}
h = 0;
for (i = 0;i < shaper_len;i++)
h += shapercoefs[shaper_type][i] * shapebuf[ch][i];
s += h;
u = s;
s += randbuf[randptr++ & (RANDBUFLEN-1)];
if (s < shaper_clipmin)
{
//double d = (double)s / shaper_clipmin;
//*peak = *peak < d ? d : *peak;
s = shaper_clipmin;
}
if (s > shaper_clipmax)
{
//double d = (double)s / shaper_clipmax;
//*peak = *peak < d ? d : *peak;
s = shaper_clipmax;
}
s = RINT(s);
for (i = shaper_len - 2;i >= 0;i--) shapebuf[ch][i+1] = shapebuf[ch][i];
shapebuf[ch][0] = s - u;
return (int)s;
}

View File

@ -1,30 +0,0 @@
//from SSRC
#ifndef NULLSOFT_VORBIS_SHAPER_H
#define NULLSOFT_VORBIS_SHAPER_H
#include "main.h"
typedef float REAL;
enum
{
DITHER_RECTANGLE=0,
DITHER_TRIANGLE=1,
DITHER_GAUSSIAN=2,
};
class Shaper
{
double **shapebuf;
int shaper_type,shaper_len,shaper_clipmin,shaper_clipmax;
REAL *randbuf;
int randptr;
int dtype;
int nch;
public:
Shaper(int freq,int _nch,int min,int max,int _dtype,int pdf,double noiseamp);
int do_shaping(double s,/*double *peak,*/int ch);
~Shaper();
};
#endif

View File

@ -1,2 +0,0 @@
#include "main.h"

View File

@ -1,491 +0,0 @@
/* This program is licensed under the GNU Library General Public License, version 2,
* a copy of which is included with this program (LICENCE.LGPL).
*
* (c) 2000-2001 Michael Smith <msmith@labyrinth.net.au>
*
*
* Comment editing backend, suitable for use by nice frontend interfaces.
*
* last modified: $Id: vcedit.c,v 1.3 2013/10/22 14:17:11 dromagod Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ogg/ogg.h>
#include <vorbis/codec.h>
#include "vcedit.h"
//#include "i18n.h"
#define CHUNKSIZE 4096
vcedit_state *vcedit_new_state(void)
{
vcedit_state *state = malloc(sizeof(vcedit_state));
memset(state, 0, sizeof(vcedit_state));
return state;
}
char *vcedit_error(vcedit_state *state)
{
return state->lasterror;
}
vorbis_comment *vcedit_comments(vcedit_state *state)
{
return state->vc;
}
static void vcedit_clear_internals(vcedit_state *state)
{
if(state->vc)
{
vorbis_comment_clear(state->vc);
free(state->vc);
}
if(state->os)
{
ogg_stream_clear(state->os);
free(state->os);
}
if(state->oy)
{
ogg_sync_clear(state->oy);
free(state->oy);
}
if(state->vendor)
free(state->vendor);
if(state->mainbuf)
free(state->mainbuf);
if(state->bookbuf)
free(state->bookbuf);
if(state->vi) {
vorbis_info_clear(state->vi);
free(state->vi);
}
memset(state, 0, sizeof(*state));
}
void vcedit_clear(vcedit_state *state)
{
if(state)
{
vcedit_clear_internals(state);
free(state);
}
}
/* Next two functions pulled straight from libvorbis, apart from one change
* - we don't want to overwrite the vendor string.
*/
static void _v_writestring(oggpack_buffer *o,char *s, int len)
{
while(len--)
{
oggpack_write(o,*s++,8);
}
}
static int _commentheader_out(vorbis_comment *vc, char *vendor, ogg_packet *op)
{
oggpack_buffer opb;
oggpack_writeinit(&opb);
/* preamble */
oggpack_write(&opb,0x03,8);
_v_writestring(&opb,"vorbis", 6);
/* vendor */
oggpack_write(&opb,(unsigned long)strlen(vendor),32);
_v_writestring(&opb,vendor, (int)strlen(vendor));
/* comments */
oggpack_write(&opb,vc->comments,32);
if(vc->comments){
int i;
for(i=0;i<vc->comments;i++){
if(vc->user_comments[i]){
oggpack_write(&opb,vc->comment_lengths[i],32);
_v_writestring(&opb,vc->user_comments[i],
vc->comment_lengths[i]);
}else{
oggpack_write(&opb,0,32);
}
}
}
oggpack_write(&opb,1,1);
op->packet = _ogg_malloc(oggpack_bytes(&opb));
memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
op->bytes=oggpack_bytes(&opb);
op->b_o_s=0;
op->e_o_s=0;
op->granulepos=0;
oggpack_writeclear(&opb);
return 0;
}
static int _blocksize(vcedit_state *s, ogg_packet *p)
{
int this = vorbis_packet_blocksize(s->vi, p);
int ret = (this + s->prevW)/4;
if(!s->prevW)
{
s->prevW = this;
return 0;
}
s->prevW = this;
return ret;
}
static int _fetch_next_packet(vcedit_state *s, ogg_packet *p, ogg_page *page)
{
int result = ogg_stream_packetout(s->os, p);
if(result > 0)
return 1;
else
{
if(s->eosin)
return 0;
while(ogg_sync_pageout(s->oy, page) <= 0)
{
char *buffer = ogg_sync_buffer(s->oy, CHUNKSIZE);
int bytes = (int)s->read(buffer,1, CHUNKSIZE, s->in);
ogg_sync_wrote(s->oy, bytes);
if(bytes == 0)
return 0;
}
if(ogg_page_eos(page))
s->eosin = 1;
else if(ogg_page_serialno(page) != s->serial)
{
s->eosin = 1;
s->extrapage = 1;
return 0;
}
ogg_stream_pagein(s->os, page);
return _fetch_next_packet(s, p, page);
}
}
int vcedit_open(vcedit_state *state, FILE *in)
{
return vcedit_open_callbacks(state, (void *)in,
(vcedit_read_func)fread, (vcedit_write_func)fwrite);
}
int vcedit_open_callbacks(vcedit_state *state, void *in,
vcedit_read_func read_func, vcedit_write_func write_func)
{
char *buffer;
int bytes,i;
ogg_packet *header;
ogg_packet header_main;
ogg_packet header_comments;
ogg_packet header_codebooks;
ogg_page og;
state->in = in;
state->read = read_func;
state->write = write_func;
state->oy = malloc(sizeof(ogg_sync_state));
ogg_sync_init(state->oy);
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
bytes = (int)state->read(buffer, 1, CHUNKSIZE, state->in);
ogg_sync_wrote(state->oy, bytes);
if(ogg_sync_pageout(state->oy, &og) != 1)
{
if(bytes<CHUNKSIZE)
state->lasterror = "Input truncated or empty.";
else
state->lasterror = "Input is not an Ogg bitstream.";
goto err;
}
state->serial = ogg_page_serialno(&og);
state->os = malloc(sizeof(ogg_stream_state));
ogg_stream_init(state->os, state->serial);
state->vi = malloc(sizeof(vorbis_info));
vorbis_info_init(state->vi);
state->vc = malloc(sizeof(vorbis_comment));
vorbis_comment_init(state->vc);
if(ogg_stream_pagein(state->os, &og) < 0)
{
state->lasterror = "Error reading first page of Ogg bitstream.";
goto err;
}
if(ogg_stream_packetout(state->os, &header_main) != 1)
{
state->lasterror = "Error reading initial header packet.";
goto err;
}
if(vorbis_synthesis_headerin(state->vi, state->vc, &header_main) < 0)
{
state->lasterror = "Ogg bitstream does not contain vorbis data.";
goto err;
}
state->mainlen = header_main.bytes;
state->mainbuf = malloc(state->mainlen);
memcpy(state->mainbuf, header_main.packet, header_main.bytes);
i = 0;
header = &header_comments;
while(i<2) {
while(i<2) {
int result = ogg_sync_pageout(state->oy, &og);
if(result == 0) break; /* Too little data so far */
else if(result == 1)
{
ogg_stream_pagein(state->os, &og);
while(i<2)
{
result = ogg_stream_packetout(state->os, header);
if(result == 0) break;
if(result == -1)
{
state->lasterror = "Corrupt secondary header.";
goto err;
}
vorbis_synthesis_headerin(state->vi, state->vc, header);
if(i==1)
{
state->booklen = header->bytes;
state->bookbuf = malloc(state->booklen);
memcpy(state->bookbuf, header->packet,
header->bytes);
}
i++;
header = &header_codebooks;
}
}
}
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
bytes = (int)state->read(buffer, 1, CHUNKSIZE, state->in);
if(bytes == 0 && i < 2)
{
state->lasterror = "EOF before end of vorbis headers.";
goto err;
}
ogg_sync_wrote(state->oy, bytes);
}
/* Copy the vendor tag */
bytes = (int)strlen(state->vc->vendor);
state->vendor = malloc(bytes +1);
strncpy(state->vendor, state->vc->vendor, bytes);
/* Headers are done! */
return 0;
err:
vcedit_clear_internals(state);
return -1;
}
int vcedit_write(vcedit_state *state, void *out)
{
ogg_stream_state streamout;
ogg_packet header_main;
ogg_packet header_comments;
ogg_packet header_codebooks;
ogg_page ogout, ogin;
ogg_packet op;
ogg_int64_t granpos = 0;
int result;
char *buffer;
int bytes;
int needflush=0, needout=0;
state->eosin = 0;
state->extrapage = 0;
header_main.bytes = state->mainlen;
header_main.packet = state->mainbuf;
header_main.b_o_s = 1;
header_main.e_o_s = 0;
header_main.granulepos = 0;
header_codebooks.bytes = state->booklen;
header_codebooks.packet = state->bookbuf;
header_codebooks.b_o_s = 0;
header_codebooks.e_o_s = 0;
header_codebooks.granulepos = 0;
ogg_stream_init(&streamout, state->serial);
_commentheader_out(state->vc, state->vendor, &header_comments);
ogg_stream_packetin(&streamout, &header_main);
ogg_stream_packetin(&streamout, &header_comments);
ogg_stream_packetin(&streamout, &header_codebooks);
while((result = ogg_stream_flush(&streamout, &ogout)))
{
if(state->write(ogout.header,1,ogout.header_len, out) !=
(size_t) ogout.header_len)
goto cleanup;
if(state->write(ogout.body,1,ogout.body_len, out) !=
(size_t) ogout.body_len)
goto cleanup;
}
while(_fetch_next_packet(state, &op, &ogin))
{
int size;
size = _blocksize(state, &op);
granpos += size;
if(needflush)
{
if(ogg_stream_flush(&streamout, &ogout))
{
if(state->write(ogout.header,1,ogout.header_len,
out) != (size_t) ogout.header_len)
goto cleanup;
if(state->write(ogout.body,1,ogout.body_len,
out) != (size_t) ogout.body_len)
goto cleanup;
}
}
else if(needout)
{
if(ogg_stream_pageout(&streamout, &ogout))
{
if(state->write(ogout.header,1,ogout.header_len,
out) != (size_t) ogout.header_len)
goto cleanup;
if(state->write(ogout.body,1,ogout.body_len,
out) != (size_t) ogout.body_len)
goto cleanup;
}
}
needflush=needout=0;
if(op.granulepos == -1)
{
op.granulepos = granpos;
ogg_stream_packetin(&streamout, &op);
}
else /* granulepos is set, validly. Use it, and force a flush to
account for shortened blocks (vcut) when appropriate */
{
if(granpos > op.granulepos)
{
granpos = op.granulepos;
ogg_stream_packetin(&streamout, &op);
needflush=1;
}
else
{
ogg_stream_packetin(&streamout, &op);
needout=1;
}
}
}
streamout.e_o_s = 1;
while(ogg_stream_flush(&streamout, &ogout))
{
if(state->write(ogout.header,1,ogout.header_len,
out) != (size_t) ogout.header_len)
goto cleanup;
if(state->write(ogout.body,1,ogout.body_len,
out) != (size_t) ogout.body_len)
goto cleanup;
}
if (state->extrapage)
{
if(state->write(ogin.header,1,ogin.header_len,
out) != (size_t) ogin.header_len)
goto cleanup;
if (state->write(ogin.body,1,ogin.body_len, out) !=
(size_t) ogin.body_len)
goto cleanup;
}
state->eosin=0; /* clear it, because not all paths to here do */
while(!state->eosin) /* We reached eos, not eof */
{
/* We copy the rest of the stream (other logical streams)
* through, a page at a time. */
while(1)
{
result = ogg_sync_pageout(state->oy, &ogout);
if(result==0)
break;
if(result<0)
state->lasterror = "Corrupt or missing data, continuing...";
else
{
/* Don't bother going through the rest, we can just
* write the page out now */
if(state->write(ogout.header,1,ogout.header_len,
out) != (size_t) ogout.header_len) {
// fprintf(stderr, "Bumming out\n");
goto cleanup;
}
if(state->write(ogout.body,1,ogout.body_len, out) !=
(size_t) ogout.body_len) {
// fprintf(stderr, "Bumming out 2\n");
goto cleanup;
}
}
}
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
bytes = (int)state->read(buffer,1, CHUNKSIZE, state->in);
ogg_sync_wrote(state->oy, bytes);
if(bytes == 0)
{
state->eosin = 1;
break;
}
}
cleanup:
ogg_stream_clear(&streamout);
ogg_packet_clear(&header_comments);
free(state->mainbuf);
free(state->bookbuf);
state->mainbuf = state->bookbuf = NULL;
if(!state->eosin)
{
state->lasterror =
"Error writing stream to output. "
"Output stream may be corrupted or truncated.";
return -1;
}
return 0;
}

View File

@ -1,62 +0,0 @@
/* This program is licensed under the GNU Library General Public License, version 2,
* a copy of which is included with this program (with filename LICENSE.LGPL).
*
* (c) 2000-2001 Michael Smith <msmith@labyrinth.net.au>
*
* VCEdit header.
*
* last modified: $ID:$
*/
#ifndef __VCEDIT_H
#define __VCEDIT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <ogg/ogg.h>
#include <vorbis/codec.h>
typedef size_t (*vcedit_read_func)(void *, size_t, size_t, void *);
typedef size_t (*vcedit_write_func)(const void *, size_t, size_t, void *);
typedef struct {
ogg_sync_state *oy;
ogg_stream_state *os;
vorbis_comment *vc;
vorbis_info *vi;
vcedit_read_func read;
vcedit_write_func write;
void *in;
long serial;
unsigned char *mainbuf;
unsigned char *bookbuf;
int mainlen;
int booklen;
char *lasterror;
char *vendor;
int prevW;
int extrapage;
int eosin;
} vcedit_state;
extern vcedit_state * vcedit_new_state(void);
extern void vcedit_clear(vcedit_state *state);
extern vorbis_comment * vcedit_comments(vcedit_state *state);
extern int vcedit_open(vcedit_state *state, FILE *in);
extern int vcedit_open_callbacks(vcedit_state *state, void *in,
vcedit_read_func read_func, vcedit_write_func write_func);
extern int vcedit_write(vcedit_state *state, void *out);
extern char * vcedit_error(vcedit_state *state);
#ifdef __cplusplus
}
#endif
#endif /* __VCEDIT_H */

View File

@ -1,39 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,79,0,0
PRODUCTVERSION WINAMP_PRODUCTVER
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Winamp SA"
VALUE "FileDescription", "Winamp Input Plug-in"
VALUE "FileVersion", "1,79,0,0"
VALUE "InternalName", "Nullsoft Vorbis Decoder"
VALUE "LegalCopyright", "Copyright © 2001-2023 Winamp SA"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "in_vorbis.dll"
VALUE "ProductName", "Winamp"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +0,0 @@
#include "main.h"
#include "api__in_vorbis.h"

View File

@ -1,114 +0,0 @@
libdiscid ChangeLog:
--------------------
libdiscid-0.6.2:
- ISRC and MCN support on BSD
- LIB-60: fix make check for default device on generic/unknown platform
- make Doxygen output reproducible (no timestamps)
- remove newline for Linux device "1" from proc
libdiscid-0.6.1:
- LIB-59: windows: fix bug preventing ISRC reads
libdiscid-0.6.0:
- LIB-41: add discid_get_troc_string() for fuzzy toc lookup
- LIB-54: add libmusicbrainz example with fuzzy toc lookup
- LIB-43: windows: the default drive is the first cd drive letter
- LIB-45: Linux/BSD/Solaris: try several possible default device names
- LIB-28: Mac: allow drive numbers as devices, default now "1"
- LIB-55, LIB-56: allow drive numbers for Windows and Linux
- LIB-53: discid_get_submission_url() returns the new NGS url
currently no functional change, the old url was redirected
- LIB-52: more validation for parameters of discid_put()
- LIB-48: assert successful read/put when API is used
- the discisrc example prints the name of the device used
libdiscid-0.5.2:
- LIB-51: fix ISRC reading on Mac OS X again
- LIB-50: fix segfault in mb_disc_load_toc on Solaris
- LIB-26: add a better test suite, including valgrind memcheck target
- print time information in the discid example
libdiscid-0.5.1:
- LIB-40: discid_get_webservice_url() (web service version 1) is deprecated
please use libmusicbrainz to gather metadata by disc ID
- LIB-7: rewrote data track handling, releases with multiple data tracks
This also fixes LIB-18 (no ID for DVDs) and LIB-9 (PS/PS2 CDs)
- LIB-44: fix invalid disc IDs on first read of multi-session discs
- LIB-37: Autotools optimization (non-recursive build etc.)
- LIB-42: remove Windows 9x platform code
- renamed openbsd platform code to netbsd, still used by both.
libdiscid-0.5.0:
- LIB-29: add read_sparse() for faster reading again
- LIB-35: add HAVE_SPARSE_READ and VERSION_* defines
- LIB-36: hide internal symbols on Linux/Unix
- LIB-34: distmac and distwin32 cmake targets
libdiscid-0.4.1:
- fix distribution: include disc_generic.c in Autotools dist
libdiscid-0.4.0:
- LIB-23: add has_feature() and get_feature_list() to API (platform check)
- add get_version_string() to API
- CMake : add FreeBSD, NetBSD, OpenBSD -> all platforms supported
- LIB-24: support generic platform (discid_put() only)
- Win32 : Added versioninfo resource to DLL
- LIB-32: change libtool from -version-info to -version-name
- LIB-27: fix (k)FreeBSD includes
- fix lots of compiler warnings
libdiscid-0.3.2:
- fix distribution so it works for autotools AND cmake
libdiscid-0.3.1:
- ISRC and MCN support on Linux
- Autotools: fix Windows, remove unneeded libs on SunOS
- CMake: add Cygwin, add SunOS, fix Mac OS X
- updated docs, created INSTALL file
libdiscid-0.3.0:
- Fixed reading of 99 track CDs on Mac OS X.
- Added API for reading ISRCs and MCNs (implemented on Windows and Mac OS X).
- Added Solaris, OpenBSD and kFreeBSD support.
libdiscid-0.2.2:
- Set libtool version number to 2:1:2 because it is backwards compatible
with versions 0.1.x. Thanks to Luks for spotting this.
libdiscid-0.2.1:
- Added code for automatic CD drive detection on darwin (Rob).
libdiscid-0.2.0:
- Use accurate TOC reading method for multi-session CDs on
Windows NT/2000/XP (Lukas).
- Replace custom MSVC makefile with CMake build system (Lukas).
- Added support for FreeBSD (Patrick Hurrelmann).
- Addded the discid_get_webservice_url() function (Rob).
libdiscid-0.1.1:
- Use generic 'cdaudio' device name on windows (Lukas).
libdiscid-0.1.0:
- Initial public release.

View File

@ -1,30 +0,0 @@
A Library for creating MusicBrainz DiscIDs
------------------------------------------
libdiscid is a C library for creating MusicBrainz DiscIDs from audio CDs.
It reads a CD's table of contents (TOC) and generates an identifier which
can be used to lookup the CD at MusicBrainz (http://musicbrainz.org).
Additionally, it provides a submission URL for adding the DiscID to the
database.
The library also provides FreeDB disc IDs, and MCN + ISRCs, if available.
The interface of this library is new, but the DiscID algorithm and the
operating system dependent CD-ROM/DVD-ROM access code have been ported
from libmusicbrainz version 2.
Please report all bugs you find via the MusicBrainz bug tracker.
Don't forget to state which OS and what version you are using:
http://tickets.musicbrainz.org/browse/LIB
Questions about this package may be posted to the MusicBrainz
development mailing list (mb-devel):
http://musicbrainz.org/doc/Communication/Mailing_Lists
More information can be found at the package's official homepage:
http://musicbrainz.org/doc/libdiscid

View File

@ -1,486 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2013 Johannes Dewender
Copyright (C) 2006-2010 Lukas Lalinsky
Copyright (C) 2006 Matthias Friedrich
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------- */
#ifndef MUSICBRAINZ_DISC_ID_H
#define MUSICBRAINZ_DISC_ID_H
#if (defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__))
# ifdef libdiscid_EXPORTS
# define LIBDISCID_API __declspec(dllexport)
# else
# define LIBDISCID_API __declspec(dllimport)
# endif
# define LIBDISCID_INTERNAL
#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
# define LIBDISCID_API
# define LIBDISCID_INTERNAL __attribute__((visibility("hidden")))
#elif defined(__SUNPRO_C)
# define LIBDISCID_API __global
# define LIBDISCID_INTERNAL __hidden
#else
# define LIBDISCID_API
# define LIBDISCID_INTERNAL
#endif
#if (defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__))
#define LIBDISCID_DEPRECATED __declspec(deprecated)
#elif (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) || defined(__clang__)
#define LIBDISCID_DEPRECATED __attribute__((deprecated))
#else
#define LIBDISCID_DEPRECATED
#endif
#define DISCID_VERSION_MAJOR @libdiscid_MAJOR@
#define DISCID_VERSION_MINOR @libdiscid_MINOR@
#define DISCID_VERSION_PATCH @libdiscid_PATCH@
#define DISCID_VERSION_NUM @libdiscid_VERSION_NUM@
#ifdef __cplusplus
extern "C" {
#endif
/*!
* \mainpage libdiscid
* \section intro Introduction
*
* Libdiscid is a C library for calculating DiscIDs
* (<a href="http://musicbrainz.org/doc/Disc ID">MusicBrainz</a>
* and <a href="http://freedb.org">freedb</a>)
* for Audio CDs.
* Additionally the library can extract the MCN/UPC/EAN and the
* <a href="http://musicbrainz.org/doc/ISRC">ISRCs</a> from disc.
*
* The idea is to have an easy to use library without any dependencies
* that can be used from scripting languages.
*
* The API is documented in discid.h.
*
* \section examples Examples
*
* This is an example of the most basic usage:
*
* \code
*
* DiscId *disc = discid_new();
*
* if ( discid_read_sparse(disc, "/dev/cdrom", 0) == 0 ) {
* fprintf(stderr, "Error: %s\n", discid_get_error_msg(disc));
* return 1;
* }
*
* printf("DiscID : %s\n", discid_get_id(disc));
* printf("Submit via : %s\n", discid_get_submission_url(disc));
*
* discid_free(disc);
*
* \endcode
*
* \section Building
*
* libdiscid provides a pkg-config script that returns the necessary compiler and linker flags, as well as the
* version number. To build a small sample program one would use:
*
* @par
* <tt>gcc libdiscid-test.c \`pkg-config libdiscid --cflags --libs\` -o libdiscid-test</tt>
*
* \section Contact
*
* - <a href="http://lists.musicbrainz.org/mailman/listinfo/musicbrainz-devel">MusicBrainz Development Mailing List</a>
* - <a href="http://tickets.musicbrainz.org/browse/LIB">MusicBrainz Bug Tracker</a>
* - <a href="http://musicbrainz.org/doc/libdiscid">MusicBrainz Documentation</a>
* - <a href="https://github.com/metabrainz/libdiscid">Github Repository</a>
*
*/
/**
* A transparent handle for an Audio CD.
*
* This is returned by discid_new() and has to be passed as the first
* parameter to all discid_*() functions.
*/
typedef void *DiscId;
/**
* Return a handle for a new DiscId object.
*
* If no memory could be allocated, NULL is returned. Don't use the created
* DiscId object before calling discid_read() or discid_put().
*
* @return a DiscId object, or NULL.
*/
LIBDISCID_API DiscId *discid_new();
/**
* Release the memory allocated for the DiscId object.
*
* @param d a DiscId object created by discid_new()
*/
LIBDISCID_API void discid_free(DiscId *d);
/**
* Read all supported features of the disc in the given CD-ROM/DVD-ROM drive.
*
* This function reads the disc in the drive specified by the given device
* identifier. If the device is NULL, the default drive, as returned by
* discid_get_default_device() is used.
*
* If you do not require all features provided by libdiscid, such as MCN
* or ISRC reading, you should consider using discid_read_sparse() instead
* of discid_read() for performance reasons.
*
* On error, this function returns false and sets the error message which you
* can access using discid_get_error_msg(). In this case, the other functions
* won't return meaningful values and should not be used.
*
* This function may be used multiple times with the same DiscId object.
*
* @param d a DiscId object created by discid_new()
* @param device an operating system dependent device identifier, or NULL
* @return true if successful, or false on error.
*/
LIBDISCID_API int discid_read(DiscId *d, const char *device);
/**
* Read the disc in the given CD-ROM/DVD-ROM drive
* extracting only the TOC and additionally specified features.
*
* This function will always read the TOC, but additional features
* like ::DISCID_FEATURE_MCN and ::DISCID_FEATURE_ISRC can be set
* using the features parameter.
* Multiple features can be set using bitwise OR.
*
* If you only want to generate a disc ID, you only need the TOC,
* so set features to 0:
* \code
* discid_read_sparse(disc, device, 0)
* \endcode
* This is a bit more verbose, but equivalent since ::DISCID_FEATURE_READ
* is always implied:
* \code
* discid_read_sparse(disc, device, DISCID_FEATURE_READ)
* \endcode
*
* If you want to read all features available, you can use discid_read().
*
* On error, this function returns false and sets the error message which you
* can access using discid_get_error_msg(). In this case, the other functions
* won't return meaningful values and should not be used.
*
* This function may be used multiple times with the same DiscId object.
*
* \since libdiscid 0.5.0
*
* @param d a DiscId object created by discid_new()
* @param device an operating system dependent device identifier, or NULL
* @param features a list of bit flags from the enum ::discid_feature
* @return true if successful, or false on error.
*/
LIBDISCID_API int discid_read_sparse(DiscId *d, const char *device,
unsigned int features);
#define DISCID_HAVE_SPARSE_READ
/**
* Provides the TOC of a known CD.
*
* This function may be used if the TOC has been read earlier and you
* want to calculate the disc ID afterwards, without accessing the disc
* drive. It replaces the discid_read function in this case.
*
* On error, this function returns false and sets the error message which you
* can access using discid_get_error_msg(). In this case, the other functions
* won't return meaningful values and should not be used.
*
* The offsets parameter points to an array which contains the track offsets
* for each track. The first element, offsets[0], is the leadout track. It
* must contain the total number of sectors on the disc.
*
* For discs with additional data tracks, the trailing data tracks
* should be ignored. offset[0] should then be the last sector of the last
* audio track.
* Make sure the length of the last audio track as returned by libdiscid
* after a put is the same as the length of your last audio track.
* Depending on your tools you might need to substract 11400 (2:32 min.).
* See also:
* <a href="http://musicbrainz.org/doc/Disc_ID_Calculation">Disc ID Calculation</a>
*
*
* @param d a DiscID object created by discid_new()
* @param first the number of the first audio track on disc (usually one)
* @param last the number of the last audio track on the disc
* @param offsets a pointer to an array of 100 track offsets
* @return true if the given data was valid, and false on error
*/
LIBDISCID_API int discid_put(DiscId *d, int first, int last, int *offsets);
/**
* Return a human-readable error message.
*
* This function may only be used if discid_read() failed. The returned
* error message is only valid as long as the DiscId object exists.
*
* @param d a DiscId object created by discid_new()
* @return a string describing the error that occurred
*/
LIBDISCID_API char *discid_get_error_msg(DiscId *d);
/**
* Return a MusicBrainz DiscID.
*
* The returned string is only valid as long as the DiscId object exists.
*
* @param d a DiscId object created by discid_new()
* @return a string containing a MusicBrainz DiscID
*/
LIBDISCID_API char *discid_get_id(DiscId *d);
/**
* Return a FreeDB DiscID.
*
* The returned string is only valid as long as the DiscId object exists.
*
* @param d a DiscId object created by discid_new()
* @return a string containing a FreeDB DiscID
*/
LIBDISCID_API char *discid_get_freedb_id(DiscId *d);
/**
* Return a string representing CD Table Of Contents (TOC).
*
* The string has following values separated by space:
* first track number
* last track number
* total length in sectors
* offset of 1st track
* offset of 2nd track
* ...
*
* Example:
* 1 7 164900 150 22460 50197 80614 100828 133318 144712
*
* The returned string is only valid as long as the DiscId object exists.
*
* @param d a DiscId object created by discid_new()
* @return a string containing TOC information
*/
LIBDISCID_API char *discid_get_toc_string(DiscId *d);
/**
* Return an URL for submitting the DiscID to MusicBrainz.
*
* The URL leads to an interactive disc submission wizard that guides the
* user through the process of associating this disc's DiscID with a
* release in the MusicBrainz database.
*
* The returned string is only valid as long as the DiscId object exists.
*
* @param d a DiscId object created by discid_new()
* @return a string containing an URL
*/
LIBDISCID_API char *discid_get_submission_url(DiscId *d);
/**
* Return an URL for retrieving CD information from MusicBrainz' web service
*
* The URL provides the CD information in XML.
* See http://musicbrainz.org/development/mmd for details.
*
* The returned string is only valid as long as the DiscId object exists.
*
* @param d a DiscId object created by discid_new()
* @return a string containing an URL
*
* @deprecated This function is deprecated. Please use libmusicbrainz instead
* since this function returns an URL referring the deprecated webservice.
*/
LIBDISCID_API LIBDISCID_DEPRECATED char *discid_get_webservice_url(DiscId *d);
/**
* Return the name of the default disc drive for this machine.
* This isn't constant, but possibly depends on the drives currently
* attached, depending on the platform.
* For this reason you should call this once and save it
* when you want to make sure to use the same drive for
* multiple operations.
*
* The returned string is thread local and owned by libdiscid internally.
*
* @return a string containing an operating system dependent device identifier
*/
LIBDISCID_API char *discid_get_default_device(void);
/**
* Return the number of the first track on this disc.
*
* @param d a DiscId object created by discid_new()
* @return the number of the first track
*/
LIBDISCID_API int discid_get_first_track_num(DiscId *d);
/**
* Return the number of the last audio track on this disc.
*
* @param d a DiscId object created by discid_new()
* @return the number of the last track
*/
LIBDISCID_API int discid_get_last_track_num(DiscId *d);
/**
* Return the length of the disc in sectors.
*
* @param d a DiscId object created by discid_new()
* @return the length of the disc in sectors
*/
LIBDISCID_API int discid_get_sectors(DiscId *d);
/**
* Return the sector offset of a track.
*
* Only track numbers between (and including) discid_get_first_track_num()
* and discid_get_last_track_num() may be used.
*
* @param d a DiscId object created by discid_new()
* @param track_num the number of a track
* @return sector offset of the specified track
*/
LIBDISCID_API int discid_get_track_offset(DiscId *d, int track_num);
/**
* Return the length of a track in sectors.
*
* Only track numbers between (and including) discid_get_first_track_num()
* and discid_get_last_track_num() may be used.
*
* @param d a DiscId object created by discid_new()
* @param track_num the number of a track
* @return length of the specified track
*/
LIBDISCID_API int discid_get_track_length(DiscId *d, int track_num);
/**
* Return the Media Catalogue Number (MCN) for the disc.
*
* This is essentially an EAN (= UPC with 0 prefix).
*
* \since libdiscid 0.3.0
*
* @param d a DiscId object created by discid_new()
* @return a string containing an Media Catalogue Number of the disk
*/
LIBDISCID_API char* discid_get_mcn(DiscId *d);
/**
* Return the ISRC for a track.
*
* Only track numbers between (and including) discid_get_first_track_num()
* and discid_get_last_track_num() may be used.
*
* \since libdiscid 0.3.0
*
* @param d a DiscId object created by discid_new()
* @param track_num the number of a track
* @return a string containing an ISRC for the specified track
*/
LIBDISCID_API char* discid_get_track_isrc(DiscId *d, int track_num);
/**
* PLATFORM-DEPENDENT FEATURES
*
* The platform dependent features are currently:
* - "read" read TOC from disc
* - "mcn" read MCN from disc
* - "isrc" read ISRC from disc
*
* A table in the
* <a href="http://musicbrainz.org/doc/libdiscid">MusicBrainz Documentation</a>
* specifies which features are available on which platform in what version.
*
* In the code you can use discid_get_feature_list() or discid_has_feature()
* below to get the features for your platform in this version.
*/
enum discid_feature {
DISCID_FEATURE_READ = 1 << 0,
DISCID_FEATURE_MCN = 1 << 1,
DISCID_FEATURE_ISRC = 1 << 2,
};
/**
* Check if a certain feature is implemented on the current platform.
*
* This only works for single features, not bit masks with multiple features.
*
* \since libdiscid 0.4.0
*
* @param feature as enum ::discid_feature
* @return 1 if the feature is implemented and 0 if not.
*/
LIBDISCID_API int discid_has_feature(enum discid_feature feature);
#define DISCID_FEATURE_STR_READ "read"
#define DISCID_FEATURE_STR_MCN "mcn"
#define DISCID_FEATURE_STR_ISRC "isrc"
#define DISCID_FEATURE_LENGTH 32
/**
* Return a list of features supported by the current platform.
* The array of length ::DISCID_FEATURE_LENGTH should be allocated by the user.
* After the call each element of the array is either NULL
* or a pointer to a static string.
*
* \since libdiscid 0.4.0
*
* @param[out] features a static string array of length ::DISCID_FEATURE_LENGTH
*/
LIBDISCID_API void discid_get_feature_list(
char *features[DISCID_FEATURE_LENGTH]);
/**
* Return the full version string of this library, including the name.
* This can be used for debug output.
* Don't use this to test for features, see discid_has_feature().
*
* \since libdiscid 0.4.0
*
* @return a string containing the version of libdiscid.
*/
LIBDISCID_API char *discid_get_version_string(void);
#ifdef __cplusplus
}
#endif
#endif /* MUSICBRAINZ_DISC_ID_H */

View File

@ -1,139 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2006 Matthias Friedrich
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$
--------------------------------------------------------------------------- */
/*
* For internal use only. This header file is not installed.
*/
#ifndef MUSICBRAINZ_DISC_ID_PRIVATE_H
#define MUSICBRAINZ_DISC_ID_PRIVATE_H
#include "discid/discid.h"
/* Length of toc string, "xxx+xxx" + 100 tracks 7 bytes each ("+xxxxxx")
* The highest possible offset is 90 minutes * 60 seconds/minute * 75 frames/second = 405000.
* That is 6 digits plus one plus sign = 7 characters per track.
* So 3 + 3 (first and last) + 100*7 (disc length plus 99 tracks) = 706
*/
#define MB_TOC_STRING_LENGTH (3 + 3 + 100*7)
/* Length of a MusicBrainz DiscID in bytes (without a trailing '\0'-byte). */
#define MB_DISC_ID_LENGTH 32
/* Length of a FreeDB DiscID in bytes (without a trailing '\0'-byte). */
#define FREEDB_DISC_ID_LENGTH 8
/* The maximum permitted length for an error message (without the '\0'-byte). */
#define MB_ERROR_MSG_LENGTH 255
/* Length of url prefixes */
#define MB_URL_PREFIX_LENGTH 300
/* Maximum length of any url (including query string) */
#define MB_MAX_URL_LENGTH (MB_URL_PREFIX_LENGTH + MB_DISC_ID_LENGTH + MB_TOC_STRING_LENGTH)
/* The URL that can be used for submitting DiscIDs (no parameters yet) */
#define MB_SUBMISSION_URL "http://musicbrainz.org/cdtoc/attach"
/* The URL that can be used for retrieving XML for a CD */
#define MB_WEBSERVICE_URL "http://musicbrainz.org/ws/1/release"
/* Maximum length of a Media Catalogue Number string */
#define MCN_STR_LENGTH 13
/* Maximum length of a ISRC code string */
#define ISRC_STR_LENGTH 12
/* Maximum disc length in frames/sectors
* This is already not according to spec, but many players might still work
* Spec is 79:59.75 = 360000 + lead-in + lead-out */
#define MAX_DISC_LENGTH (90 * 60 * 75)
/*
* This data structure represents an audio disc.
*
* We use fixed length strings here because that way the user doesn't have to
* check for memory exhaustion conditions. As soon as the mb_disc object has
* been created, all calls returning strings will be successful.
*/
typedef struct {
int first_track_num;
int last_track_num;
int track_offsets[100];
char id[MB_DISC_ID_LENGTH+1];
char freedb_id[FREEDB_DISC_ID_LENGTH+1];
char submission_url[MB_MAX_URL_LENGTH+1];
char webservice_url[MB_MAX_URL_LENGTH+1];
char toc_string[MB_TOC_STRING_LENGTH+1];
char error_msg[MB_ERROR_MSG_LENGTH+1];
char isrc[100][ISRC_STR_LENGTH+1];
char mcn[MCN_STR_LENGTH+1];
int success;
} mb_disc_private;
typedef struct {
int control;
int address;
} mb_disc_toc_track;
typedef struct {
int first_track_num;
int last_track_num;
mb_disc_toc_track tracks[100];
} mb_disc_toc;
/*
* This function has to be implemented once per operating system.
*
* The caller guarantees that both the disc and device parameters are
* not NULL.
*
* Implementors have to set mb_disc_private's first_track_num, last_track_num,
* and track_offsets attributes. If there is an error, the error_msg attribute
* has to be set to a human-readable error message.
*
* On error, 0 is returned. On success, 1 is returned.
*/
LIBDISCID_INTERNAL int mb_disc_read_unportable(mb_disc_private *disc, const char *device, unsigned int features);
/*
* This should return the name of the default/preferred CDROM/DVD device
* on this operating system. It has to be in a format usable for the second
* parameter of mb_disc_read_unportable().
*/
LIBDISCID_INTERNAL char *mb_disc_get_default_device_unportable(void);
/*
* This should return 1 if the feature is supported by the platform
* and 0 if not.
*/
LIBDISCID_INTERNAL int mb_disc_has_feature_unportable(enum discid_feature feature);
/*
* Load data to the mb_disc_private structure based on mb_disc_toc.
*
* On error, 0 is returned. On success, 1 is returned.
*/
LIBDISCID_INTERNAL int mb_disc_load_toc(mb_disc_private *disc, mb_disc_toc *toc);
#endif /* MUSICBRAINZ_DISC_ID_PRIVATE_H */

View File

@ -1,110 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2000 Robert Kaye
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$
----------------------------------------------------------------------------*/
/*
* Program: RFC-822 routines (originally from SMTP)
*
* Author: Mark Crispin
* Networks and Distributed Computing
* Computing & Communications
* University of Washington
* Administration Building, AG-44
* Seattle, WA 98195
* Internet: MRC@CAC.Washington.EDU
*
* Date: 27 July 1988
* Last Edited: 10 September 1998
*
* Sponsorship: The original version of this work was developed in the
* Symbolic Systems Resources Group of the Knowledge Systems
* Laboratory at Stanford University in 1987-88, and was funded
* by the Biomedical Research Technology Program of the National
* Institutes of Health under grant number RR-00785.
*
* Original version Copyright 1988 by The Leland Stanford Junior University
* Copyright 1998 by the University of Washington
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notices appear in all copies and that both the
* above copyright notices and this permission notice appear in supporting
* documentation, and that the name of the University of Washington or The
* Leland Stanford Junior University not be used in advertising or publicity
* pertaining to distribution of the software without specific, written prior
* permission. This software is made available "as is", and
* THE UNIVERSITY OF WASHINGTON AND THE LELAND STANFORD JUNIOR UNIVERSITY
* DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE,
* INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE UNIVERSITY OF
* WASHINGTON OR THE LELAND STANFORD JUNIOR UNIVERSITY BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include <ctype.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include "base64.h"
/* NOTE: This is not true RFC822 anymore. The use of the characters
'/', '+', and '=' is no bueno when the ID will be used as part of a URL.
'_', '.', and '-' have been used instead
*/
/* Convert binary contents to BASE64
* Accepts: source
* length of source
* pointer to return destination length
* Returns: destination as BASE64
*/
unsigned char *rfc822_binary (void *src,unsigned long srcl,unsigned long *len)
{
unsigned char *ret,*d;
unsigned char *s = (unsigned char *) src;
char *v = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._";
unsigned long i = ((srcl + 2) / 3) * 4;
*len = i += 2 * ((i / 60) + 1);
d = ret = (unsigned char *) malloc ((size_t) ++i);
for (i = 0; srcl; s += 3) { /* process tuplets */
*d++ = v[s[0] >> 2]; /* byte 1: high 6 bits (1) */
/* byte 2: low 2 bits (1), high 4 bits (2) */
*d++ = v[((s[0] << 4) + (--srcl ? (s[1] >> 4) : 0)) & 0x3f];
/* byte 3: low 4 bits (2), high 2 bits (3) */
*d++ = srcl ? v[((s[1] << 2) + (--srcl ? (s[2] >> 6) : 0)) & 0x3f] : '-';
/* byte 4: low 6 bits (3) */
*d++ = srcl ? v[s[2] & 0x3f] : '-';
if (srcl) srcl--; /* count third character if processed */
if ((++i) == 15) { /* output 60 characters? */
i = 0; /* restart line break count, insert CRLF */
*d++ = '\015'; *d++ = '\012';
}
}
*d = '\0'; /* tie off string */
return ret; /* return the resulting string */
}

View File

@ -1,74 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2000 Robert Kaye
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
$Id$
----------------------------------------------------------------------------*/
/*
* Program: RFC-822 routines (originally from SMTP)
*
* Author: Mark Crispin
* Networks and Distributed Computing
* Computing & Communications
* University of Washington
* Administration Building, AG-44
* Seattle, WA 98195
* Internet: MRC@CAC.Washington.EDU
*
* Date: 27 July 1988
* Last Edited: 10 September 1998
*
* Sponsorship: The original version of this work was developed in the
* Symbolic Systems Resources Group of the Knowledge Systems
* Laboratory at Stanford University in 1987-88, and was funded
* by the Biomedical Research Technology Program of the National
* Institutes of Health under grant number RR-00785.
*
* Original version Copyright 1988 by The Leland Stanford Junior University
* Copyright 1998 by the University of Washington
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notices appear in all copies and that both the
* above copyright notices and this permission notice appear in supporting
* documentation, and that the name of the University of Washington or The
* Leland Stanford Junior University not be used in advertising or publicity
* pertaining to distribution of the software without specific, written prior
* permission. This software is made available "as is", and
* THE UNIVERSITY OF WASHINGTON AND THE LELAND STANFORD JUNIOR UNIVERSITY
* DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE,
* INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE UNIVERSITY OF
* WASHINGTON OR THE LELAND STANFORD JUNIOR UNIVERSITY BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#ifndef BASE64_H
#define BASE64_H
#include "discid/discid.h" /* for LIBDISCID_INTERNAL */
LIBDISCID_INTERNAL unsigned char *rfc822_binary (void *src,unsigned long srcl,unsigned long *len);
#endif

View File

@ -1,508 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2006 Matthias Friedrich
Copyright (C) 2000 Robert Kaye
Copyright (C) 1999 Marc E E van Woerkom
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------- */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <string.h>
#include <assert.h>
#include <limits.h>
#include "sha1.h"
#include "base64.h"
#include "discid/discid.h"
#include "discid/discid_private.h"
#define TRACK_NUM_IS_VALID(disc, i) \
( i >= disc->first_track_num && i <= disc->last_track_num )
static void create_disc_id(mb_disc_private *d, char buf[]);
static void create_freedb_disc_id(mb_disc_private *d, char buf[]);
static char *create_toc_string(mb_disc_private *d, char *sep);
static void create_submission_url(mb_disc_private *d, char buf[]);
static void create_webservice_url(mb_disc_private *d, char buf[]);
/****************************************************************************
*
* Implementation of the public interface.
*
****************************************************************************/
DiscId *discid_new() {
/* initializes everything to zero */
return calloc(1, sizeof(mb_disc_private));
}
void discid_free(DiscId *d) {
free(d);
}
char *discid_get_error_msg(DiscId *d) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
return disc->error_msg;
}
char *discid_get_id(DiscId *d) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
if (!disc->success)
return NULL;
if (strlen(disc->id) == 0)
create_disc_id(disc, disc->id);
return disc->id;
}
char *discid_get_freedb_id(DiscId *d) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
if (!disc->success)
return NULL;
if (strlen(disc->freedb_id) == 0)
create_freedb_disc_id(disc, disc->freedb_id);
return disc->freedb_id;
}
char *discid_get_toc_string(DiscId *d) {
mb_disc_private *disc = (mb_disc_private *) d;
assert( disc != NULL );
assert( disc->success );
if ( ! disc->success )
return NULL;
if ( strlen(disc->toc_string) == 0 ) {
char *toc = create_toc_string(disc, " ");
if (toc) {
memcpy(disc->toc_string, toc, strlen(toc) + 1);
free(toc);
}
}
return disc->toc_string;
}
char *discid_get_submission_url(DiscId *d) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
if (!disc->success)
return NULL;
if (strlen(disc->submission_url) == 0)
create_submission_url(disc, disc->submission_url);
return disc->submission_url;
}
char *discid_get_webservice_url(DiscId *d) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
if (!disc->success)
return NULL;
if (strlen(disc->webservice_url) == 0)
create_webservice_url(disc, disc->webservice_url);
return disc->webservice_url;
}
int discid_read(DiscId *d, const char *device) {
return discid_read_sparse(d, device, UINT_MAX);
}
int discid_read_sparse(DiscId *d, const char *device, unsigned int features) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
if (device == NULL)
device = discid_get_default_device();
assert(device != NULL);
/* Necessary, because the disc handle could have been used before. */
memset(disc, 0, sizeof(mb_disc_private));
/* pre-read the TOC to reduce "not-ready" problems
* See LIB-44 (issues with multi-session discs)
*/
if (!mb_disc_read_unportable(disc, device, DISCID_FEATURE_READ)) {
return 0;
}
memset(disc, 0, sizeof(mb_disc_private));
return disc->success = mb_disc_read_unportable(disc, device, features);
}
int discid_put(DiscId *d, int first, int last, int *offsets) {
int i, disc_length;
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
/* Necessary, because the disc handle could have been used before. */
memset(disc, 0, sizeof(mb_disc_private));
/* extensive checking of given parameters */
if (first > last || first < 1
|| first > 99 || last < 1 || last > 99) {
sprintf(disc->error_msg, "Illegal track limits");
return 0;
}
if (offsets == NULL) {
sprintf(disc->error_msg, "No offsets given");
return 0;
}
disc_length = offsets[0];
if (disc_length > MAX_DISC_LENGTH) {
sprintf(disc->error_msg, "Disc too long");
return 0;
}
for (i = 0; i <= last; i++) {
if (offsets[i] > disc_length) {
sprintf(disc->error_msg, "Invalid offset");
return 0;
}
if (i > 1 && offsets[i-1] > offsets[i]) {
sprintf(disc->error_msg, "Invalid order");
return 0;
}
}
disc->first_track_num = first;
disc->last_track_num = last;
memcpy(disc->track_offsets, offsets, sizeof(int) * (last+1));
disc->success = 1;
return 1;
}
char *discid_get_default_device(void) {
return mb_disc_get_default_device_unportable();
}
int discid_get_first_track_num(DiscId *d) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
if (!disc->success)
return -1;
else
return disc->first_track_num;
}
int discid_get_last_track_num(DiscId *d) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
if (!disc->success)
return -1;
else
return disc->last_track_num;
}
int discid_get_sectors(DiscId *d) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
if (!disc->success)
return -1;
else
return disc->track_offsets[0];
}
int discid_get_track_offset(DiscId *d, int i) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
assert(TRACK_NUM_IS_VALID(disc, i));
if (!disc->success || !TRACK_NUM_IS_VALID(disc, i))
return -1;
else
return disc->track_offsets[i];
}
int discid_get_track_length(DiscId *d, int i) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
assert(TRACK_NUM_IS_VALID(disc, i));
if (!disc->success || !TRACK_NUM_IS_VALID(disc, i))
return -1;
else if (i < disc->last_track_num)
return disc->track_offsets[i+1] - disc->track_offsets[i];
else
return disc->track_offsets[0] - disc->track_offsets[i];
}
char *discid_get_mcn(DiscId *d) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
if (!disc->success)
return NULL;
else
return disc->mcn;
}
char* discid_get_track_isrc(DiscId *d, int i) {
mb_disc_private *disc = (mb_disc_private *) d;
assert(disc != NULL);
assert(disc->success);
assert(TRACK_NUM_IS_VALID(disc, i));
if (!disc->success || i == 0 || !TRACK_NUM_IS_VALID(disc, i))
return NULL;
else
return disc->isrc[i];
}
int discid_has_feature(enum discid_feature feature) {
return mb_disc_has_feature_unportable(feature);
}
void discid_get_feature_list(char *features[DISCID_FEATURE_LENGTH]) {
int i;
/* for the code, the parameter is actually only a pointer */
memset(features, 0, sizeof(char *) * DISCID_FEATURE_LENGTH);
i = 0;
if (discid_has_feature(DISCID_FEATURE_READ)) {
features[i++] = DISCID_FEATURE_STR_READ;
}
if (discid_has_feature(DISCID_FEATURE_MCN)) {
features[i++] = DISCID_FEATURE_STR_MCN;
}
if (discid_has_feature(DISCID_FEATURE_ISRC)) {
features[i++] = DISCID_FEATURE_STR_ISRC;
}
return;
}
char *discid_get_version_string(void) {
#ifdef HAVE_CONFIG_H
return PACKAGE_STRING;
#else
return "";
#endif
}
/****************************************************************************
*
* Private utilities, not exported.
*
****************************************************************************/
/*
* Create a DiscID based on the TOC data found in the DiscId object.
* The DiscID is placed in the provided string buffer.
*/
static void create_disc_id(mb_disc_private *d, char buf[]) {
SHA_INFO sha;
unsigned char digest[20], *base64;
unsigned long size;
char tmp[17]; /* for 8 hex digits (16 to avoid trouble) */
int i;
assert(d != NULL);
assert(d->success);
sha_init(&sha);
sprintf(tmp, "%02X", d->first_track_num);
sha_update(&sha, (unsigned char *) tmp, strlen(tmp));
sprintf(tmp, "%02X", d->last_track_num);
sha_update(&sha, (unsigned char *) tmp, strlen(tmp));
for (i = 0; i < 100; i++) {
sprintf(tmp, "%08X", d->track_offsets[i]);
sha_update(&sha, (unsigned char *) tmp, strlen(tmp));
}
sha_final(digest, &sha);
base64 = rfc822_binary(digest, sizeof(digest), &size);
memcpy(buf, base64, size);
buf[size] = '\0';
free(base64);
}
/*
* Create a FreeDB DiscID based on the TOC data found in the DiscId object.
* The DiscID is placed in the provided string buffer.
*/
static void create_freedb_disc_id(mb_disc_private *d, char buf[]) {
int i, n, m, t;
assert(d != NULL);
assert(d->success);
n = 0;
for (i = 0; i < d->last_track_num; i++) {
m = d->track_offsets[i + 1] / 75;
while (m > 0) {
n += m % 10;
m /= 10;
}
}
t = d->track_offsets[0] / 75 - d->track_offsets[1] / 75;
sprintf(buf, "%08x", ((n % 0xff) << 24 | t << 8 | d->last_track_num));
}
/*
* Create a string based on the TOC data found in the mb_disc_private
* object. The returned string is allocated, caller has to free() it.
* On failure, it returns NULL.
*
* Format is:
* [1st track num][sep][last track num][sep][length in sectors][sep][1st track offset][sep]...
*/
static char *create_toc_string(mb_disc_private *d, char *sep) {
char tmp[16];
char *toc;
int i, size;
assert( d != NULL );
/* number of tracks */
size = 1 + d->last_track_num - d->first_track_num;
/* first&last track num and total length */
size += 3;
/* number + separator */
size *= (6 + strlen(sep));
/* nul */
size++;
toc = calloc(size, sizeof(char));
if (!toc) return NULL;
sprintf(toc, "%d%s%d%s%d",
d->first_track_num,
sep,
d->last_track_num,
sep,
d->track_offsets[0]);
for (i = d->first_track_num; i <= d->last_track_num; i++) {
sprintf(tmp, "%s%d", sep, d->track_offsets[i]);
strcat(toc, tmp);
}
return toc;
}
/* Append &toc=... to buf, calling create_toc_string() */
static void cat_toc_param(mb_disc_private *d, char *buf) {
char *toc = create_toc_string(d, "+");
if (toc) {
strcat(buf, "&toc=");
strcat(buf, toc);
free(toc);
}
}
/*
* Create a submission URL based on the TOC data found in the mb_disc_private
* object. The URL is placed in the provided string buffer.
*/
static void create_submission_url(mb_disc_private *d, char buf[]) {
char tmp[16];
assert(d != NULL);
assert(d->success);
strcpy(buf, MB_SUBMISSION_URL);
strcat(buf, "?id=");
strcat(buf, discid_get_id((DiscId *) d));
sprintf(tmp, "&tracks=%d", d->last_track_num);
strcat(buf, tmp);
cat_toc_param(d, buf);
}
/*
* Create a web service URL based on the TOC data found in the mb_disc_private
* object. The URL is placed in the provided string buffer.
*/
static void create_webservice_url(mb_disc_private *d, char buf[]) {
assert(d != NULL);
assert(d->success);
strcpy(buf, MB_WEBSERVICE_URL);
strcat(buf, "?type=xml&discid=");
strcat(buf, discid_get_id((DiscId *) d));
cat_toc_param(d, buf);
}
/* EOF */

View File

@ -1,194 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2008 Patrick Hurrelmann
Copyright (C) 2006 Matthias Friedrich
Copyright (C) 2000 Robert Kaye
Copyright (C) 1999 Marc E E van Woerkom
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------- */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/cdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <unistd.h>
#if defined(__FreeBSD__)
#include <netinet/in.h> /* for ntohl() */
#else
#include <util.h> /* for getrawpartition() */
#endif
#include "discid/discid_private.h"
#include "unix.h"
#define MAX_DEV_LEN 15
static int get_device(int n, char* device_name, size_t device_name_length) {
#if !defined(__FreeBSD__) /* /dev/rcdNX, where X is the letter for the raw partition */
snprintf(device_name, device_name_length, "/dev/rcd%d%c", n - 1, 'a' + getrawpartition());
#else /* on FreeBSD it's just /dev/cdN */
snprintf(device_name, device_name_length, "/dev/cd%d", n - 1);
#endif
return mb_disc_unix_exists(device_name);
}
int mb_disc_unix_read_toc_header(int fd, mb_disc_toc *toc) {
struct ioc_toc_header th;
struct cd_toc_entry te[100];
struct ioc_read_toc_entry rte;
int i;
memset(&th, 0, sizeof th);
if (ioctl(fd, CDIOREADTOCHEADER, &th) < 0)
return 0; /* error */
toc->first_track_num = th.starting_track;
toc->last_track_num = th.ending_track;
if (toc->last_track_num == 0)
return 1; /* no entries to read */
/* Read all the TOC entries in one icotl() call */
memset(&te, 0, sizeof te);
memset(&rte, 0, sizeof rte);
rte.address_format = CD_LBA_FORMAT;
rte.data = &te[0];
rte.data_len = sizeof te;
rte.starting_track = toc->first_track_num;
if (ioctl(fd, CDIOREADTOCENTRYS, &rte) < 0)
return 0; /* error */
for (i = toc->first_track_num; i <= toc->last_track_num; ++i) {
assert(te[i - toc->first_track_num].track == i);
#if defined(__FreeBSD__) /* LBA address is in network byte order */
toc->tracks[i].address = ntohl(te[i - toc->first_track_num].addr.lba);
#else
toc->tracks[i].address = te[i - toc->first_track_num].addr.lba;
#endif
toc->tracks[i].control = te[i - toc->first_track_num].control;
}
/* leadout - track number 170 (0xAA) */
assert(te[i - toc->first_track_num].track == 0xAA);
#if defined(__FreeBSD__) /* LBA address is in network byte order */
toc->tracks[0].address = ntohl(te[i - toc->first_track_num].addr.lba);
#else
toc->tracks[0].address = te[i - toc->first_track_num].addr.lba;
#endif
toc->tracks[0].control = te[i - toc->first_track_num].control;
return 1;
}
int mb_disc_unix_read_toc_entry(int fd, int track_num, mb_disc_toc_track *track) {
/* All TOC entries were already read by mb_disc_unix_read_toc_header() */
return 1;
}
void mb_disc_unix_read_mcn(int fd, mb_disc_private *disc) {
struct cd_sub_channel_info sci;
struct ioc_read_subchannel rsc;
memset(&sci, 0, sizeof sci);
memset(&rsc, 0, sizeof rsc);
rsc.address_format = CD_LBA_FORMAT; /* not technically relevant */
rsc.data_format = CD_MEDIA_CATALOG;
rsc.data_len = sizeof sci;
rsc.data = &sci;
if ( ioctl(fd, CDIOCREADSUBCHANNEL, &rsc) < 0 )
perror ("Warning: Unable to read the disc's media catalog number");
else {
if (sci.what.media_catalog.mc_valid)
strncpy( disc->mcn,
(const char *) sci.what.media_catalog.mc_number,
MCN_STR_LENGTH );
else
memset( disc->mcn, 0, MCN_STR_LENGTH );
}
}
void mb_disc_unix_read_isrc(int fd, mb_disc_private *disc, int track_num) {
struct cd_sub_channel_info sci;
struct ioc_read_subchannel rsc;
memset(&sci, 0, sizeof sci);
memset(&rsc, 0, sizeof rsc);
rsc.address_format = CD_LBA_FORMAT; /* not technically relevant */
rsc.data_format = CD_TRACK_INFO;
rsc.track = track_num;
rsc.data_len = sizeof sci;
rsc.data = &sci;
if ( ioctl(fd, CDIOCREADSUBCHANNEL, &rsc) < 0 )
perror ("Warning: Unable to read track info (ISRC)");
else {
if (sci.what.track_info.ti_valid)
strncpy( disc->isrc[track_num],
(const char *) sci.what.track_info.ti_number,
ISRC_STR_LENGTH );
else
memset( disc->isrc[track_num], 0, ISRC_STR_LENGTH );
}
}
int mb_disc_has_feature_unportable(enum discid_feature feature) {
switch(feature) {
case DISCID_FEATURE_READ:
case DISCID_FEATURE_MCN:
case DISCID_FEATURE_ISRC:
return 1;
default:
return 0;
}
}
int mb_disc_read_unportable(mb_disc_private *disc, const char *device,
unsigned int features) {
char device_name[MAX_DEV_LEN] = "";
int device_number;
device_number = (int) strtol(device, NULL, 10);
if (device_number > 0) {
if(!get_device(device_number, device_name, MAX_DEV_LEN)) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"cannot find cd device with the number '%d'",
device_number);
return 0; /* error */
}
device = device_name;
}
return mb_disc_unix_read(disc, device, features);
}
char *mb_disc_get_default_device_unportable(void) {
static char result[MAX_DEV_LEN + 1];
/* No error check here, so we always return the appropriate device for cd0 */
get_device(1, result, sizeof result);
return result;
}
/* EOF */

View File

@ -1,242 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2013 Johannes Dewender
Copyright (C) 2006 Robert Kaye
Copyright (C) 1999 Marc E E van Woerkom
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/IOCDBlockStorageDevice.h>
#include <IOKit/storage/IOCDMediaBSDClient.h>
#include "discid/discid.h"
#include "discid/discid_private.h"
#include "unix.h"
#define MB_DEFAULT_DEVICE "1" /* first disc drive (empty or not) */
#define TOC_BUFFER_LEN 2048
static int find_cd_block_devices(io_iterator_t *device_iterator)
{
mach_port_t master_port;
CFMutableDictionaryRef matching_dictionary;
if (IOMasterPort(MACH_PORT_NULL, &master_port) != KERN_SUCCESS)
return 0;
matching_dictionary = IOServiceMatching(kIOCDBlockStorageDeviceClass);
if (IOServiceGetMatchingServices(master_port, matching_dictionary,
device_iterator) != KERN_SUCCESS)
return 0;
else
return 1;
}
static int get_device_from_entry(io_registry_entry_t entry,
char *device_path, int max_len)
{
int return_value = 0;
size_t dev_path_len;;
CFStringRef cf_device_name;;
*device_path = '\0';
cf_device_name = IORegistryEntrySearchCFProperty(entry,
kIOServicePlane, CFSTR(kIOBSDNameKey),
kCFAllocatorDefault, kIORegistryIterateRecursively);
if (cf_device_name) {
strcpy(device_path, _PATH_DEV);
/* Add "r" before the device name to use the raw disk node
* without the buffering cache. */
strcat(device_path, "r");
dev_path_len = strlen(device_path);
if (CFStringGetCString(cf_device_name,
device_path + dev_path_len,
max_len - dev_path_len - 1,
kCFStringEncodingASCII))
return_value = 1;
CFRelease(cf_device_name);
}
return return_value;
}
static int get_device_from_number(int device_number,
char * buffer, int buffer_len) {
int return_value = 0;
int index = 0;
io_iterator_t device_iterator;
io_object_t device_object = IO_OBJECT_NULL;
if (!find_cd_block_devices(&device_iterator))
return 0;
while (index < device_number
&& (device_object = IOIteratorNext(device_iterator)))
index++;
if (index != device_number) {
return_value = 0;
} else {
return_value = get_device_from_entry(device_object,
buffer, buffer_len);
}
IOObjectRelease(device_object);
IOObjectRelease(device_iterator);
return return_value;
}
void mb_disc_unix_read_mcn(int fd, mb_disc_private *disc)
{
dk_cd_read_mcn_t cd_read_mcn;
bzero(&cd_read_mcn, sizeof(cd_read_mcn));
if(ioctl(fd, DKIOCCDREADMCN, &cd_read_mcn) == -1) {
fprintf(stderr, "Warning: Unable to read the disc's media catalog number.\n");
} else {
strncpy( disc->mcn, cd_read_mcn.mcn, MCN_STR_LENGTH );
}
}
void mb_disc_unix_read_isrc(int fd, mb_disc_private *disc, int track)
{
dk_cd_read_isrc_t cd_read_isrc;
bzero(&cd_read_isrc, sizeof(cd_read_isrc));
cd_read_isrc.track = track;
if(ioctl(fd, DKIOCCDREADISRC, &cd_read_isrc) == -1) {
fprintf(stderr, "Warning: Unable to read the international standard recording code (ISRC) for track %i\n", track);
return;
} else {
strncpy( disc->isrc[track], cd_read_isrc.isrc, ISRC_STR_LENGTH );
}
}
int mb_disc_has_feature_unportable(enum discid_feature feature) {
switch(feature) {
case DISCID_FEATURE_READ:
case DISCID_FEATURE_MCN:
case DISCID_FEATURE_ISRC:
return 1;
default:
return 0;
}
}
char *mb_disc_get_default_device_unportable(void)
{
return MB_DEFAULT_DEVICE;
}
int mb_disc_unix_read_toc_header(int fd, mb_disc_toc *mb_toc) {
dk_cd_read_toc_t toc;
CDTOC *cdToc;
mb_disc_toc_track *track;
int i, numDesc;
int track_num, min_track, max_track;
memset(&toc, 0, sizeof(toc));
toc.format = kCDTOCFormatTOC;
toc.formatAsTime = 0;
toc.buffer = (char *)malloc(TOC_BUFFER_LEN);
toc.bufferLength = TOC_BUFFER_LEN;
if (ioctl(fd, DKIOCCDREADTOC, &toc) < 0) {
return 0;
}
if (toc.bufferLength < sizeof(CDTOC)) {
return 0;
}
cdToc = (CDTOC *)toc.buffer;
numDesc = CDTOCGetDescriptorCount(cdToc);
min_track = -1;
max_track = -1;
for(i = 0; i < numDesc; i++) {
CDTOCDescriptor *desc = &cdToc->descriptors[i];
track = NULL;
/* A2 is the code for the lead-out position in the lead-in */
if (desc->point == 0xA2 && desc->adr == 1) {
track = &mb_toc->tracks[0];
}
/* actual track data, (adr 2-3 are for MCN and ISRC data) */
if (desc->point <= 99 && desc->adr == 1) {
track_num = desc->point;
track = &mb_toc->tracks[track_num];
if (min_track < 0 || min_track > track_num) {
min_track = track_num;
}
if (max_track < track_num) {
max_track = track_num;
}
}
if (track) {
track->address = CDConvertMSFToLBA(desc->p);
track->control = desc->control;
}
}
mb_toc->first_track_num = min_track;
mb_toc->last_track_num = max_track;
free(toc.buffer);
return 1;
}
int mb_disc_unix_read_toc_entry(int fd, int track_num, mb_disc_toc_track *toc) {
/* On Darwin the tracks are already filled along with the header */
return 1;
}
int mb_disc_read_unportable(mb_disc_private *disc, const char *device,
unsigned int features) {
int device_number;
char device_name[MAXPATHLEN] = "\0";
device_number = (int) strtol(device, NULL, 10);
if (device_number > 0) {
if (!get_device_from_number(device_number,
device_name, MAXPATHLEN)) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"no disc in drive number: %d", device_number);
return 0;
} else {
return mb_disc_unix_read(disc, device_name, features);
}
} else {
return mb_disc_unix_read(disc, device, features);
}
}

View File

@ -1,43 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2013 Johannes Dewender
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------- */
#include <stdio.h>
#include "discid/discid.h"
#include "discid/discid_private.h"
char *mb_disc_get_default_device_unportable(void) {
return "/dev/null";
}
int mb_disc_has_feature_unportable(enum discid_feature feature) {
return 0;
}
int mb_disc_read_unportable(mb_disc_private *disc, const char *device, unsigned int features) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"disc reading not implemented on this platform");
return 0;
}
/* EOF */

View File

@ -1,275 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2013 Johannes Dewender
Copyright (C) 2006 Matthias Friedrich
Copyright (C) 2000 Robert Kaye
Copyright (C) 1999 Marc E E van Woerkom
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------- */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/cdrom.h>
#include <scsi/sg.h>
#include "discid/discid.h"
#include "discid/discid_private.h"
#include "unix.h"
/* timeout better shouldn't happen for scsi commands -> device is reset */
#define DEFAULT_TIMEOUT 30000 /* in ms */
#ifndef SG_MAX_SENSE
#define SG_MAX_SENSE 16
#endif
#define MB_DEFAULT_DEVICE "/dev/cdrom"
#define MAX_DEV_LEN 50
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
# define THREAD_LOCAL __thread
#else
# define THREAD_LOCAL
#endif
static THREAD_LOCAL char default_device[MAX_DEV_LEN] = "";
static int get_device(int number, char *device, int device_len) {
FILE *proc_file;
char *current_device;
char *lineptr = NULL;
char *saveptr = NULL;
size_t bufflen;
int i, count, counter;
int return_value = 0;
proc_file = fopen("/proc/sys/dev/cdrom/info", "r");
if (proc_file != NULL) {
/* skip to line containing device names */
do {
if (getline(&lineptr, &bufflen, proc_file) < 0) {
return 0;
}
} while (strstr(lineptr, "drive name:") == NULL);
/* count number of devices = number of tabs - 1*/
count = -1;
for (i = 0; i < strlen(lineptr); i++) {
if (lineptr[i] == '\t') count++;
}
/* go through devices, they are in reverse order */
current_device = strtok_r(lineptr, "\t", &saveptr);
/* skip column title */
current_device = strtok_r(NULL, "\t", &saveptr);
counter = count;
while (current_device != NULL && counter >= number) {
if (counter == number) {
snprintf(device, device_len,
"/dev/%s", current_device);
return_value = 1;
}
/* go to next in list */
current_device = strtok_r(NULL, "\t", &saveptr);
counter--;
}
/* trim the trailing \n for the last entry = first device */
if (return_value && device[strlen(device)-1] == '\n') {
device[strlen(device)-1] = '\0';
}
free(lineptr);
fclose(proc_file);
}
return return_value;
}
int mb_disc_unix_read_toc_header(int fd, mb_disc_toc *toc) {
struct cdrom_tochdr th;
int ret = ioctl(fd, CDROMREADTOCHDR, &th);
if ( ret < 0 )
return 0; /* error */
toc->first_track_num = th.cdth_trk0;
toc->last_track_num = th.cdth_trk1;
return 1;
}
int mb_disc_unix_read_toc_entry(int fd, int track_num, mb_disc_toc_track *track) {
struct cdrom_tocentry te;
int ret;
te.cdte_track = track_num;
te.cdte_format = CDROM_LBA;
ret = ioctl(fd, CDROMREADTOCENTRY, &te);
assert( te.cdte_format == CDROM_LBA );
if ( ret < 0 )
return 0; /* error */
track->address = te.cdte_addr.lba;
track->control = te.cdte_ctrl;
return 1;
}
char *mb_disc_get_default_device_unportable(void) {
/* prefer the default device symlink to the internal names */
if (mb_disc_unix_exists(MB_DEFAULT_DEVICE)) {
return MB_DEFAULT_DEVICE;
} else {
if (get_device(1, default_device, MAX_DEV_LEN)) {
return default_device;
} else {
return MB_DEFAULT_DEVICE;
}
}
}
void mb_disc_unix_read_mcn(int fd, mb_disc_private *disc) {
struct cdrom_mcn mcn;
memset(&mcn, 0, sizeof mcn);
if(ioctl(fd, CDROM_GET_MCN, &mcn) == -1) {
fprintf(stderr, "Warning: Unable to read the disc's media catalog number.\n");
} else {
strncpy( disc->mcn,
(const char *)mcn.medium_catalog_number,
MCN_STR_LENGTH );
}
}
/* Send a scsi command and receive data. */
static int scsi_cmd(int fd, unsigned char *cmd, int cmd_len,
unsigned char *data, int data_len) {
unsigned char sense_buffer[SG_MAX_SENSE]; /* for "error situations" */
sg_io_hdr_t io_hdr;
memset(&io_hdr, 0, sizeof io_hdr);
assert(cmd_len <= 16);
io_hdr.interface_id = 'S'; /* must always be 'S' (SCSI generic) */
io_hdr.cmd_len = cmd_len;
io_hdr.cmdp = cmd;
io_hdr.timeout = DEFAULT_TIMEOUT; /* timeout in ms */
io_hdr.sbp = sense_buffer;/* only used when status is CHECK_CONDITION */
io_hdr.mx_sb_len = sizeof sense_buffer;
io_hdr.flags = SG_FLAG_DIRECT_IO;
io_hdr.dxferp = (void*)data;
io_hdr.dxfer_len = data_len;
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
if (ioctl(fd, SG_IO, &io_hdr) != 0) {
return errno;
} else {
return io_hdr.status; /* 0 = success */
}
}
void mb_disc_unix_read_isrc(int fd, mb_disc_private *disc, int track_num) {
int i;
unsigned char cmd[10];
unsigned char data[24];
char buffer[ISRC_STR_LENGTH+1];
memset(cmd, 0, sizeof cmd);
memset(data, 0, sizeof data);
memset(buffer, 0, sizeof buffer);
/* data read from the last appropriate sector encountered
* by a current or previous media access operation.
* The Logical Unit accesses the media when there is/was no access.
* TODO: force access at a specific block? -> no duplicate ISRCs?
*/
cmd[0] = 0x42; /* READ SUB-CHANNEL */
/* cmd[1] reserved / MSF bit (unused) */
cmd[2] = 1 << 6; /* 6th bit set (SUBQ) -> get sub-channel data */
cmd[3] = 0x03; /* get ISRC (ADR 3, Q sub-channel Mode-3) */
/* 4+5 reserved */
cmd[6] = track_num;
/* cmd[7] = upper byte of the transfer length */
cmd[8] = sizeof data; /* transfer length in bytes (4 header, 20 data)*/
/* cmd[9] = control byte */
if (scsi_cmd(fd, cmd, sizeof cmd, data, sizeof data) != 0) {
fprintf(stderr, "Warning: Cannot get ISRC code for track %d\n",
track_num);
return;
}
/* data[1:4] = sub-q channel data header (audio status, data length) */
if (data[8] & (1 << 7)) { /* TCVAL is set -> ISRCs valid */
for (i = 0; i < ISRC_STR_LENGTH; i++) {
buffer[i] = data[9 + i];
}
buffer[ISRC_STR_LENGTH] = 0;
strncpy(disc->isrc[track_num], buffer, ISRC_STR_LENGTH);
}
/* data[21:23] = zero, AFRAME, reserved */
}
int mb_disc_has_feature_unportable(enum discid_feature feature) {
switch(feature) {
case DISCID_FEATURE_READ:
case DISCID_FEATURE_MCN:
case DISCID_FEATURE_ISRC:
return 1;
default:
return 0;
}
}
int mb_disc_read_unportable(mb_disc_private *disc, const char *device,
unsigned int features) {
char device_name[MAX_DEV_LEN] = "";
int device_number;
device_number = (int) strtol(device, NULL, 10);
if (device_number > 0) {
if(!get_device(device_number, device_name, MAX_DEV_LEN)) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"cannot find cd device with the number '%d'",
device_number);
return 0;
} else {
return mb_disc_unix_read(disc, device_name, features);
}
} else {
return mb_disc_unix_read(disc, device, features);
}
}
/* EOF */

View File

@ -1,108 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2009 Shunsuke Kuroda
Copyright (C) 2006 Matthias Friedrich
Copyright (C) 2000 Robert Kaye
Copyright (C) 1999 Marc E E van Woerkom
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
--------------------------------------------------------------------------- */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/cdio.h>
#include "discid/discid.h"
#include "discid/discid_private.h"
#include "unix.h"
#define NUM_CANDIDATES 2
static char *device_candidates[NUM_CANDIDATES] = {"/vol/dev/aliases/cdrom0",
"/volumes/dev/aliases/cdrom0"};
int mb_disc_unix_read_toc_header(int fd, mb_disc_toc *toc) {
struct cdrom_tochdr th;
int ret = ioctl(fd, CDROMREADTOCHDR, &th);
if ( ret < 0 )
return ret; /* error */
toc->first_track_num = th.cdth_trk0;
toc->last_track_num = th.cdth_trk1;
return ret;
}
int mb_disc_unix_read_toc_entry(int fd, int track_num, mb_disc_toc_track *track) {
struct cdrom_tocentry te;
int ret;
memset(&te, 0, sizeof te);
te.cdte_track = track_num;
te.cdte_format = CDROM_LBA;
ret = ioctl(fd, CDROMREADTOCENTRY, &te);
if ( ret < 0 )
return 0; /* error */
assert( te.cdte_format == CDROM_LBA );
track->address = te.cdte_addr.lba;
track->control = te.cdte_ctrl;
return 1;
}
void mb_disc_unix_read_mcn(int fd, mb_disc_private *disc) {
return;
}
void mb_disc_unix_read_isrc(int fd, mb_disc_private *disc, int track_num) {
return;
}
char *mb_disc_get_default_device_unportable(void) {
return mb_disc_unix_find_device(device_candidates, NUM_CANDIDATES);
}
int mb_disc_has_feature_unportable(enum discid_feature feature) {
switch(feature) {
case DISCID_FEATURE_READ:
return 1;
default:
return 0;
}
}
int mb_disc_read_unportable(mb_disc_private *disc, const char *device,
unsigned int features) {
return mb_disc_unix_read(disc, device, features);
}
/* EOF */

View File

@ -1,247 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2007-2008 Lukas Lalinsky
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
----------------------------------------------------------------------------*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#if (_MSC_VER < 1900)
#define snprintf _snprintf
#endif
#endif
#include <windows.h>
#include <string.h>
#include <stdio.h>
#if defined(__CYGWIN__)
#include <ntddcdrm.h>
#elif defined(__MINGW32__)
#include <ddk/ntddcdrm.h>
#else
#include "ntddcdrm.h"
#endif
#include "discid/discid.h"
#include "discid/discid_private.h"
#define MB_DEFAULT_DEVICE "D:"
#define MAX_DEV_LEN 3
#if defined(_MSC_VER)
# define THREAD_LOCAL __declspec(thread)
#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
# define THREAD_LOCAL __thread
#else
# define THREAD_LOCAL
#endif
static THREAD_LOCAL char default_device[MAX_DEV_LEN] = "\0";
static int address_to_sectors(UCHAR address[4]) {
return address[1] * 4500 + address[2] * 75 + address[3];
}
static HANDLE create_device_handle(mb_disc_private *disc, const char *device) {
HANDLE hDevice;
char filename[128];
const char* colon;
size_t len;
strcpy(filename, "\\\\.\\");
len = strlen(device);
colon = strchr(device, ':');
if (colon) {
len = colon - device + 1;
}
strncat(filename, device, len > 120 ? 120 : len);
hDevice = CreateFile(filename, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"cannot open the CD audio device '%s'", device);
return 0;
}
return hDevice;
}
static void read_disc_mcn(HANDLE hDevice, mb_disc_private *disc) {
DWORD dwReturned;
BOOL bResult;
CDROM_SUB_Q_DATA_FORMAT format;
SUB_Q_CHANNEL_DATA data;
format.Track = 0;
format.Format = IOCTL_CDROM_MEDIA_CATALOG;
bResult = DeviceIoControl(hDevice, IOCTL_CDROM_READ_Q_CHANNEL,
&format, sizeof(format),
&data, sizeof(data),
&dwReturned, NULL);
if (bResult == FALSE) {
fprintf(stderr, "Warning: Unable to read the disc's media catalog number.\n");
} else {
strncpy(disc->mcn, (char *) data.MediaCatalog.MediaCatalog,
MCN_STR_LENGTH);
}
}
static void read_disc_isrc(HANDLE hDevice, mb_disc_private *disc, int track) {
DWORD dwReturned;
BOOL bResult;
CDROM_SUB_Q_DATA_FORMAT format;
SUB_Q_CHANNEL_DATA data;
format.Track = track;
format.Format = IOCTL_CDROM_TRACK_ISRC;
bResult = DeviceIoControl(hDevice, IOCTL_CDROM_READ_Q_CHANNEL,
&format, sizeof(format),
&data, sizeof(data),
&dwReturned, NULL);
if (bResult == FALSE) {
fprintf(stderr, "Warning: Unable to read the international standard recording code (ISRC) for track %i\n", track);
} else {
strncpy(disc->isrc[track], (char *) data.TrackIsrc.TrackIsrc,
ISRC_STR_LENGTH);
}
}
static int get_nth_device(int number, char* device, int device_length) {
int i, counter = 0;
char tmpDevice[MAX_DEV_LEN];
DWORD mask = GetLogicalDrives();
for (i = 0; i <= 25; i++) {
if (mask >> i & 1) {
snprintf(tmpDevice, MAX_DEV_LEN, "%c:", i + 'A');
if (GetDriveType(tmpDevice) == DRIVE_CDROM) {
counter++;
if (counter == number) {
strncpy(device, tmpDevice, device_length);
return TRUE;
}
}
}
}
return FALSE;
}
char *mb_disc_get_default_device_unportable(void) {
if (!get_nth_device(1, default_device, MAX_DEV_LEN)) {
return MB_DEFAULT_DEVICE;
}
return default_device;
}
int mb_disc_has_feature_unportable(enum discid_feature feature) {
switch(feature) {
case DISCID_FEATURE_READ:
case DISCID_FEATURE_MCN:
case DISCID_FEATURE_ISRC:
return 1;
default:
return 0;
}
}
static int mb_disc_winnt_read_toc(HANDLE device, mb_disc_private *disc, mb_disc_toc *toc) {
DWORD dwReturned;
BOOL bResult;
CDROM_TOC cd;
int i;
bResult = DeviceIoControl(device, IOCTL_CDROM_READ_TOC,
NULL, 0,
&cd, sizeof(cd),
&dwReturned, NULL);
if (bResult == FALSE) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"error while reading the CD TOC");
return 0;
}
toc->first_track_num = cd.FirstTrack;
toc->last_track_num = cd.LastTrack;
/* Get info about all tracks */
for (i = toc->first_track_num; i <= toc->last_track_num; i++) {
toc->tracks[i].address = address_to_sectors(cd.TrackData[i - 1].Address) - 150;
toc->tracks[i].control = cd.TrackData[i - 1].Control;
}
/* Lead-out is stored after the last track */
toc->tracks[0].address = address_to_sectors(cd.TrackData[toc->last_track_num].Address) - 150;
toc->tracks[0].control = cd.TrackData[toc->last_track_num].Control;
return 1;
}
int mb_disc_read_unportable(mb_disc_private *disc, const char *device,
unsigned int features) {
mb_disc_toc toc;
char tmpDevice[MAX_DEV_LEN];
HANDLE hDevice;
int i, device_number;
device_number = (int) strtol(device, NULL, 10);
if (device_number > 0) {
if (!get_nth_device(device_number, tmpDevice, MAX_DEV_LEN)) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"cannot find the CD audio device '%i'", device_number);
return 0;
}
device = tmpDevice;
}
hDevice = create_device_handle(disc, device);
if (hDevice == 0)
return 0;
if (!mb_disc_winnt_read_toc(hDevice, disc, &toc)) {
CloseHandle(hDevice);
return 0;
}
if (!mb_disc_load_toc(disc, &toc)) {
CloseHandle(hDevice);
return 0;
}
if (features & DISCID_FEATURE_MCN) {
read_disc_mcn(hDevice, disc);
}
for (i = disc->first_track_num; i <= disc->last_track_num; i++) {
if (features & DISCID_FEATURE_ISRC) {
read_disc_isrc(hDevice, disc, i);
}
}
CloseHandle(hDevice);
return 1;
}
/* EOF */

View File

@ -1,320 +0,0 @@
/*
* ntddcdrm.h
*
* CDROM IOCTL interface.
*
* This file is part of the w32api package.
*
* Contributors:
* Created by Casper S. Hornstrup <chorns@users.sourceforge.net>
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __NTDDCDRM_H
#define __NTDDCDRM_H
#if __GNUC__ >=3
#pragma GCC system_header
#endif
#ifdef __cplusplus
extern "C" {
#endif
#pragma pack(push,4)
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
#define IOCTL_CDROM_CHECK_VERIFY \
CTL_CODE(IOCTL_CDROM_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_FIND_NEW_DEVICES \
CTL_CODE(IOCTL_CDROM_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_GET_CONTROL \
CTL_CODE(IOCTL_CDROM_BASE, 0x000D, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY \
CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_GET_LAST_SESSION \
CTL_CODE(IOCTL_CDROM_BASE, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_GET_VOLUME \
CTL_CODE(IOCTL_CDROM_BASE, 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_PAUSE_AUDIO \
CTL_CODE(IOCTL_CDROM_BASE, 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_PLAY_AUDIO_MSF \
CTL_CODE(IOCTL_CDROM_BASE, 0x0006, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_RAW_READ \
CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS)
#define IOCTL_CDROM_READ_Q_CHANNEL \
CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_READ_TOC \
CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_READ_TOC_EX \
CTL_CODE(IOCTL_CDROM_BASE, 0x0015, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_RESUME_AUDIO \
CTL_CODE(IOCTL_CDROM_BASE, 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_SEEK_AUDIO_MSF \
CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_SET_VOLUME \
CTL_CODE(IOCTL_CDROM_BASE, 0x000A, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_SIMBAD \
CTL_CODE(IOCTL_CDROM_BASE, 0x1003, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_STOP_AUDIO \
CTL_CODE(IOCTL_CDROM_BASE, 0x0002, METHOD_BUFFERED, FILE_READ_ACCESS)
#define MAXIMUM_NUMBER_TRACKS 100
#define MAXIMUM_CDROM_SIZE 804
#define MINIMUM_CDROM_READ_TOC_EX_SIZE 2
typedef struct _TRACK_DATA {
UCHAR Reserved;
UCHAR Control : 4;
UCHAR Adr : 4;
UCHAR TrackNumber;
UCHAR Reserved1;
UCHAR Address[4];
} TRACK_DATA, *PTRACK_DATA;
/* CDROM_DISK_DATA.DiskData flags */
#define CDROM_DISK_AUDIO_TRACK 0x00000001
#define CDROM_DISK_DATA_TRACK 0x00000002
typedef struct _CDROM_DISK_DATA {
ULONG DiskData;
} CDROM_DISK_DATA, *PCDROM_DISK_DATA;
typedef struct _CDROM_PLAY_AUDIO_MSF {
UCHAR StartingM;
UCHAR StartingS;
UCHAR StartingF;
UCHAR EndingM;
UCHAR EndingS;
UCHAR EndingF;
} CDROM_PLAY_AUDIO_MSF, *PCDROM_PLAY_AUDIO_MSF;
/* CDROM_READ_TOC_EX.Format constants */
#define CDROM_READ_TOC_EX_FORMAT_TOC 0x00
#define CDROM_READ_TOC_EX_FORMAT_SESSION 0x01
#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC 0x02
#define CDROM_READ_TOC_EX_FORMAT_PMA 0x03
#define CDROM_READ_TOC_EX_FORMAT_ATIP 0x04
#define CDROM_READ_TOC_EX_FORMAT_CDTEXT 0x05
typedef struct _CDROM_READ_TOC_EX {
UCHAR Format : 4;
UCHAR Reserved1 : 3;
UCHAR Msf : 1;
UCHAR SessionTrack;
UCHAR Reserved2;
UCHAR Reserved3;
} CDROM_READ_TOC_EX, *PCDROM_READ_TOC_EX;
typedef struct _CDROM_SEEK_AUDIO_MSF {
UCHAR M;
UCHAR S;
UCHAR F;
} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF;
/* CDROM_SUB_Q_DATA_FORMAT.Format constants */
#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00
#define IOCTL_CDROM_CURRENT_POSITION 0x01
#define IOCTL_CDROM_MEDIA_CATALOG 0x02
#define IOCTL_CDROM_TRACK_ISRC 0x03
typedef struct _CDROM_SUB_Q_DATA_FORMAT {
UCHAR Format;
UCHAR Track;
} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT;
typedef struct _CDROM_TOC {
UCHAR Length[2];
UCHAR FirstTrack;
UCHAR LastTrack;
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS];
} CDROM_TOC, *PCDROM_TOC;
#define CDROM_TOC_SIZE sizeof(CDROM_TOC)
typedef struct _CDROM_TOC_ATIP_DATA_BLOCK {
UCHAR CdrwReferenceSpeed : 3;
UCHAR Reserved3 : 1;
UCHAR WritePower : 3;
UCHAR True1 : 1;
UCHAR Reserved4 : 6;
UCHAR UnrestrictedUse : 1;
UCHAR Reserved5 : 1;
UCHAR A3Valid : 1;
UCHAR A2Valid : 1;
UCHAR A1Valid : 1;
UCHAR Reserved6 : 3;
UCHAR IsCdrw : 1;
UCHAR True2 : 1;
UCHAR Reserved7;
UCHAR LeadInMsf[3];
UCHAR Reserved8;
UCHAR LeadOutMsf[3];
UCHAR Reserved9;
UCHAR A1Values[3];
UCHAR Reserved10;
UCHAR A2Values[3];
UCHAR Reserved11;
UCHAR A3Values[3];
UCHAR Reserved12;
} CDROM_TOC_ATIP_DATA_BLOCK, *PCDROM_TOC_ATIP_DATA_BLOCK;
/* CDROM_TOC_CD_TEXT_DATA_BLOCK.PackType constants */
#define CDROM_CD_TEXT_PACK_ALBUM_NAME 0x80
#define CDROM_CD_TEXT_PACK_PERFORMER 0x81
#define CDROM_CD_TEXT_PACK_SONGWRITER 0x82
#define CDROM_CD_TEXT_PACK_COMPOSER 0x83
#define CDROM_CD_TEXT_PACK_ARRANGER 0x84
#define CDROM_CD_TEXT_PACK_MESSAGES 0x85
#define CDROM_CD_TEXT_PACK_DISC_ID 0x86
#define CDROM_CD_TEXT_PACK_GENRE 0x87
#define CDROM_CD_TEXT_PACK_TOC_INFO 0x88
#define CDROM_CD_TEXT_PACK_TOC_INFO2 0x89
#define CDROM_CD_TEXT_PACK_UPC_EAN 0x8e
#define CDROM_CD_TEXT_PACK_SIZE_INFO 0x8f
typedef struct _CDROM_TOC_CD_TEXT_DATA_BLOCK {
UCHAR PackType;
UCHAR TrackNumber : 7;
UCHAR ExtensionFlag : 1;
UCHAR SequenceNumber;
UCHAR CharacterPosition : 4;
UCHAR BlockNumber : 3;
UCHAR Unicode : 1;
union {
UCHAR Text[12];
WCHAR WText[6];
};
UCHAR CRC[2];
} CDROM_TOC_CD_TEXT_DATA_BLOCK, *PCDROM_TOC_CD_TEXT_DATA_BLOCK;
/* CDROM_TOC_FULL_TOC_DATA_BLOCK.Adr constants */
#define ADR_NO_MODE_INFORMATION 0x0
#define ADR_ENCODES_CURRENT_POSITION 0x1
#define ADR_ENCODES_MEDIA_CATALOG 0x2
#define ADR_ENCODES_ISRC 0x3
typedef struct _CDROM_TOC_FULL_TOC_DATA_BLOCK {
UCHAR SessionNumber;
UCHAR Control : 4;
UCHAR Adr : 4;
UCHAR Reserved1;
UCHAR Point;
UCHAR MsfExtra[3];
UCHAR Zero;
UCHAR Msf[3];
} CDROM_TOC_FULL_TOC_DATA_BLOCK, *PCDROM_TOC_FULL_TOC_DATA_BLOCK;
/* SUB_Q_HEADER.AudioStatus constants */
#define AUDIO_STATUS_NOT_SUPPORTED 0x00
#define AUDIO_STATUS_IN_PROGRESS 0x11
#define AUDIO_STATUS_PAUSED 0x12
#define AUDIO_STATUS_PLAY_COMPLETE 0x13
#define AUDIO_STATUS_PLAY_ERROR 0x14
#define AUDIO_STATUS_NO_STATUS 0x15
typedef struct _SUB_Q_HEADER {
UCHAR Reserved;
UCHAR AudioStatus;
UCHAR DataLength[2];
} SUB_Q_HEADER, *PSUB_Q_HEADER;
typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER {
SUB_Q_HEADER Header;
UCHAR FormatCode;
UCHAR Reserved[3];
UCHAR Reserved1 : 7;
UCHAR Mcval :1;
UCHAR MediaCatalog[15];
} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER;
typedef struct _SUB_Q_TRACK_ISRC {
SUB_Q_HEADER Header;
UCHAR FormatCode;
UCHAR Reserved0;
UCHAR Track;
UCHAR Reserved1;
UCHAR Reserved2 : 7;
UCHAR Tcval : 1;
UCHAR TrackIsrc[15];
} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC;
typedef struct _SUB_Q_CURRENT_POSITION {
SUB_Q_HEADER Header;
UCHAR FormatCode;
UCHAR Control : 4;
UCHAR ADR : 4;
UCHAR TrackNumber;
UCHAR IndexNumber;
UCHAR AbsoluteAddress[4];
UCHAR TrackRelativeAddress[4];
} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION;
typedef union _SUB_Q_CHANNEL_DATA {
SUB_Q_CURRENT_POSITION CurrentPosition;
SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog;
SUB_Q_TRACK_ISRC TrackIsrc;
} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA;
/* CDROM_AUDIO_CONTROL.LbaFormat constants */
#define AUDIO_WITH_PREEMPHASIS 0x1
#define DIGITAL_COPY_PERMITTED 0x2
#define AUDIO_DATA_TRACK 0x4
#define TWO_FOUR_CHANNEL_AUDIO 0x8
typedef struct _CDROM_AUDIO_CONTROL {
UCHAR LbaFormat;
USHORT LogicalBlocksPerSecond;
} CDROM_AUDIO_CONTROL, *PCDROM_AUDIO_CONTROL;
typedef struct _VOLUME_CONTROL {
UCHAR PortVolume[4];
} VOLUME_CONTROL, *PVOLUME_CONTROL;
typedef enum _TRACK_MODE_TYPE {
YellowMode2,
XAForm2,
CDDA
} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
typedef struct __RAW_READ_INFO {
LARGE_INTEGER DiskOffset;
ULONG SectorCount;
TRACK_MODE_TYPE TrackMode;
} RAW_READ_INFO, *PRAW_READ_INFO;
#pragma pack(pop)
#ifdef __cplusplus
}
#endif
#endif /* __NTDDCDRM_H */

View File

@ -1,329 +0,0 @@
/* (PD) 2001 The Bitzi Corporation
* Please see file COPYING or http://bitzi.com/publicdomain
* for more info.
*
* NIST Secure Hash Algorithm
* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu>
* from Peter C. Gutmann's implementation as found in
* Applied Cryptography by Bruce Schneier
* Further modifications to include the "UNRAVEL" stuff, below
*
* This code is in the public domain
*
* $Id$
*/
#include <string.h>
#include "sha1.h"
/* UNRAVEL should be fastest & biggest */
/* UNROLL_LOOPS should be just as big, but slightly slower */
/* both undefined should be smallest and slowest */
#define UNRAVEL
/* #define UNROLL_LOOPS */
/* SHA f()-functions */
#define f1(x,y,z) ((x & y) | (~x & z))
#define f2(x,y,z) (x ^ y ^ z)
#define f3(x,y,z) ((x & y) | (x & z) | (y & z))
#define f4(x,y,z) (x ^ y ^ z)
/* SHA constants */
#define CONST1 0x5a827999L
#define CONST2 0x6ed9eba1L
#define CONST3 0x8f1bbcdcL
#define CONST4 0xca62c1d6L
/* truncate to 32 bits -- should be a null op on 32-bit machines */
#define T32(x) ((x) & 0xffffffffL)
/* 32-bit rotate */
#define R32(x,n) T32(((x << n) | (x >> (32 - n))))
/* the generic case, for when the overall rotation is not unraveled */
#define FG(n) \
T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); \
E = D; D = C; C = R32(B,30); B = A; A = T
/* specific cases, for when the overall rotation is unraveled */
#define FA(n) \
T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); B = R32(B,30)
#define FB(n) \
E = T32(R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n); A = R32(A,30)
#define FC(n) \
D = T32(R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n); T = R32(T,30)
#define FD(n) \
C = T32(R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n); E = R32(E,30)
#define FE(n) \
B = T32(R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n); D = R32(D,30)
#define FT(n) \
A = T32(R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n); C = R32(C,30)
/* do SHA transformation */
static void sha_transform(SHA_INFO *sha_info)
{
int i;
SHA_BYTE *dp;
SHA_LONG T, A, B, C, D, E, W[80], *WP;
dp = sha_info->data;
/*
the following makes sure that at least one code block below is
traversed or an error is reported, without the necessity for nested
preprocessor if/else/endif blocks, which are a great pain in the
nether regions of the anatomy...
*/
#undef SWAP_DONE
#if (SHA_BYTE_ORDER == 1234)
#define SWAP_DONE
for (i = 0; i < 16; ++i) {
T = *((SHA_LONG *) dp);
dp += 4;
W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
}
#endif /* SHA_BYTE_ORDER == 1234 */
#if (SHA_BYTE_ORDER == 4321)
#define SWAP_DONE
for (i = 0; i < 16; ++i) {
T = *((SHA_LONG *) dp);
dp += 4;
W[i] = T32(T);
}
#endif /* SHA_BYTE_ORDER == 4321 */
#if (SHA_BYTE_ORDER == 12345678)
#define SWAP_DONE
for (i = 0; i < 16; i += 2) {
T = *((SHA_LONG *) dp);
dp += 8;
W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
T >>= 32;
W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
}
#endif /* SHA_BYTE_ORDER == 12345678 */
#if (SHA_BYTE_ORDER == 87654321)
#define SWAP_DONE
for (i = 0; i < 16; i += 2) {
T = *((SHA_LONG *) dp);
dp += 8;
W[i] = T32(T >> 32);
W[i+1] = T32(T);
}
#endif /* SHA_BYTE_ORDER == 87654321 */
#ifndef SWAP_DONE
#error Unknown byte order -- you need to add code here
#endif /* SWAP_DONE */
for (i = 16; i < 80; ++i) {
W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
#if (SHA_VERSION == 1)
W[i] = R32(W[i], 1);
#endif /* SHA_VERSION */
}
A = sha_info->digest[0];
B = sha_info->digest[1];
C = sha_info->digest[2];
D = sha_info->digest[3];
E = sha_info->digest[4];
WP = W;
#ifdef UNRAVEL
FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
sha_info->digest[0] = T32(sha_info->digest[0] + E);
sha_info->digest[1] = T32(sha_info->digest[1] + T);
sha_info->digest[2] = T32(sha_info->digest[2] + A);
sha_info->digest[3] = T32(sha_info->digest[3] + B);
sha_info->digest[4] = T32(sha_info->digest[4] + C);
#else /* !UNRAVEL */
#ifdef UNROLL_LOOPS
FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
#else /* !UNROLL_LOOPS */
for (i = 0; i < 20; ++i) { FG(1); }
for (i = 20; i < 40; ++i) { FG(2); }
for (i = 40; i < 60; ++i) { FG(3); }
for (i = 60; i < 80; ++i) { FG(4); }
#endif /* !UNROLL_LOOPS */
sha_info->digest[0] = T32(sha_info->digest[0] + A);
sha_info->digest[1] = T32(sha_info->digest[1] + B);
sha_info->digest[2] = T32(sha_info->digest[2] + C);
sha_info->digest[3] = T32(sha_info->digest[3] + D);
sha_info->digest[4] = T32(sha_info->digest[4] + E);
#endif /* !UNRAVEL */
}
/* initialize the SHA digest */
void sha_init(SHA_INFO *sha_info)
{
sha_info->digest[0] = 0x67452301L;
sha_info->digest[1] = 0xefcdab89L;
sha_info->digest[2] = 0x98badcfeL;
sha_info->digest[3] = 0x10325476L;
sha_info->digest[4] = 0xc3d2e1f0L;
sha_info->count_lo = 0L;
sha_info->count_hi = 0L;
sha_info->local = 0;
}
/* update the SHA digest */
void sha_update(SHA_INFO *sha_info, SHA_BYTE *buffer, size_t count)
{
size_t i;
SHA_LONG clo;
clo = T32(sha_info->count_lo + ((SHA_LONG) count << 3));
if (clo < sha_info->count_lo) {
++sha_info->count_hi;
}
sha_info->count_lo = clo;
sha_info->count_hi += (SHA_LONG) count >> 29;
if (sha_info->local) {
i = SHA_BLOCKSIZE - sha_info->local;
if (i > count) {
i = count;
}
memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
count -= i;
buffer += i;
sha_info->local += i;
if (sha_info->local == SHA_BLOCKSIZE) {
sha_transform(sha_info);
} else {
return;
}
}
while (count >= SHA_BLOCKSIZE) {
memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
buffer += SHA_BLOCKSIZE;
count -= SHA_BLOCKSIZE;
sha_transform(sha_info);
}
memcpy(sha_info->data, buffer, count);
sha_info->local = count;
}
/* finish computing the SHA digest */
void sha_final(unsigned char digest[20], SHA_INFO *sha_info)
{
int count;
SHA_LONG lo_bit_count, hi_bit_count;
lo_bit_count = sha_info->count_lo;
hi_bit_count = sha_info->count_hi;
count = (int) ((lo_bit_count >> 3) & 0x3f);
((SHA_BYTE *) sha_info->data)[count++] = 0x80;
if (count > SHA_BLOCKSIZE - 8) {
memset(((SHA_BYTE *) sha_info->data) + count, 0, SHA_BLOCKSIZE - count);
sha_transform(sha_info);
memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
} else {
memset(((SHA_BYTE *) sha_info->data) + count, 0,
SHA_BLOCKSIZE - 8 - count);
}
sha_info->data[56] = (unsigned char) ((hi_bit_count >> 24) & 0xff);
sha_info->data[57] = (unsigned char) ((hi_bit_count >> 16) & 0xff);
sha_info->data[58] = (unsigned char) ((hi_bit_count >> 8) & 0xff);
sha_info->data[59] = (unsigned char) ((hi_bit_count >> 0) & 0xff);
sha_info->data[60] = (unsigned char) ((lo_bit_count >> 24) & 0xff);
sha_info->data[61] = (unsigned char) ((lo_bit_count >> 16) & 0xff);
sha_info->data[62] = (unsigned char) ((lo_bit_count >> 8) & 0xff);
sha_info->data[63] = (unsigned char) ((lo_bit_count >> 0) & 0xff);
sha_transform(sha_info);
digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
}
/* compute the SHA digest of a FILE stream */
#define BLOCK_SIZE 8192
void sha_stream(unsigned char digest[20], SHA_INFO *sha_info, FILE *fin)
{
size_t i;
SHA_BYTE data[BLOCK_SIZE];
sha_init(sha_info);
while ((i = fread(data, 1, BLOCK_SIZE, fin)) > 0) {
sha_update(sha_info, data, i);
}
sha_final(digest, sha_info);
}
/* print a SHA digest */
void sha_print(unsigned char digest[20])
{
int i, j;
for (j = 0; j < 5; ++j) {
for (i = 0; i < 4; ++i) {
printf("%02x", *digest++);
}
printf("%c", (j < 4) ? ' ' : '\n');
}
}
char *sha_version(void)
{
#if (SHA_VERSION == 1)
static char *version = "SHA-1";
#else
static char *version = "SHA";
#endif
return(version);
}

View File

@ -1,63 +0,0 @@
/* NIST Secure Hash Algorithm */
/* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */
/* from Peter C. Gutmann's implementation as found in */
/* Applied Cryptography by Bruce Schneier */
/* This code is in the public domain */
/* $Id$ */
#ifndef SHA_H
#define SHA_H
#include <stdlib.h>
#include <stdio.h>
#include "discid/discid.h" /* for LIBDISCID_INTERNAL */
/* Useful defines & typedefs */
typedef unsigned char SHA_BYTE; /* 8-bit quantity */
typedef unsigned long SHA_LONG; /* 32-or-more-bit quantity */
#define SHA_BLOCKSIZE 64
#define SHA_DIGESTSIZE 20
typedef struct {
SHA_LONG digest[5]; /* message digest */
SHA_LONG count_lo, count_hi; /* 64-bit bit count */
SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
size_t local; /* unprocessed amount in data */
} SHA_INFO;
LIBDISCID_INTERNAL void sha_init(SHA_INFO *);
LIBDISCID_INTERNAL void sha_update(SHA_INFO *, SHA_BYTE *, size_t);
LIBDISCID_INTERNAL void sha_final(unsigned char [20], SHA_INFO *);
LIBDISCID_INTERNAL void sha_stream(unsigned char [20], SHA_INFO *, FILE *);
LIBDISCID_INTERNAL void sha_print(unsigned char [20]);
LIBDISCID_INTERNAL char *sha_version(void);
#define SHA_VERSION 1
#ifdef HAVE_CONFIG_H
#include "config.h"
#ifdef WORDS_BIGENDIAN
# if SIZEOF_LONG == 4
# define SHA_BYTE_ORDER 4321
# elif SIZEOF_LONG == 8
# define SHA_BYTE_ORDER 87654321
# endif
#else
# if SIZEOF_LONG == 4
# define SHA_BYTE_ORDER 1234
# elif SIZEOF_LONG == 8
# define SHA_BYTE_ORDER 12345678
# endif
#endif
#else
#define SHA_BYTE_ORDER 1234
#endif
#endif /* SHA_H */

View File

@ -1,116 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2006 Lukas Lalinsky
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------- */
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#if (_MSC_VER < 1900)
#define snprintf _snprintf
#endif
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "discid/discid_private.h"
#define XA_INTERVAL ((60 + 90 + 2) * 75)
#define DATA_TRACK 0x04
int mb_disc_load_toc(mb_disc_private *disc, mb_disc_toc *toc) {
int first_audio_track, last_audio_track, i;
mb_disc_toc_track *track;
if (toc->first_track_num < 1) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"invalid CD TOC - first track number must be 1 or higher");
return 0;
}
if (toc->last_track_num < 1) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"invalid CD TOC - last track number must be 99 or lower");
return 0;
}
/* we can't just skip data tracks at the front
* releases are always expected to start with track 1 by MusicBrainz
*/
first_audio_track = toc->first_track_num;
last_audio_track = -1;
/* scan the TOC for audio tracks */
for (i = toc->first_track_num; i <= toc->last_track_num; i++) {
track = &toc->tracks[i];
if ( !(track->control & DATA_TRACK) ) {
last_audio_track = i;
}
}
if (last_audio_track < 0) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"no actual audio tracks on disc: CDROM or DVD?");
return 0;
}
disc->first_track_num = first_audio_track;
disc->last_track_num = last_audio_track;
/* get offsets for all found data tracks */
for (i = first_audio_track; i <= last_audio_track; i++) {
track = &toc->tracks[i];
if (track->address > 0) {
disc->track_offsets[i] = track->address + 150;
} else {
/* this seems to happen on "copy-protected" discs */
disc->track_offsets[i] = 150;
}
}
/* if the last audio track is not the last track on the CD,
* use the offset of the next data track as the "lead-out" offset */
if (last_audio_track < toc->last_track_num) {
track = &toc->tracks[last_audio_track + 1];
disc->track_offsets[0] = track->address - XA_INTERVAL + 150;
} else {
/* use the regular lead-out track */
track = &toc->tracks[0];
disc->track_offsets[0] = track->address + 150;
}
/* as long as the lead-out isn't actually bigger than
* the position of the last track, the last track is invalid.
* This happens on "copy-protected"/invalid discs.
* The track is then neither a valid audio track, nor data track.
*/
while (disc->track_offsets[0] < disc->track_offsets[last_audio_track]) {
disc->last_track_num = --last_audio_track;
disc->track_offsets[last_audio_track + 1] = 0;
track = &toc->tracks[last_audio_track + 1];
disc->track_offsets[0] = track->address - XA_INTERVAL + 150;
}
return 1;
}
/* EOF */

View File

@ -1,151 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2006 Matthias Friedrich
Copyright (C) 2000 Robert Kaye
Copyright (C) 1999 Marc E E van Woerkom
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------- */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include "discid/discid_private.h"
#include "unix.h"
int mb_disc_unix_exists(const char *device) {
int fd;
fd = open(device, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
/* we only check for existance, access should fail later on */
if (errno == ENOENT) {
return 0;
} else {
return 1;
}
} else {
close(fd);
return 1;
}
}
char *mb_disc_unix_find_device(char *candidates[], int num_candidates) {
int i;
for (i = 0; i < num_candidates; i++) {
if (mb_disc_unix_exists(candidates[i])) {
return candidates[i];
}
}
/* use the first name for the error message later on */
return candidates[0];
}
int mb_disc_unix_open(mb_disc_private *disc, const char *device) {
int fd;
fd = open(device, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"cannot open device `%s'", device);
}
/* fd < 0 check needs to be made by caller */
return fd;
}
int mb_disc_unix_read_toc(int fd, mb_disc_private *disc, mb_disc_toc *toc) {
int i;
/* Find the numbers of the first track (usually 1) and the last track. */
if ( !mb_disc_unix_read_toc_header(fd, toc) ) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"cannot read table of contents");
return 0;
}
/* basic error checking */
if ( toc->last_track_num == 0 ) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"this disc has no tracks");
return 0;
}
/*
* Read the TOC entry for every track.
*/
for (i = toc->first_track_num; i <= toc->last_track_num; i++) {
if ( !mb_disc_unix_read_toc_entry(fd, i, &toc->tracks[i]) ) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"cannot read TOC entry for track %d", i);
return 0;
}
}
if ( !mb_disc_unix_read_toc_entry(fd, 0xAA, &toc->tracks[0]) ) {
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
"cannot read TOC entry for lead-out");
return 0;
}
return 1;
}
int mb_disc_unix_read(mb_disc_private *disc, const char *device,
unsigned int features) {
mb_disc_toc toc;
int fd;
int i;
fd = mb_disc_unix_open(disc, device);
if (fd < 0)
return 0;
if ( !mb_disc_unix_read_toc(fd, disc, &toc) ) {
close(fd);
return 0;
}
if ( !mb_disc_load_toc(disc, &toc) ) {
close(fd);
return 0;
}
/* Read in the media catalog number */
if (features & DISCID_FEATURE_MCN
&& mb_disc_has_feature_unportable(DISCID_FEATURE_MCN)) {
mb_disc_unix_read_mcn(fd, disc);
}
/* Read the ISRC for the track */
if (features & DISCID_FEATURE_ISRC
&& mb_disc_has_feature_unportable(DISCID_FEATURE_ISRC)) {
for (i = disc->first_track_num; i <= disc->last_track_num; i++) {
mb_disc_unix_read_isrc(fd, disc, i);
}
}
close(fd);
return 1;
}
/* EOF */

View File

@ -1,103 +0,0 @@
/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2013 Johannes Dewender
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------- */
#include "discid/discid_private.h"
/*
* required functions
* ------------------
*/
/*
* Read the TOC header from disc
*
* THIS FUNCTION HAS TO BE IMPLEMENTED FOR THE PLATFORM
*/
LIBDISCID_INTERNAL int mb_disc_unix_read_toc_header(int fd, mb_disc_toc *toc);
/*
* Read a TOC entry for a certain track from disc
*
* THIS FUNCTION HAS TO BE IMPLEMENTED FOR THE PLATFORM
*/
LIBDISCID_INTERNAL int mb_disc_unix_read_toc_entry(int fd, int track_num,
mb_disc_toc_track *track);
/*
* Read the MCN from the disc
*
* THIS FUNCTION HAS TO BE IMPLEMENTED FOR THE PLATFORM
*/
LIBDISCID_INTERNAL void mb_disc_unix_read_mcn(int fd, mb_disc_private *disc);
/*
* Read the ISRC for a certain track from disc
*
* THIS FUNCTION HAS TO BE IMPLEMENTED FOR THE PLATFORM
*/
LIBDISCID_INTERNAL void mb_disc_unix_read_isrc(int fd, mb_disc_private *disc,
int track_num);
/*
* provided functions
* ------------------
*/
/*
* This function is implemented in unix.c and can be used
* for most platforms to implement mb_disc_read_unportable
* after the above functions are implemented on the platform.
* Returns 1 on success and 0 on failure.
*/
LIBDISCID_INTERNAL int mb_disc_unix_read(mb_disc_private *disc,
const char *device, unsigned int features);
/*
* This function is implemented in unix.c and can be used
* after the above functions are implemented on the platform.
* This uses mb_disc_unix_read_toc_* and adds some error checking.
* Returns 1 on success and 0 on failure.
*/
LIBDISCID_INTERNAL int mb_disc_unix_read_toc(int fd, mb_disc_private *disc,
mb_disc_toc *toc);
/*
* utility function to find an existing device from a candidate list
*/
LIBDISCID_INTERNAL int mb_disc_unix_exists(const char *device);
/*
* utility function to find an existing device from a candidate list
*/
LIBDISCID_INTERNAL char *mb_disc_unix_find_device(char *candidates[],
int num_candidates);
/*
* utility function to try opening the device with open()
* returns a non-negative file descriptor on success.
* On failure a negative integer is returned and error_msg filled
* with an appropriate string.
*/
LIBDISCID_INTERNAL int mb_disc_unix_open(mb_disc_private *disc,
const char *device);