~ubuntu-branches/ubuntu/trusty/psychtoolbox-3/trusty-proposed

« back to all changes in this revision

Viewing changes to PsychSourceGL/Source/Common/PsychPortAudio/PsychPortAudio.c

  • Committer: Package Import Robot
  • Author(s): Yaroslav Halchenko
  • Date: 2013-11-19 23:34:50 UTC
  • mfrom: (3.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20131119233450-f7nf92vb8qavjmk8
Tags: 3.0.11.20131017.dfsg1-3
Upload to unsable since fresh glew has arrived to sid!

Show diffs side-by-side

added added

removed removed

Lines of Context:
188
188
unsigned int  audiodevicecount = 0;
189
189
unsigned int  verbosity = 4;
190
190
double        yieldInterval = 0.001;            // How long to wait in calls to PsychYieldIntervalSeconds().
191
 
psych_bool    uselocking = TRUE;                // Use Mutex locking and signalling code for thread synchronization?
192
 
psych_bool    lockToCore1 = TRUE;               // Lock all engine threads to run on cpu core 1 on Windows to work around broken TSC sync on multi-cores?
 
191
psych_bool    uselocking = TRUE;                // Use Mutex locking and signalling code for thread synchronization?
 
192
psych_bool    lockToCore1 = TRUE;               // NO LONGER USED: Lock all engine threads to run on cpu core 1 on Windows to work around broken TSC sync on multi-cores?
193
193
psych_bool    pulseaudio_autosuspend = TRUE;    // Should we try to suspend the Pulseaudio sound server on Linux while we're active?
194
194
psych_bool    pulseaudio_isSuspended = FALSE;   // Is PulseAudio suspended by us?
195
195
 
758
758
        psych_int64  playposition, outsbsize, insbsize, recposition;
759
759
        psych_int64  outsboffset;
760
760
        unsigned int reqstate;
761
 
        double now, firstsampleonset, onsetDelta, offsetDelta, captureStartTime, tMonotonic;
 
761
        double now, firstsampleonset, onsetDelta, offsetDelta, captureStartTime;
762
762
        double repeatCount;     
763
763
        psych_int64 playpositionlimit;
764
764
        PaHostApiTypeId hA;
797
797
                // the audio thread to cpu core 1, hope that repeated redundant
798
798
                // calls don't create scheduling overhead or excessive other overhead.
799
799
                // The explanation for this can be found in Source/Windows/Base/PsychTimeGlue.c
800
 
                if (lockToCore1) SetThreadAffinityMask(GetCurrentThread(), 1);
 
800
        //
 
801
        // Update: We leave the decision to the time glue if we should lock to core zero,
 
802
        // or some other usercode defined subset of cores, or all cores. PsychAutoLockThreadToCores()
 
803
                // Update: No longer needed, as the job is done implicitely by the call to 
 
804
        // PsychGetAdjustedPrecisionTimerSeconds(&now);
 
805
        //
 
806
        // DISABLED: PsychAutoLockThreadToCores(NULL);
801
807
#endif
802
808
                
803
809
                // Retrieve current system time:
820
826
                        // further processing.
821
827
 
822
828
                        // Get current CLOCK_MONOTONIC time:
823
 
                        tMonotonic = PsychOSGetLinuxMonotonicTime();
 
829
                        double tMonotonic = PsychOSGetLinuxMonotonicTime();
824
830
                        
825
831
                        // Returned current time timestamp closer to tMonotonic than to GetSecs time?
826
832
                        if (fabs(timeInfo->currentTime - tMonotonic) < fabs(timeInfo->currentTime - now)) {
939
945
        // sound content (ie., not simply zero silence padding frames):
940
946
        committedFrames = 0;
941
947
 
 
948
    // Reset number of silence frames so far:
 
949
    silenceframes = 0;
 
950
    
942
951
        // NULL-out pointer to buffer with sound data to play. It will get initialized later on
943
952
        // in PsychPAProcessSchedule():
944
953
        playoutbuffer = NULL;
966
975
        // Assign 1 as neutral value for AM modulator slaves, as 1 is the neutral
967
976
        // element for gain-modulation (multiplication), as opposed to zero as neutral
968
977
        // element for mixing and for outputting "silence":
969
 
        neutralValue = (dev->opmode & kPortAudioIsAMModulator) ? 1.0 : 0;
 
978
        neutralValue = (dev->opmode & kPortAudioIsAMModulator) ? 1.0f : 0.0f;
970
979
 
971
980
        // Requested logical playback state is "stopped" or "aborting" ? If so, abort.
972
981
        if ((reqstate == 0) || (reqstate == 3)) {               
988
997
                PsychPAUnlockDeviceMutex(dev);
989
998
                
990
999
                // Prime the outputbuffer with silence, so playback is effectively stopped:
991
 
                if (outputBuffer && !isSlave) memset(outputBuffer, 0, (size_t) framesPerBuffer * outchannels * sizeof(float));
 
1000
                if (outputBuffer && !isSlave) memset(outputBuffer, 0, (size_t) (framesPerBuffer * outchannels * sizeof(float)));
992
1001
 
993
1002
                if (dev->runMode == 0) {
994
1003
                        // Runmode 0: We shall really stop the engine:
1019
1028
                PsychPAUnlockDeviceMutex(dev);
1020
1029
                
1021
1030
                // Prime the outputbuffer with silence to simulate a stopped audio device:
1022
 
                if (outputBuffer && !isSlave) memset(outputBuffer, 0, (size_t) framesPerBuffer * outchannels * sizeof(float));
 
1031
                if (outputBuffer && !isSlave) memset(outputBuffer, 0, (size_t) (framesPerBuffer * outchannels * sizeof(float)));
1023
1032
 
1024
1033
                // Done:
1025
1034
                return(paContinue);
1084
1093
                                PsychPAUnlockDeviceMutex(dev);
1085
1094
                                
1086
1095
                                // At least one buffer away. Fill our buffer with zeros, aka silence:
1087
 
                                if (!isSlave) memset(outputBuffer, 0, (size_t) framesPerBuffer * outchannels * sizeof(float));
 
1096
                                if (!isSlave) memset(outputBuffer, 0, (size_t) (framesPerBuffer * outchannels * sizeof(float)));
1088
1097
                                
1089
1098
                                // Ready. Tell engine to continue stream processing, i.e., call us again...
1090
1099
                                return(paContinue);
1097
1106
                                // Fill in some silence:
1098
1107
                                if (neutralValue == 0) {
1099
1108
                                        // Fast-path: Zerofill for silence...
1100
 
                                        memset(outputBuffer, 0, (size_t) silenceframes * outchannels * sizeof(float));
 
1109
                                        memset(outputBuffer, 0, (size_t) (silenceframes * outchannels * sizeof(float)));
1101
1110
                                        out+= (silenceframes * outchannels);
1102
1111
                                }
1103
1112
                                else {
1143
1152
                // Scratch buffers for slave callbacks already allocated?
1144
1153
                if ((dev->opmode & kPortAudioCapture) && (dev->slaveInBuffer == NULL)) {
1145
1154
                        // Allocate input distribution buffer:
1146
 
                        dev->slaveInBuffer = (float*) malloc(sizeof(float) * dev->batchsize * inchannels);
 
1155
                        dev->slaveInBuffer = (float*) malloc(sizeof(float) * (size_t) (dev->batchsize * inchannels));
1147
1156
                        if (NULL == dev->slaveInBuffer) {
1148
1157
                                // Out of memory! Perform an emergency abort:
1149
1158
                                dev->reqstate = 255;
1156
1165
 
1157
1166
                if ((dev->opmode & kPortAudioPlayBack) && (dev->slaveOutBuffer == NULL)) {
1158
1167
                        // Allocate output receive buffer and output gain receive buffer:
1159
 
                        dev->slaveOutBuffer = (float*) malloc(sizeof(float) * dev->batchsize * outchannels);
1160
 
                        dev->slaveGainBuffer = (float*) malloc(sizeof(float) * dev->batchsize * outchannels);
 
1168
                        dev->slaveOutBuffer = (float*) malloc(sizeof(float) * (size_t) (dev->batchsize * outchannels));
 
1169
                        dev->slaveGainBuffer = (float*) malloc(sizeof(float) * (size_t) (dev->batchsize * outchannels));
1161
1170
                        if ((NULL == dev->slaveOutBuffer) || (NULL == dev->slaveGainBuffer)) {
1162
1171
                                // Out of memory! Perform an emergency abort:
1163
1172
                                dev->reqstate = 255;
1169
1178
                }
1170
1179
 
1171
1180
                // Have scratch buffers ready. Clear output intermix buffer:
1172
 
                memset(outputBuffer, 0, dev->batchsize * outchannels * sizeof(float));
 
1181
                memset(outputBuffer, 0, (size_t) (dev->batchsize * outchannels * sizeof(float)));
1173
1182
 
1174
1183
                // Iterate over all slave device callbacks: Or at least until all registered slaves are handled.
1175
1184
                numSlavesHandled = 0;
1357
1366
        // This code only executes on non-masters in live monitoring mode - a mode where all
1358
1367
        // sound data is fed back immediately with shortest possible latency
1359
1368
        // from input to output, without any involvement of Matlab/Octave code:
 
1369
        // Note: "Non-master" also means: A standard sound device without any slaves!
1360
1370
        if (!isMaster && (dev->opmode & kPortAudioMonitoring)) {
1361
1371
                // Copy input buffer to output buffer:
1362
 
                memcpy(out, &(in[committedFrames * inchannels]), framesPerBuffer * outchannels * sizeof(float));
 
1372
                // We need to offset our copy by committedFrames into the "in"putbuffer.
 
1373
                // Reason: committedFrames output buffer frames have been filled with
 
1374
                // silence already, and framesPerBuffer has been decremented by these
 
1375
                // committedFrames - We can only copy this reduced amount from the input
 
1376
                // buffer to the output buffer. We choose the most recent 'framesPerBuffer'
 
1377
                // frames from the inputbuffer, ie., at offset committedFrames, because the
 
1378
                // freshest frames are towards the end of the buffer, not at the beginning.
 
1379
                // (Yes this may twist your mind, but it makes sense, given the way the buffers
 
1380
                // are filled during capture and emptied during playback, believe me!)
 
1381
                memcpy(out, &(in[committedFrames * inchannels]), (size_t) (framesPerBuffer * outchannels * sizeof(float)));
1363
1382
 
1364
1383
                // Store updated positions in device structure:
1365
1384
                dev->playposition = playposition + (framesPerBuffer * outchannels);
1484
1503
                // Store updated playposition in device structure:
1485
1504
                dev->playposition = playposition;
1486
1505
 
1487
 
                // Update total count of emitted valid non-silence sample frames:
 
1506
                // Update total count of emitted sample frames during this callback by number of non-silence frames:
1488
1507
                committedFrames += i / outchannels;
1489
1508
 
1490
1509
                // Compute output time of last outputted sample from this iteration:
1491
1510
                dev->currentTime = firstsampleonset + ((double) committedFrames / (double) dev->streaminfo->sampleRate);
1492
1511
 
1493
1512
                // Update total count of emitted samples since start of playback:
1494
 
                dev->totalplaycount+= committedFrames * outchannels;
 
1513
                dev->totalplaycount+= (committedFrames - silenceframes) * outchannels;
1495
1514
                
1496
1515
                // Another end-of-playback check:
1497
1516
                if (parc > 0) {
1824
1843
                        pa_initialized = FALSE;
1825
1844
                }
1826
1845
 
 
1846
                // Detach our callback function for low-level debug output:
 
1847
                PaUtil_SetDebugPrintFunction(NULL);
 
1848
 
1827
1849
                // Restart suspended PulseAudio server if it was suspended by us:
1828
1850
                if (pulseaudio_isSuspended) {
1829
1851
                        // Call external "pactl" utility via shell to ask
1837
1859
                        pulseaudio_isSuspended = FALSE;
1838
1860
                }
1839
1861
        }
1840
 
 
1841
 
        // Detach our callback function for low-level debug output:
1842
 
        PaUtil_SetDebugPrintFunction(NULL);
1843
1862
        
1844
1863
        return(PsychError_none);
1845
1864
}
1871
1890
                }
1872
1891
 
1873
1892
        #if PSYCH_SYSTEM == PSYCH_WINDOWS
1874
 
        // Sanity check dynamic portaudio_x86.dll loading on Windows:
1875
 
        if (NULL == LoadLibrary("portaudio_x86.dll")) {
 
1893
        // Sanity check dynamic portaudio dll loading on Windows:
 
1894
        if ((NULL == LoadLibrary("portaudio_x86.dll")) && (NULL == LoadLibrary("portaudio_x64.dll"))) {
1876
1895
            // Failed:
1877
1896
            printf("\n\nPTB-ERROR: Tried to initialize PsychPortAudio's PortAudio engine. This didn't work,\n");
1878
 
            printf("PTB-ERROR: because i couldn't find or load the required portaudio_x86.dll library.\n");
 
1897
            printf("PTB-ERROR: because i couldn't find or load the required portaudio_x86.dll or portaudio_x64.dll library.\n");
1879
1898
            printf("PTB-ERROR: Please make sure to call the InitializePsychSound function before first use of\n");
1880
1899
            printf("PTB-ERROR: PsychPortAudio, otherwise this error will happen.\n\n");
1881
 
                        PsychErrorExitMsg(PsychError_user, "Failed to initialize due to portaudio_x86.dll loading problem. Call InitializePsychSound first! Aborted.");
 
1900
                        PsychErrorExitMsg(PsychError_user, "Failed to initialize due to portaudio DLL loading problem. Call InitializePsychSound first! Aborted.");
1882
1901
        }
1883
1902
        #endif
1884
1903
        
1887
1906
 
1888
1907
                if ((err=Pa_Initialize())!=paNoError) {
1889
1908
                        printf("PTB-ERROR: Portaudio initialization failed with following port audio error: %s \n", Pa_GetErrorText(err));
 
1909
            PaUtil_SetDebugPrintFunction(NULL);
1890
1910
                        PsychErrorExitMsg(PsychError_system, "Failed to initialize PortAudio subsystem.");
1891
1911
                }
1892
1912
                else {
1992
2012
        int  m, n, p;
1993
2013
        double* mychannelmap;
1994
2014
        double suggestedLatency, lowlatency;
1995
 
        PaDeviceIndex paDevice;
1996
2015
        PaHostApiIndex paHostAPI;
1997
2016
        PaStreamParameters outputParameters;
1998
2017
        PaStreamParameters inputParameters;
2248
2267
                // No specific frequency requested:
2249
2268
                if (latencyclass < 3) {
2250
2269
                        // At levels < 3, we select the device specific default.
2251
 
                        freq = referenceDevInfo->defaultSampleRate;
 
2270
                        freq = (int) referenceDevInfo->defaultSampleRate;
2252
2271
                }
2253
2272
                else {
2254
2273
                        freq = 96000; // Go really high...
2403
2422
                if (mode & kPortAudioPlayBack) {
2404
2423
                        // Allocate a dummy outputbuffer with one sampleframe:
2405
2424
                        audiodevices[audiodevicecount].outputbuffersize = sizeof(float) * audiodevices[audiodevicecount].outchannels * 1;
2406
 
                        audiodevices[audiodevicecount].outputbuffer = (float*) malloc(audiodevices[audiodevicecount].outputbuffersize);
 
2425
                        audiodevices[audiodevicecount].outputbuffer = (float*) malloc((size_t) audiodevices[audiodevicecount].outputbuffersize);
2407
2426
                        if (audiodevices[audiodevicecount].outputbuffer==NULL) PsychErrorExitMsg(PsychError_outofMemory, "Out of system memory when trying to allocate audio buffer.");
2408
2427
                }
2409
2428
                
2410
2429
                if (mode & kPortAudioCapture) {
2411
2430
                        // Allocate a dummy inputbuffer with one sampleframe:
2412
2431
                        audiodevices[audiodevicecount].inputbuffersize = sizeof(float) * audiodevices[audiodevicecount].inchannels * 1;
2413
 
                        audiodevices[audiodevicecount].inputbuffer = (float*) calloc(1, audiodevices[audiodevicecount].inputbuffersize);
 
2432
                        audiodevices[audiodevicecount].inputbuffer = (float*) calloc(1, (size_t) audiodevices[audiodevicecount].inputbuffersize);
2414
2433
                        if (audiodevices[audiodevicecount].inputbuffer == NULL) PsychErrorExitMsg(PsychError_outofMemory, "Free system memory exhausted when trying to allocate audio recording buffer!");
2415
2434
                }               
2416
2435
        }
2604
2623
        PsychAllocInIntegerListArg(3, kPsychArgOptional, &numel, &nrchannels);
2605
2624
        if (numel == 0) {
2606
2625
                // No optional channelcount argument provided: Default to pamaster settings:
2607
 
                mynrchannels[0] = audiodevices[pamaster].outchannels;
2608
 
                mynrchannels[1] = audiodevices[pamaster].inchannels;
2609
 
                if (mode & kPortAudioIsOutputCapture) mynrchannels[1] = audiodevices[pamaster].outchannels;
 
2626
                mynrchannels[0] = (int) audiodevices[pamaster].outchannels;
 
2627
                mynrchannels[1] = (int) audiodevices[pamaster].inchannels;
 
2628
                if (mode & kPortAudioIsOutputCapture) mynrchannels[1] = (int) audiodevices[pamaster].outchannels;
2610
2629
        }
2611
2630
        else if (numel == 1) {
2612
2631
                // One argument provided: Set same count for playback and recording:
2785
2804
 
2786
2805
        // Setup per-channel output volumes for slave: Each channel starts with a 1.0 setting, ie., max volume:
2787
2806
        if (audiodevices[audiodevicecount].outchannels > 0) {
2788
 
                audiodevices[audiodevicecount].outChannelVolumes = (float*) malloc(sizeof(float) * audiodevices[audiodevicecount].outchannels);
 
2807
                audiodevices[audiodevicecount].outChannelVolumes = (float*) malloc(sizeof(float) * (size_t) audiodevices[audiodevicecount].outchannels);
2789
2808
                if (audiodevices[audiodevicecount].outChannelVolumes == NULL) PsychErrorExitMsg(PsychError_outofMemory, "Memory exhausted during audio volume vector allocation.");
2790
2809
                for (i = 0; i < audiodevices[audiodevicecount].outchannels; i++) audiodevices[audiodevicecount].outChannelVolumes[i] = 1.0;
2791
2810
        }
3030
3049
                PsychPAUnlockDeviceMutex(&audiodevices[pahandle]);
3031
3050
                
3032
3051
                // Ok, everything sane, fill the buffer:
3033
 
                buffersize = sizeof(float) * inchannels * insamples;
 
3052
                buffersize = sizeof(float) * (size_t) (inchannels * insamples);
3034
3053
                if (audiodevices[pahandle].outputbuffer && (audiodevices[pahandle].outputbuffersize != buffersize)) {
3035
3054
                        free(audiodevices[pahandle].outputbuffer);
3036
3055
                        audiodevices[pahandle].outputbuffer = NULL;
3100
3119
                if (audiodevices[pahandle].outputbuffer == NULL) PsychErrorExitMsg(PsychError_user, "No audio buffer allocated! You must call this method once before start of playback to initially allocate a buffer of sufficient size.");
3101
3120
 
3102
3121
                // Buffer of sufficient size for a streaming refill of this amount?
3103
 
                buffersize = sizeof(float) * (psych_int64) inchannels * (psych_int64) insamples;
3104
 
                if (audiodevices[pahandle].outputbuffersize < buffersize) PsychErrorExitMsg(PsychError_user, "Total capacity of audio buffer is too small for a refill of this size! Allocate an initial buffer of at least the size of the biggest refill.");
 
3122
                buffersize = sizeof(float) * (size_t) ((psych_int64) inchannels * (psych_int64) insamples);
 
3123
                if (audiodevices[pahandle].outputbuffersize < (psych_int64) buffersize) PsychErrorExitMsg(PsychError_user, "Total capacity of audio buffer is too small for a refill of this size! Allocate an initial buffer of at least the size of the biggest refill.");
3105
3124
 
3106
3125
                // Need to lock b'cause of 'playposition':
3107
3126
                PsychPALockDeviceMutex(&audiodevices[pahandle]);
3329
3348
        if (bufferhandle > 0) {
3330
3349
                // Generic buffer:
3331
3350
                outdata = buffer->outputbuffer;
3332
 
                outbuffersize = buffer->outputbuffersize;
 
3351
                outbuffersize = (size_t) buffer->outputbuffersize;
3333
3352
        }
3334
3353
        else {
3335
3354
                // Standard playout buffer:
3336
3355
                outdata = audiodevices[pahandle].outputbuffer;
3337
 
                outbuffersize = audiodevices[pahandle].outputbuffersize;
 
3356
                outbuffersize = (size_t) audiodevices[pahandle].outputbuffersize;
3338
3357
        }
3339
3358
 
3340
3359
        // Buffer exists?
3529
3548
        // Deref bufferHandle:
3530
3549
        buffer = PsychPAGetAudioBuffer(bufferhandle);
3531
3550
        outdata = buffer->outputbuffer;
3532
 
        outbuffersize = buffer->outputbuffersize;
 
3551
        outbuffersize = (size_t) buffer->outputbuffersize;
3533
3552
        buffersize = sizeof(float) * (size_t) inchannels * (size_t) insamples;
3534
3553
 
3535
3554
        if (indata) {
3632
3651
        if (pahandle < 0 || pahandle>=MAX_PSYCH_AUDIO_DEVS || audiodevices[pahandle].stream == NULL) PsychErrorExitMsg(PsychError_user, "Invalid audio device handle provided.");
3633
3652
        if ((audiodevices[pahandle].opmode & kPortAudioCapture) == 0) PsychErrorExitMsg(PsychError_user, "Audio device has not been opened for audio capture, so this call doesn't make sense.");
3634
3653
 
3635
 
        buffersize = audiodevices[pahandle].inputbuffersize;
 
3654
        buffersize = (size_t) audiodevices[pahandle].inputbuffersize;
3636
3655
        
3637
3656
        // Copy in optional amount of buffer memory to allocate for internal recording ringbuffer:
3638
3657
        allocsize = 0;
3672
3691
                
3673
3692
                // Calculate needed buffersize in samples: Convert allocsize in seconds to size in bytes:
3674
3693
                audiodevices[pahandle].inputbuffersize = sizeof(float) * ((psych_int64) (allocsize * audiodevices[pahandle].streaminfo->sampleRate)) * audiodevices[pahandle].inchannels;
3675
 
                audiodevices[pahandle].inputbuffer = (float*) calloc(1, audiodevices[pahandle].inputbuffersize);
 
3694
                audiodevices[pahandle].inputbuffer = (float*) calloc(1, (size_t) audiodevices[pahandle].inputbuffersize);
3676
3695
                if (audiodevices[pahandle].inputbuffer == NULL) PsychErrorExitMsg(PsychError_outofMemory, "Free system memory exhausted when trying to allocate audio recording buffer!");
3677
3696
 
3678
3697
                // This was an (re-)allocation call, so no data is pending in the buffer.
3711
3730
                minSamples = minSecs * ((double) audiodevices[pahandle].streaminfo->sampleRate) * ((double) audiodevices[pahandle].inchannels) + ((double) audiodevices[pahandle].inchannels);
3712
3731
 
3713
3732
                // Bigger than buffersize? That would be a no no...
3714
 
                if (((psych_int64) minSamples * sizeof(float)) > audiodevices[pahandle].inputbuffersize) {
 
3733
                if (((psych_int64) (minSamples * sizeof(float))) > audiodevices[pahandle].inputbuffersize) {
3715
3734
                        PsychPAUnlockDeviceMutex(&audiodevices[pahandle]);
3716
3735
                        PsychErrorExitMsg(PsychError_user, "Invalid 'minimumAmountToReturnSecs' parameter: The requested minimum is bigger than the whole capture buffer size!'");                      
3717
3736
                }
3752
3771
        PsychPAUnlockDeviceMutex(&audiodevices[pahandle]);
3753
3772
        
3754
3773
        insamples = (insamples < 0) ? 0 : insamples;
3755
 
        buffersize = insamples * sizeof(float);
 
3774
        buffersize = (size_t) insamples * sizeof(float);
3756
3775
 
3757
3776
        // Buffer "overflow" detected?
3758
 
        if (buffersize > audiodevices[pahandle].inputbuffersize) {
 
3777
        if ((psych_int64) buffersize > audiodevices[pahandle].inputbuffersize) {
3759
3778
                // Ok, the buffer did overrun and captured data was lost. Limit returned data
3760
3779
                // to buffersize and set the overrun flag, optionally output a warning:
3761
 
                buffersize = audiodevices[pahandle].inputbuffersize;
 
3780
                buffersize = (size_t) audiodevices[pahandle].inputbuffersize;
3762
3781
                insamples = buffersize / sizeof(float);
3763
3782
                
3764
3783
                // Set overrun flag:
3774
3793
                // Clamp insamples to that value, if neccessary:
3775
3794
                if (insamples > maxSamples) {
3776
3795
                        insamples = maxSamples;
3777
 
                        buffersize = insamples * sizeof(float);
 
3796
                        buffersize = (size_t) insamples * sizeof(float);
3778
3797
                }
3779
3798
        }
3780
3799
        
3864
3883
 
3865
3884
        static char seeAlsoString[] = "Open";    
3866
3885
        
3867
 
        PaError err;
3868
3886
        int pahandle= -1;
3869
3887
        int waitForStart = 0;
3870
3888
        double when = 0.0;
4578
4596
        PsychSetStructArrayDoubleElement("XRuns", 0, audiodevices[pahandle].xruns, status);
4579
4597
        PsychSetStructArrayDoubleElement("TotalCalls", 0, audiodevices[pahandle].paCalls, status);
4580
4598
        PsychSetStructArrayDoubleElement("TimeFailed", 0, audiodevices[pahandle].noTime, status);
4581
 
        PsychSetStructArrayDoubleElement("BufferSize", 0, audiodevices[pahandle].batchsize, status);
 
4599
        PsychSetStructArrayDoubleElement("BufferSize", 0, (double) audiodevices[pahandle].batchsize, status);
4582
4600
        PsychSetStructArrayDoubleElement("CPULoad", 0, (Pa_IsStreamActive(audiodevices[pahandle].stream)) ? Pa_GetStreamCpuLoad(audiodevices[pahandle].stream) : 0.0, status);
4583
4601
        PsychSetStructArrayDoubleElement("PredictedLatency", 0, audiodevices[pahandle].predictedLatency, status);
4584
4602
        PsychSetStructArrayDoubleElement("LatencyBias", 0, audiodevices[pahandle].latencyBias, status);
5041
5059
                if (endSample > maxSample) PsychErrorExitMsg(PsychError_user, "Invalid 'endSample' provided. Must be no greater than total buffersize!");
5042
5060
        }
5043
5061
        else {
5044
 
                endSample = maxSample;
 
5062
                endSample = (double) maxSample;
5045
5063
        }
5046
5064
 
5047
5065
        if (endSample < startSample) PsychErrorExitMsg(PsychError_user, "Invalid 'endSample' provided. Must be greater or equal than 'startSample'!");
5075
5093
                "potential race-conditions between internal processing threads. Locking is enabled by default. Only "
5076
5094
                "disable locking to work around seriously broken audio device drivers or system setups and be aware "
5077
5095
                "that this may have unpleasant side effects and can cause all kinds of malfunctions by itself!\n"
5078
 
                "'lockToCore1' - Enable (1) or Disable (0) locking of all audio engine processing threads to cpu core 1 "
 
5096
                "'lockToCore1' - Deprecated: Enable (1) or Disable (0) locking of all audio engine processing threads to cpu core 1 "
5079
5097
                "on Microsoft Windows systems. By default threads are locked to cpu core 1 to avoid problems with "
5080
5098
                "timestamping due to bugs in some microprocessors clocks and in Microsoft Windows itself. If you're "
5081
5099
                "confident/certain that your system is bugfree wrt. to its clocks and want to get a bit more "
5082
5100
                "performance out of multi-core machines, you can disable this. You must perform this setting before "
5083
 
                "you open the first audio device the first time, otherwise the setting might be ignored.\n"
 
5101
                "you open the first audio device the first time, otherwise the setting might be ignored. In the current "
 
5102
        "driver this setting is silently ignored, as a new method of handling this has been implemented.\n"
5084
5103
                "'audioserver_autosuspend' - Enable (1) or Disable (0) automatic suspending of running desktop "
5085
5104
                "audio servers, e.g., PulseAudio, while PsychPortAudio is active. Default is (1) - suspend while "
5086
5105
                "PsychPortAudio does its thing. Desktop sound servers like the commonly used PulseAudio server "
5181
5200
        int pahandle = -1;
5182
5201
        int enableSchedule;
5183
5202
        int maxSize = 128;
5184
 
        int j;
 
5203
        unsigned int j;
5185
5204
        
5186
5205
        // Setup online help: 
5187
5206
        PsychPushHelp(useString, synopsisString, seeAlsoString);
5429
5448
                if (endSample > maxSample) PsychErrorExitMsg(PsychError_user, "Invalid 'endSample' provided. Must be no greater than total buffersize!");
5430
5449
        }
5431
5450
        else {
5432
 
                endSample = maxSample;
 
5451
                endSample = (double) maxSample;
5433
5452
        }
5434
5453
 
5435
5454
        if (endSample < startSample) PsychErrorExitMsg(PsychError_user, "Invalid 'endSample' provided. Must be greater or equal than 'startSample'!");
5452
5471
                slot->mode = 1 | 2 | ((specialFlags & 1) ? 4 : 0);
5453
5472
                slot->bufferhandle   = bufferHandle;
5454
5473
                slot->repetitions    = (commandCode == 0) ? ((repetitions == 0) ? -1 : repetitions) : 0.0;;
5455
 
                slot->loopStartFrame = startSample;
5456
 
                slot->loopEndFrame   = endSample;
 
5474
                slot->loopStartFrame = (psych_int64) startSample;
 
5475
                slot->loopEndFrame   = (psych_int64) endSample;
5457
5476
                slot->command            = commandCode;
5458
5477
                slot->tWhen                      = (commandCode > 0) ? repetitions : 0.0;
5459
5478