Directsound Study Notes (7): Buffer operation

Source: Internet
Author: User

Fill and play static buffer

Loading data into a static buffer involves three steps:
1. Use idirectsoundbuffer8: Lock to lock the entire buffer zone. You specify the offset location (usually 0) in the buffer and return the memory address of the point.
2. Use standard memory copyProgramWrite the audio data to the returned address.
3. Use idirectsoundbuffer8: Unlock to unlock the buffer zone.

The following example shows these steps. lpdsbstatic is an idirectsoundbuffer8 interface pointer, and pbdata is a data source address:

Lpvoid lpvwrite;
DWORD dwlength;

If (Ds_ OK = Lpdsbstatic -> Lock (
0 , // Offset at which to start lock.
0 , // Size of lock; ignored because of flag.
& Lpvwrite, // Gets address of first part of lock.
& Dwlength, // Gets size of first part of lock.
Null, // Address of wraparound not needed.
Null, // Size of wraparound not needed.
Dsblock_entirebuffer )) // Flag.
{
Memcpy (lpvwrite, pbdata, dwlength );
Lpdsbstatic -> Unlock (
Lpvwrite, // Address of lock start.
Dwlength, // Size of lock.
Null, // No wraparound portion.
0 ); // No wraparound size.
}
Else
(
Errorhandler (); // Add error-handling here.
}

Call idirectsoundbuffer8: play buffer, as shown in the following example:

Lpdsbstatic -> Setcurrentposition ( 0 );
Hresult HR = Lpdsbstatic -> Play (
0 , // Unused.
0 , // Priority for voice management.
0 ); // Flags.
If (Failed (HR ))
(
Errorhandler (); // Add error-handling here.
}

Because the dsbplay_looping ID is not set in this example, the playback stops automatically when the buffer reaches the end. You can also use idirectsoundbuffer8: Stop to stop it too early. When you stop a buffer too early, the position of the playback pointer remains there. In this example, call idirectsoundbuffer8: setcurrentposition to ensure that the buffer is played from the starting position.

Use Stream Buffer

When playing a long sound segment in a stream buffer zone, you cannot load all the sound into the buffer zone at a time. When playing in the buffer zone, old data is periodically replaced by new data. Call the idirectsoundbuffer8: Play method to play the stream buffer, and set the dsflags parameter to dsbplay_looping. Call the idirectsoundbuffer8: Stop method to stop playing. This method immediately stops the buffer, so you need to ensure that all data has been played. This can be achieved by checking the playback position in turn or setting the notification position.

The following steps are required to flow into a buffer:
1. Determine whether the buffer zone is ready to receive new data. This can be achieved by checking the playback pointer in turn or waiting for notifications.
2. Use idirectsoundbuffer8: Lock to lock part of the buffer. This method returns one or two addresses from which data can be immediately written.
3. Use the standard memory copy program to write the audio data to the returned address.
4. Use idirectsoundbuffer8: Unlock to unlock the buffer zone.
Idirectsoundbuffer8: lock may return two addresses because you can lock any number of bytes up to the buffer size and ignore the starting point. For example, assume that you start locking 30 000 bytes at the 20 000 bytes of a 40 000 bytes buffer. At this time, you must perform two independent memory copies.

Although the entire buffer zone can be locked, you cannot do this during buffer playback. Generally, you only update a small part of the buffer at a time. For example, when the playback pointer reaches 2/4 of the buffer, you can lock 1/4 of the buffer and write data. You can never write the buffer between the playback pointer and the write pointer.

The following function writes data to a sound buffer. The starting position is passed in by dwoffset:

Bool appwritedatatobuffer (
Lpdirectsoundbuffer8 lpdsb, // The buffer.
DWORD dwoffset, // Our own write cursor.
Lpbyte lpbsounddata, // Start of our data.
DWORD dwsoundbytes) // Size of block to copy.
{
Lpvoid lpvptr1;
DWORD dwbytes1;
Lpvoid lpvptr2;
DWORD dwbytes2;
Hresult hr;
 
// Obtain memory address of write block. This will be in two parts
// If the block wraps around.
 
HR = Lpdsb -> Lock (dwoffset, dwsoundbytes, & Lpvptr1,
& Dwbytes1, & Lpvptr2, & Dwbytes2, 0 );
 
// If the buffer was lost, restore and retry lock.
 
If (Dserr_bufferlost = HR)
{
Lpdsb -> Restore ();
HR = Lpdsb -> Lock (dwoffset, dwsoundbytes,
& Lpvptr1, & Dwbytes1,
& Lpvptr2, & Dwbytes2, 0 );
}  
If (Succeeded (HR ))
{
// Write to pointers.
 
Copymemory (lpvptr1, lpbsounddata, dwbytes1 );
If (Null ! = Lpvptr2)
{
Copymemory (lpvptr2, lpbsounddata+Dwbytes1, dwbytes2 );
}  
 
// Release the data back to directsound.
 
HR = Lpdsb -> Unlock (lpvptr1, dwbytes1, lpvptr2,
Dwbytes2 );
If (Succeeded (HR ))
{
//Success.
ReturnTrue;
}  
}  
 
// Lock, unlock, or restore failed.
 
Return False;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.