0
0

Is there a way to read raw cd data, instead of just playing the cd??? Because, if you allow raw data reads of each CDA track on the cd you could allow spectrum analysis, VU, and all DSP effects for CD Audio. If anyone is familiar with Sonique2, the sonique team implemented a Raw CD reader into S2, I was just thinking maybe in upcoming releases of FMOD you could also implement such abilities into it. Thanks.

  • You must to post comments
0
0

Wow, no one has replied yet! ๐Ÿ˜ฅ

Anyways, maybe you’re not understanding me. By raw data reads I mean actually being able to load each track as if it were a single file, then decoding the data into a readable format for fmod to play. Thus, reading the raw data from each track. Is this impossible or is it accomplishable through fmod?

Thanks.

  • You must to post comments
0
0

What you need is digital audio extraction.
The new version of windows media player plays that way.

It is not (yet) possible with fmod, and I haven’t found code on how to do it myself yet.

  • You must to post comments
0
0

As far as I know, Brett posted in another Topic that this is not implented in FMOD yet. It is planed, but Brett has not found enough information on this. I hope that Brett is now more informed and the next release is going to have such a function, but I guess this is only a hope.

(hm, I guess I should pay more attention to the english lessons at school ๐Ÿ˜‰ )

  • You must to post comments
0
0

Ok, thank you. I might try to find some resources on digital audio extraction, and then post back later. Thanks for the info.

  • You must to post comments
0
0

The only way to do this is to use the aspi or the mscdex api, here is a snippet from the msdn :
(sorry for this long code )

//——————————————————————–
// Code inside the Win32 DLL (the 32-bit side of the thunk)
// ReadSectorsFromCD() is exported by the DLL so that it can be called
// by Win32-based applications.

include <windows.h>

define CD_SECTOR_SIZE 2048

__declspec(dllexport)
BOOL WINAPI ReadSectorsFromCD (BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpBuff);

// Prototype for thunk function in 16-bit DLL.
BOOL FAR PASCAL ReadCDRomSectors (BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpBuffer);

/*——————————————————————-
ReadSectorsFromCD()

Calls the thunked function, ReadCDRomSectors(). This function is
exported by the Win32 DLL and thus is callable from Win32-based
applications.

Parameters:

 bDrive
    Drive letter of CD-ROM drive to read from. Specified as
    a character in the range 'A', 'B', 'C', ..., 'Z'.  May be
    upper- or lower-case.

 dwStartSector
    First sector to read.

 wSectors
    Number of sectors to read.

 lpBuffer
    Buffer to contain sector data. Must be large enough to
    accommodate all sectors being read. Because this buffer is
    provided to the 16-bit DLL via a thunk, its maximum
    length is limited to 64K.

Example use:
// Read 5 sectors from CD-ROM drive E: starting at sector 16.
fResult = ReadSectorsFromCD (‘E’, 16, 5, lpBuff);

Return Value
Returns TRUE if successful, or FALSE if an error occurred
in reading or if a parameter was invalid.
——————————————————————-*/

__declspec(dllexport)
BOOL WINAPI ReadSectorsFromCD (BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpBuff)
{
// Call 16-bit DLL to read sectors via a 32->16 thunk
return ReadCDRomSectors (bDrive, dwStartSector, wSectors, lpBuff);
}

//——————————————————————–
// Contents of the thunk script

enablemapdirect3216 = true;

typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned char BYTE, *LPBYTE;
typedef bool BOOL;

BOOL ReadCDRomSectors (BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpBuffer)
{
lpBuffer = inout;
}

//——————————————————————–
// Code inside the 16-bit DLL. This code implements the 16-bit side of
// the thunk, and is where the calls to MSCDEX are made to read
// sectors from a compact disc.

include <windows.h>

include <string.h>

include <ctype.h>

// Cooked-mode sector size in bytes

define CD_SECTOR_SIZE 2048

// Maximum sector buffer size in bytes

define MAX_BUFFER_LENGTH 65536

// Maximum number of sectors for each read request

