palm-os-sdk/PalmOne/Samples/ExtendedSound/Src/RecordForm.c

972 lines
23 KiB
C

/***********************************************************************
*
* Copyright (c) 2002 Palm Computing, Inc. or its subsidiaries.
* All rights reserved.
*
***********************************************************************/
/***********************************************************************
*
* File:
* RecordForm.c
*
* Description:
* Record form implementation.
*
* Version 1.0 - Initial Revision (03/04/03)
*
***********************************************************************/
#include <PalmOS.h>
#include <VFSMgr.h>
#include <HsExt.h>
#include "Common.h"
#include "PalmSoundMgrExt.h"
#include "PalmSoundCustomCtrl.h"
#include "PlayForm.h"
#include "MyPlayer.h"
#include "MyPlayerRsc.h"
#include "Wave.h"
/***********************************************************************
*
* FUNCTION: SndStreamCallback
*
* DESCRIPTION: Sound callback for recording.
*
* PARAMETERS: userData - Pointer to user data.
* streamRef - Reference to the sound stream
* bufferP - Data buffer
* bufferSizeP - Pointer to the data buffer size
*
* RETURNED: errNone is the function succeeded.
*
***********************************************************************/
static Err SndStreamCallback(void *userDataP, SndStreamRef streamRef,
void *bufferP, UInt32 *bufferSizeP)
{
Err err = errNone;
UInt32 dataWritten = 0;
PlayerInfo *myPlayerInfoP = (PlayerInfo *)userDataP;
// We expect the user data to be valid
if( myPlayerInfoP == NULL ) {
err = -1; //
goto Done;
}
// Save the actual buffer size
myPlayerInfoP->actualSize = *bufferSizeP;
// This is the input section. We are going to receive buffer continually
// until the user presses the Stop button.
// The main error to check is a memory error since the device and the card
// don't have an unlimited amout of memory.
if( myPlayerInfoP->fileType == VFS_File ) {
err = VFSFileWrite(myPlayerInfoP->file.fileRef, *bufferSizeP, bufferP, &dataWritten);
} else {
dataWritten = FileWrite(myPlayerInfoP->file.fileHandle, bufferP, 1, *bufferSizeP, &err);
}
myPlayerInfoP->dataSize += dataWritten;
*bufferSizeP = dataWritten;
Done:
return err;
}
#if 0
#pragma mark -
#endif
/***********************************************************************
*
* FUNCTION: PrvOpenFile
*
* DESCRIPTION: Open a file
*
* PARAMETERS: recording - Trus if recording, false if playing
*
* RETURNED: Ture if succeeded.
*
***********************************************************************/
static Boolean PrvOpenFile()
{
Err err = errNone;
Char fullFilePath[256] = { NULL };
Boolean result = true;
// For VFS we need to recreate the full path of the file location
if(gPlayerInfo.fileType == VFS_File)
{
// Create the full path name for the file
StrPrintF(fullFilePath, "%s/%s", gPlayerInfo.directory, gPlayerInfo.fileName);
// Open file for writing, create and truncate options
err = VFSFileOpen(gPlayerInfo.volumeRef, fullFilePath, vfsModeWrite | vfsModeCreate | vfsModeTruncate, (FileRef *)&gPlayerInfo.file.fileRef);
}
// Memory file
else
{
// Open file for writing, create and truncate options
gPlayerInfo.file.fileHandle = FileOpen(0, gPlayerInfo.fileName, sysFileTFileStream, 0, fileModeReadWrite, &err);
}
// Check for errors
if(err != errNone)
{
result = false;
// Since the handle might not be null when
// an error occurs always fix it.
gPlayerInfo.file.fileHandle = NULL;
StrPrintF(gErrorCode, "Error code: %x", err);
FrmCustomAlert(RecordErrorAlert, "Error opening the file.", (Char*)gErrorCode, NULL);
}
return result;
}
/***********************************************************************
*
* FUNCTION: PrvCloseFile
*
* DESCRIPTION: Close a file
*
* PARAMETERS: -
*
* RETURNED: Ture if succeeded.
*
***********************************************************************/
static Boolean PrvCloseFile()
{
Err err = errNone;
Boolean result = true;
if(gPlayerInfo.fileType == VFS_File) {
if(gPlayerInfo.file.fileRef)
err = VFSFileClose(gPlayerInfo.file.fileRef);
} else {
if(gPlayerInfo.file.fileHandle)
err = FileClose(gPlayerInfo.file.fileHandle);
}
if(err) {
StrPrintF(gErrorCode, "Error code: %x", err);
FrmCustomAlert(RecordErrorAlert, "Error closing the file.", (Char*)gErrorCode, NULL);
result = false;
}
return result;
}
/***********************************************************************
*
* FUNCTION: PrvStartStream
*
* DESCRIPTION: Called when record is starting.
* 1) Open a file
* 2) Create a stream
* 3) Set the custom control(s)
* 4) Write a pseudo wave header
* 5) Start the stream
*
* PARAMETERS: frmP - Form pointer.
*
* RETURNED: True if succeeded.
*
***********************************************************************/
static Boolean PrvStartStream(FormType *frmP)
{
Err err = errNone;
Boolean result = true;
FieldType *fieldP = FrmGetPtr(frmP, RecordFileField);
Char *fileName = FldGetTextPtr(fieldP);
if( *fileName == NULL ) {
err = -1;
StrCopy(gErrorCode, "Error code: NULL Pointer");
FrmCustomAlert(RecordErrorAlert, "File name cannot be null.", (Char*)gErrorCode, NULL);
goto Done;
}
// Copy the current field to the file name
StrCopy(gPlayerInfo.fileName, FldGetTextPtr(fieldP));
// Read the buffer size
fieldP = FrmGetPtr(frmP, RecordBufferField);
gPlayerInfo.bufferSize = StrAToI(FldGetTextPtr(fieldP));
gPlayerInfo.dataSize = 0;
// Tell the callback the stream direction
gPlayerInfo.streamMode = sndInput;
// 1. Open a file for recording
result = PrvOpenFile();
if(!result)
goto Done;
// 2. Create the stream
err = SndStreamCreateExtended( &gPlayerInfo.streamRef,
gPlayerInfo.streamMode,
gPlayerInfo.streamFormat,
gPlayerInfo.sampleRate,
(gPlayerInfo.streamFormat==sndFormatIMA_ADPCM)?0:gPlayerInfo.sampleType,
gPlayerInfo.streamWidth,
&SndStreamCallback,
&gPlayerInfo,
gPlayerInfo.bufferSize,
false);
// Check for errors
if(err != errNone) {
StrPrintF(gErrorCode, "Error code: %x", err);
FrmCustomAlert(RecordErrorAlert, "Error creating the stream.", (Char*)gErrorCode, NULL);
goto Done;
}
// The volume
err = SndStreamSetVolume(gPlayerInfo.streamRef, gPlayerInfo.streamVolume);
if(err != errNone) {
StrPrintF(gErrorCode, "Error code: %x", err);
FrmCustomAlert(RecordErrorAlert, "Error setting the volume of the stream.", (Char*)gErrorCode, NULL);
goto Done;
}
// 3. Custom Control
if(gPlayerInfo.streamFormat==sndFormatIMA_ADPCM)
{
SndCodecCustomControlType ct;
UInt16 blockAlign = 0;
UInt32 numChannels = (gPlayerInfo.streamWidth == sndMono) ? 1 : 2;
UInt16 blockSize = 256 * numChannels;
switch(gPlayerInfo.sampleRate)
{
case 8000:
case 11025:
case 16000:
break;
case 22050:
blockSize *= 2;
break;
case 32000:
case 44100:
FrmAlert(FrequencyAlert);
err = 1;
goto Done;
}
blockAlign = Swap16(blockSize);
ct.apiCreator = Swap32(codecDriverIMAADPCM);
ct.apiSelector = Swap32(codecIMAADPCMSetBlockSize);
ct.valueP = (void*)Swap32(&blockAlign);
ct.valueLenP = NULL;
err = SndStreamDeviceControl(gPlayerInfo.streamRef, sndControlCodecCustomControl, &ct, sizeof(ct));
if(err) {
StrPrintF(gErrorCode, "Error code: %x", err);
FrmCustomAlert(RecordErrorAlert, "Error setting the stream custom control.", (Char*)gErrorCode, NULL);
goto Done;
}
}
// 4. Reserve some space for the WAVE header
if(gPlayerInfo.streamFormat==sndFormatIMA_ADPCM) {
err = WriteADPCM_WAVEHeader(&gPlayerInfo);
} else {
err = WritePCM_WAVEHeader(&gPlayerInfo);
}
// 5. Start the stream
err = SndStreamStart(gPlayerInfo.streamRef);
if(err)
{
StrPrintF(gErrorCode, "Error code: %x", err);
FrmCustomAlert(RecordErrorAlert, "Error while staring the stream.", (Char*)gErrorCode, NULL);
goto Done;
}
Done:
if(err) {
// Close the file
PrvCloseFile();
// Delete the stream is needed
if(gPlayerInfo.streamRef)
SndStreamDelete(gPlayerInfo.streamRef);
result = false;
}
return result;
}
/***********************************************************************
*
* FUNCTION: PrvStopStream
*
* DESCRIPTION: Stop the current stream and close the open file.
*
* PARAMETERS: -
*
* RETURNED: -
*
***********************************************************************/
static void PrvStopStream()
{
Err err = errNone;
// Stop the stream
err = SndStreamStop(gPlayerInfo.streamRef);
if(err) {
gPlayerInfo.playerState = IDLE_REC;
StrPrintF(gErrorCode, "Error code: %x", err);
FrmCustomAlert(RecordErrorAlert, "Error stopping the stream.", (Char*)gErrorCode, NULL);
}
// Delete the stream
err = SndStreamDelete(gPlayerInfo.streamRef);
if(err) {
gPlayerInfo.playerState = IDLE_REC;
StrPrintF(gErrorCode, "Error code: %x", err);
FrmCustomAlert(RecordErrorAlert, "Error deleting the stream.", (Char*)gErrorCode, NULL);
}
// Rewind the file and write the real header
if(gPlayerInfo.fileType == VFS_File) {
err = VFSFileSeek(gPlayerInfo.file.fileRef, vfsOriginBeginning, 0);
} else {
err = FileSeek(gPlayerInfo.file.fileHandle, 0, fileOriginBeginning);
}
// Write WAVE header
if(gPlayerInfo.streamFormat==sndFormatIMA_ADPCM) {
err = WriteADPCM_WAVEHeader(&gPlayerInfo);
} else {
err = WritePCM_WAVEHeader(&gPlayerInfo);
}
// Close the file
PrvCloseFile();
}
#if 0
#pragma mark -
#endif
/***********************************************************************
*
* FUNCTION: PrvChangeBufferSizeField
*
* DESCRIPTION: Set the buffer size text field.
*
* PARAMETERS: frmP - Pointer to a form
* size - The buffer size
*
* RETURNED: -
*
***********************************************************************/
/*
static void PrvChangeBufferSizeField(FormType *frmP, UInt32 size)
{
static Char bufferSizeText[10] = { NULL };
// Simply convert the size parameter to a string and display it
FieldType *fieldP = FrmGetPtr(frmP, RecordBufferField);
if( fieldP ) {
StrIToA(bufferSizeText, size);
SetFieldTextFromStr(fieldP, bufferSizeText, true);
}
}
*/
/***********************************************************************
*
* FUNCTION: PrvBlinkPause
*
* DESCRIPTION: Flash the current track time when in pause mode.
*
* PARAMETERS: frmP - Pointer to the current active form
*
* RETURNED: -
*
***********************************************************************/
static void PrvBlinkPause(FormType *frmP)
{
UInt16 seconds, minutes;
Char time[10] = { NULL };
FieldType* fieldP = FrmGetPtr(frmP, RecordTimeField);
// Blink only if enough time ellapsed
if( (TimGetTicks() - gPreviousBlinkTime) > kBlinkTime)
{
gPreviousBlinkTime = TimGetTicks();
// Two states: time on/timeoff
if(gBlinkState)
{
seconds = gCurrentTime / sysTicksPerSecond;
minutes = seconds / 60;
seconds = seconds - (minutes * 60);
StrPrintF(time, "%02d:%02d", minutes, seconds);
SetFieldTextFromStr(fieldP, time, true);
}
else
{
SetFieldTextFromStr(fieldP, "", true);
}
gBlinkState = 1 - gBlinkState; // Switch flag
}
}
/***********************************************************************
*
* FUNCTION: PrvRefreshUI
*
* DESCRIPTION: Refresh the current time and actual buffer.
*
* PARAMETERS: frmP - Pointer to the current active form
*
* RETURNED: -
*
***********************************************************************/
static void PrvRefreshUI(FormType *frmP)
{
UInt16 seconds, minutes;
Char time[10] = { NULL };
// Refresh the time
FieldType* fieldP = FrmGetPtr(frmP, RecordTimeField);
if(fieldP) {
seconds = gCurrentTime / sysTicksPerSecond;
minutes = seconds / 60;
seconds = seconds - (minutes * 60);
StrPrintF(time, "%02d:%02d", minutes, seconds);
SetFieldTextFromStr(fieldP, time, true);
}
// Refresh the actual buffer size
fieldP = FrmGetPtr(frmP, RecordActualField);
if(fieldP) {
if( gPlayerInfo.actualSize ) {
StrIToA(time, gPlayerInfo.actualSize);
SetFieldTextFromStr(fieldP, time, true);
} else {
SetFieldTextFromStr(fieldP, "-", true);
}
}
}
/***********************************************************************
*
* FUNCTION: PrvSetButtonBitmaps
*
* DESCRIPTION: Changes the button bitmaps depending on player state.
*
* PARAMETERS: frmP - Form pointer.
*
* RETURNED: -
*
***********************************************************************/
static void PrvSetButtonBitmaps(FormType *frmP)
{
// Change the button icon
ControlType* controlP = FrmGetPtr(frmP, RecordRecordGraphicButton);
if( controlP )
{
switch(gPlayerInfo.playerState)
{
case IDLE_REC:
CtlSetGraphics(controlP, RecordBitmapFamily, RecordSelectedBitmapFamily);
break;
case PAUSED_REC:
CtlSetGraphics(controlP, RecordBitmapFamily, RecordSelectedBitmapFamily);
break;
case RECORDING:
CtlSetGraphics(controlP, PauseBitmapFamily, PauseSelectedBitmapFamily);
break;
default:
break;
}
}
}
/***********************************************************************
*
* FUNCTION: PrvRecordButtonPressed
*
* DESCRIPTION: Handles the player states when record is pressed.
*
* PARAMETERS: frmP - Form pointer.
*
* RETURNED: -
*
***********************************************************************/
static void PrvRecordButtonPressed(FormType *frmP)
{
Err err = errNone;
// State Machine for Record button
switch(gPlayerInfo.playerState)
{
case IDLE_REC:
if( PrvStartStream(frmP) )
{
gPlayerInfo.playerState = RECORDING;
gStartTime = TimGetTicks();
gCurrentTime = 0;
gPreviousRun = 0;
}
break;
case PAUSED_REC:
// Resume the stream
err = SndStreamPause(gPlayerInfo.streamRef, false);
if(err) {
gPlayerInfo.playerState = IDLE_REC;
StrPrintF(gErrorCode, "Error code: %x", err);
FrmCustomAlert(RecordErrorAlert, "Error resuming the stream.", (Char*)gErrorCode, NULL);
} else {
gPlayerInfo.playerState = RECORDING;
gStartTime = TimGetTicks();
gPreviousRun = gCurrentTime;
}
break;
case RECORDING:
// Pause the stream
err = SndStreamPause(gPlayerInfo.streamRef, true);
if(err) {
gPlayerInfo.playerState = IDLE_REC;
StrPrintF(gErrorCode, "Error code: %x", err);
FrmCustomAlert(RecordErrorAlert, "Error pausing the stream.", (Char*)gErrorCode, NULL);
} else {
gPlayerInfo.playerState = PAUSED_REC;
gBlinkState = 0;
}
break;
default:
gPlayerInfo.playerState = IDLE_REC;
break;
}
// Quick refresh
PrvRefreshUI(frmP);
PrvSetButtonBitmaps(frmP);
}
/***********************************************************************
*
* FUNCTION: PrvStopButtonPressed
*
* DESCRIPTION: Handles the player states when stop is pressed.
*
* PARAMETERS: frmP - Form pointer.
*
* RETURNED: -
*
***********************************************************************/
static void PrvStopButtonPressed(FormType *frmP)
{
// Reset some values
gCurrentTime = 0;
gPreviousRun = 0;
gPlayerInfo.actualSize = 0;
// State machine for Stop button
switch(gPlayerInfo.playerState)
{
case IDLE_REC:
gPlayerInfo.playerState = IDLE_REC;
break;
case PAUSED_REC:
case RECORDING:
gPlayerInfo.playerState = IDLE_REC;
PrvStopStream();
// Change state
FrmGotoForm(PlayForm);
break;
default:
break;
}
// Quick refresh
PrvRefreshUI(frmP);
PrvSetButtonBitmaps(frmP);
}
/***********************************************************************
*
* FUNCTION: PrvHandleNilEvent
*
* DESCRIPTION: Handles nil events. We will refresh the record/play time.
*
* PARAMETERS: frmP - Form pointer.
*
* RETURNED: -
*
***********************************************************************/
static void PrvHandleNilEvent(FormType *frmP)
{
switch(gPlayerInfo.playerState)
{
case IDLE_REC:
break;
case PAUSED_REC:
// Blink the current time
PrvBlinkPause(frmP);
break;
case RECORDING:
// Refresh the time
gCurrentTime = TimGetTicks() - gStartTime + gPreviousRun;
PrvRefreshUI(frmP);
break;
default:
break;
}
}
/***********************************************************************
*
* FUNCTION: PrvPlayerFormShowMenu
*
* DESCRIPTION: Display the player menu.
*
* PARAMETERS: command - Menu to handle
*
* RETURNED: True if handled
*
***********************************************************************/
static Boolean PrvPlayerFormShowMenu(UInt16 command)
{
Boolean handled = false;
UInt16 cardNo;
LocalID dbID;
DmSearchStateType searchState;
DmGetNextDatabaseByTypeCreator(true, &searchState, sysFileTApplication,
appCreatorID, true, &cardNo, &dbID);
switch (command)
{
case RecordOptionsAbout:
MenuEraseStatus(0);
HsAboutHandspringApp(cardNo, dbID, "2006", "Palm DTS Team");
handled = true;
break;
case RecordOptionsPlay:
FrmGotoForm(PlayForm);
handled = true;
break;
}
return handled;
}
#if 0
#pragma mark -
#endif
/***********************************************************************
*
* FUNCTION: RecordFormInit
*
* DESCRIPTION: Form initialiser.
*
* PARAMETERS: frmP - Pointer to a form
*
* RETURNED: -
*
***********************************************************************/
static void RecordFormInit(FormType *frmP)
{
FieldType *fieldP = NULL;
ControlType *controlP = NULL;
ListType *listP = NULL;
UInt16 listPosition = 0;
Char text[10];
// Initialize the default file string
if( !*gPlayerInfo.fileName )
StrCopy(gPlayerInfo.fileName, "default.wav");
fieldP = FrmGetPtr(frmP, RecordFileField);
if( fieldP )
SetFieldTextFromStr(fieldP, gPlayerInfo.fileName, false);
// Initialize the default buffer size
StrIToA(text, gPlayerInfo.bufferSize);
fieldP = FrmGetPtr(frmP, RecordBufferField);
if( fieldP )
SetFieldTextFromStr(fieldP, text, false);
// Initialize the actual buffer size
fieldP = FrmGetPtr(frmP, RecordActualField);
if( fieldP )
SetFieldTextFromStr(fieldP, "-", false);
// Initialize the default time
fieldP = FrmGetPtr(frmP, RecordTimeField);
if( fieldP )
SetFieldTextFromStr(fieldP, "00:00", false);
// Initialize the file location field (since we might come from the record form)
controlP = FrmGetPtr(frmP, RecordLocationPopTrigger);
listP = FrmGetPtr(frmP, RecordLocationList);
if( controlP && listP ) {
CtlSetLabel(controlP, LstGetSelectionText(listP, gPlayerInfo.fileType));
LstSetSelection(listP, gPlayerInfo.fileType);
}
// Initialize the stream width (mono/stereo)
controlP = FrmGetPtr(frmP, RecordModePopTrigger);
listP = FrmGetPtr(frmP, RecordModeList);
if( controlP && listP ) {
listPosition = (gPlayerInfo.streamWidth==sndMono)?0:1;
CtlSetLabel(controlP, LstGetSelectionText(listP, listPosition));
LstSetSelection(listP, listPosition);
}
// Initialize the sample type
controlP = FrmGetPtr(frmP, RecordSampleTypePopTrigger);
listP = FrmGetPtr(frmP, RecordSampleTypeList);
if( controlP && listP ) {
listPosition = (gPlayerInfo.sampleType==sndUInt8)?0:1;
CtlSetLabel(controlP, LstGetSelectionText(listP, listPosition));
LstSetSelection(listP, listPosition);
}
// Initialize the format
controlP = FrmGetPtr(frmP, RecordEncodingPopTrigger);
listP = FrmGetPtr(frmP, RecordEncodingList);
if( controlP && listP ) {
listPosition = (gPlayerInfo.streamFormat==sndFormatPCM)?0:1;
CtlSetLabel(controlP, LstGetSelectionText(listP, listPosition));
LstSetSelection(listP, listPosition);
}
// Initialize the sample rate
controlP = FrmGetPtr(frmP, RecordSampleRatePopTrigger);
listP = FrmGetPtr(frmP, RecordSampleRateList);
if( controlP && listP ) {
switch(gPlayerInfo.sampleRate) {
case 8000:
listPosition = 0;
break;
case 11025:
listPosition = 1;
break;
case 16000:
listPosition = 2;
break;
case 22050:
listPosition = 3;
break;
case 32000:
listPosition = 4;
break;
case 44100:
listPosition = 5;
break;
}
CtlSetLabel(controlP, LstGetSelectionText(listP, listPosition));
LstSetSelection(listP, listPosition);
}
// Initialize the volume
controlP = FrmGetPtr(frmP, RecordVolumeFeedbackSliderControl);
if( controlP ) {
UInt16 value = 0;
UInt16 minValue = 0, maxValue = 0;
CtlGetSliderValues(controlP, &minValue, &maxValue, NULL, NULL);
value = (gPlayerInfo.streamVolume * (maxValue - minValue)) >> 11;
CtlSetValue(controlP, value);
}
// Set the intial state
gPlayerInfo.playerState = IDLE_REC;
}
/***********************************************************************
*
* FUNCTION: RecordFormDeInit
*
* DESCRIPTION: Form de-initialiser.
*
* PARAMETERS: frmP - Pointer to a form
*
* RETURNED: -
*
***********************************************************************/
static void RecordFormDeInit(FormType *frmP)
{
// Check the current player state
switch(gPlayerInfo.playerState)
{
case PAUSED_REC:
case RECORDING:
PrvStopStream();
break;
default:
break;
}
}
/***********************************************************************
*
* FUNCTION: RecordFormHandleEvent
*
* DESCRIPTION: Form event handler.
*
* PARAMETERS: eventP - Pointer to an event
*
* RETURNED: True if event was handled.
*
***********************************************************************/
Boolean RecordFormHandleEvent(EventType *eventP)
{
Boolean handled = false;
FormType *frmP = FrmGetActiveForm();
switch(eventP->eType)
{
//
// Display the menu
//
case menuEvent:
handled = PrvPlayerFormShowMenu(eventP->data.menu.itemID);
PrvRefreshUI(frmP);
PrvSetButtonBitmaps(frmP);
break;
//
// Handle the form open events
//
case frmOpenEvent:
RecordFormInit(frmP);
FrmDrawForm(frmP);
handled = true;
break;
//
// Handle the form close event
//
case frmCloseEvent:
RecordFormDeInit(frmP);
break;
//
// Handle the control select events
//
case ctlSelectEvent:
switch(eventP->data.ctlSelect.controlID)
{
case RecordRecordGraphicButton:
PrvRecordButtonPressed(frmP);
handled = true;
break;
case RecordStopGraphicButton:
PrvStopButtonPressed(frmP);
handled = true;
break;
default:
break;
}
break;
//
// Handle the pop-up trigger event
//
case popSelectEvent:
switch(eventP->data.popSelect.controlID)
{
case RecordLocationPopTrigger:
gPlayerInfo.fileType = gUIFileTypeTable[eventP->data.popSelect.selection];
break;
case RecordModePopTrigger:
gPlayerInfo.streamWidth = gUIStreamModeTable[eventP->data.popSelect.selection];
break;
case RecordEncodingPopTrigger:
gPlayerInfo.streamFormat = gUIStreamFormatTable[eventP->data.popSelect.selection];
break;
case RecordSampleTypePopTrigger:
gPlayerInfo.sampleType = gUISampleTypeTable[eventP->data.popSelect.selection];
break;
case RecordSampleRatePopTrigger:
gPlayerInfo.sampleRate = gUISampleRateTable[eventP->data.popSelect.selection];
break;
case RecordFormPopTrigger:
if( eventP->data.popSelect.selection )
FrmGotoForm(PlayForm);
break;
default:
break;
}
break;
//
// Handle control repeat event
//
case ctlRepeatEvent:
switch(eventP->data.ctlRepeat.controlID)
{
case RecordVolumeFeedbackSliderControl:
{
UInt16 minValue = 0, maxValue = 0;
CtlGetSliderValues(eventP->data.ctlRepeat.pControl, &minValue, &maxValue, NULL, NULL);
gPlayerInfo.streamVolume = ((UInt32)eventP->data.ctlRepeat.value << 11) / (maxValue - minValue);
if( gPlayerInfo.streamRef ) {
SndStreamSetVolume(gPlayerInfo.streamRef, gPlayerInfo.streamVolume);
}
break;
}
}
break;
//
// Handle NilEvent
//
case nilEvent:
PrvHandleNilEvent(frmP);
handled = true;
break;
default:
break;
}
return handled;
}