define MAX_CD_SECTORS_TO_READ ((MAX_BUFFER_LENGTH) / \

                            (CD_SECTOR_SIZE))

// Processor flags masks — use for testing wFlags member of RMCS

define CARRY_FLAG 0x0001

// Real-mode call structure for making DPMI Simulate Real Mode
// Interrupt calls.
typedef struct tagRMCS
{
DWORD edi, esi, ebp, RESERVED, ebx, edx, ecx, eax;
WORD wFlags, es, ds, fs, gs, ip, cs, sp, ss;
} RMCS, FAR* LPRMCS;

BOOL FAR PASCAL __export ReadCDRomSectors (BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpBuffer);

BOOL FAR PASCAL MSCDEX_ReadSector (BYTE bDrive,
DWORD dwStartSector,
LPBYTE RMlpBuffer);

BOOL FAR PASCAL SimulateRM_Int (BYTE bIntNum, LPRMCS lpCallStruct);
void FAR PASCAL BuildRMCS (LPRMCS lpCallStruct);

/*——————————————————————-
ReadCDRomSectors()

Reads a specified number of sectors from a CD-ROM.

Parameters:

 bDrive
    Drive letter of CD-ROM drive to read from. Specified as
    a character in the range 'A', 'B', 'C', ..., 'Z'.  May be
    upper- or lower-case.

 dwStartSector
    First sector to read.

 wSectors
    Number of sectors to read.

 lpBuffer
    Buffer to contain sector data. Must be large enough to
    accommodate all sectors being read. Since this buffer is
    provided by the calling Win32 application, no more than
    the first 64K bytes will be used.

Return Value
Returns TRUE if successful, or FALSE if an error occurred
in reading or if a parameter was invalid.
——————————————————————-*/

BOOL FAR PASCAL __export ReadCDRomSectors (BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpBuffer)
{
BOOL fResult;
DWORD cbOffset;
DWORD i;
DWORD gdaBuffer; // Return value of GlobalDosAlloc().
LPBYTE RMlpBuffer; // Real-mode buffer pointer
LPBYTE PMlpBuffer; // Protected-mode buffer pointer

// Convert drive letter into drive number for MSCDEX call.
bDrive = toupper(bDrive) – ‘A’;

/*
Validate parameters:
bDrive must be between 0 and 25, inclusive.
lpBuffer must not be NULL.
wSectors must be between 1 and the maximum number of
sectors that can fit into a 64K buffer, inclusive.
*/
if (bDrive > 25 || !lpBuffer)
return FALSE;

if (!wSectors || (wSectors > MAX_CD_SECTORS_TO_READ))
return FALSE;

/*
Allocate buffer for MSCDEX call. This buffer must be below 1MB
because the MSCDEX function will be called using DPMI. Like real-
mode MSCDEX.EXE, CDFS implements the MSCDEX API as V86-mode
Interrupt 2Fh functions.

  Free memory below 1MB is relatively scarce, so allocating a
  small sector buffer increases the chances that it can be
  allocated no matter how many other applications and MS-DOS
  device drivers are running. Also, a small sector buffer leaves
  more memory for other applications to use.

*/
gdaBuffer = GlobalDosAlloc (CD_SECTOR_SIZE);

if (!gdaBuffer)
return FALSE;

RMlpBuffer = (LPBYTE)MAKELONG(0, HIWORD(gdaBuffer));
PMlpBuffer = (LPBYTE)MAKELONG(0, LOWORD(gdaBuffer));

// Call MSCDEX to read each sector.
for (i = cbOffset = 0;
i < wSectors;
i++, cbOffset += CD_SECTOR_SIZE)
{
if (fResult = MSCDEX_ReadSector (bDrive,
dwStartSector + i,
RMlpBuffer))
_fmemcpy (lpBuffer + cbOffset, PMlpBuffer, CD_SECTOR_SIZE);
else
break;
}

GlobalDosFree (LOWORD(gdaBuffer));

return (fResult);
}

/*——————————————————————-
MSCDEX_ReadSector()

Calls MSCDEX to read a single sector from a CD-ROM compact disc.

Parameters:

 bDrive
    Drive number of CD-ROM drive to read from. Expected to be
    a number in the following series: 0 = A, 1 = B, 2 = C, etc.

 dwStartSector
    First sector of read.

 RMlpBuffer
    Real-mode segment:offset pointer to a buffer that will receive
    sector data. Must be large enough to accommodate a single
    sector in cooked mode.

Return Value
Returns TRUE if successful, or FALSE if an error occurred in
reading.
——————————————————————-*/

BOOL FAR PASCAL MSCDEX_ReadSector (BYTE bDrive,
DWORD dwStartSector,
LPBYTE RMlpBuffer)
{
RMCS callStruct;
BOOL fResult;

/*
Prepare DPMI Simulate Real Mode Interrupt call structure with
the register values used to make the MSCDEX Absolute read call.
Then, call MSCDEX using DPMI and check for errors in both the DPMI
call and the MSCDEX call.
*/
BuildRMCS (&callStruct);
callStruct.eax = 0x1508; // MSCDEX Absolute read
callStruct.ebx = LOWORD(RMlpBuffer); // Offset of sect buffer
callStruct.es = HIWORD(RMlpBuffer); // Segment of sect buffer
callStruct.ecx = bDrive; // 0=A, 1=B, 2=C, etc.
callStruct.edx = 1; // Read one sector
callStruct.esi = HIWORD(dwStartSector);
callStruct.edi = LOWORD(dwStartSector);

if (fResult = SimulateRM_Int (0x2F, &callStruct))
fResult = !(callStruct.wFlags & CARRY_FLAG);

return fResult;
}

/*——————————————————————-
SimulateRM_Int()

Allows protected-mode software to execute real-mode interrupts
such as calls to MS-DOS, MS-DOS TSRs, MS-DOS device drivers.

This function implements the “Simulate Real Mode Interrupt”
function of the DPMI specification v0.9 and later.

Parameters:

 bIntNum
    Number of the interrupt to simulate.

 lpCallStruct
    Call structure that contains params (register values)
    for bIntNum.

Return Value
SimulateRM_Int returns TRUE if it succeeded or FALSE if
it failed.

Comments
lpCallStruct is a protected-mode selector:offset address, not
a real-mode segment:offset address.
——————————————————————-*/

BOOL FAR PASCAL SimulateRM_Int (BYTE bIntNum, LPRMCS lpCallStruct)
{
BOOL fRetVal = FALSE; // Assume failure

_asm {
push di
mov ax, 0300h ; DPMI Simulate Real Mode Interrupt
mov bl, bIntNum ; Number of the interrupt to simulate
mov bh, 01h ; Bit 0 = 1; all other bits must be 0
xor cx, cx ; No words to copy from PM to RM stack
les di, lpCallStruct ; Real mode call structure
int 31h ; Call DPMI
jc END1 ; CF set if error occurred

     mov  fRetVal, TRUE
 END1:
     pop di
    }

return (fRetVal);
}

/*——————————————————————-
BuildRMCS()

Initializes a real-mode call structure by zeroing all its members.

Parameters:

  lpCallStruct
     Points to a real-mode call structure

Return Value
None.

Comments
lpCallStruct is a protected-mode selector:offset address,
not a real-mode segment:offset address.
——————————————————————-*/

void FAR PASCAL BuildRMCS (LPRMCS lpCallStruct)
{
_fmemset (lpCallStruct, 0, sizeof(RMCS));
}

  • You must to post comments
0
0

hmmm, interesting. So, could this code be used for DAE. Although, I think it would be difficult on a Win9x system unless they have the most current ASPI drivers.

  • You must to post comments
0
0

Yeah, that would be cool. The current CD functions of Fmod would be greatly improved.

  • You must to post comments
0
0

That’s something I’m waiting for since I’m using fmod (ok, so not too long ๐Ÿ˜‰ ) and it would be the reason for me to implent the cd-functions of fmod into my application :)

  • You must to post comments
Showing 8 results
Your Answer

Please first to submit.