def main():
    nElectrodes = 21  #number of electrodes
    lowFreq = 200  #lower frequency boudary [Hz]
    highFreq = 5000  #higher frequency boudary [Hz]
    winSize = 6  #window size [ms]
    stepSize = .5  #step size [ms]
    inputMethod = None
    while inputMethod != 'fourier' and inputMethod != '1' and inputMethod != 'gamma' and inputMethod != '2':
        inputMethod = input(
            'Please enter the method you want to use (fourier,1/gamma,2): '
        )  #valid inputs: ('fourier','1'), ('gamma','2')
        if inputMethod == 'fourier' or inputMethod == '1':
            method = 'fourier'
        elif inputMethod == 'gamma' or inputMethod == '2':
            method = 'gamma'

    inFileName = './SoundData/tiger.wav'
    #inFileName = './SoundData/vowels.wav'
    #inFileName = './SoundData/Mond_short.wav'

    if (('inFileName' in locals()) or
        ('inFileName' in globals())) and inFileName != None:
        snd = thSound.Sound(inFileName)
    else:
        snd = thSound.Sound()
        inFileName = snd.source

    sampleRate = snd.rate

    outStem, outSuffix = inFileName.rsplit('.', 1)
    outFileName = outStem + '_out.wav'

    if snd.data.ndim < 2:
        snd.data = np.reshape(snd.data, (len(snd.data), 1))
    soundData = np.zeros(snd.data.shape)
    for lrIdx in range(snd.data.shape[1]):
        stimuli, freq = calculateStimuliWindowed(snd.data[:, lrIdx],
                                                 sampleRate, nElectrodes,
                                                 lowFreq, highFreq, winSize,
                                                 stepSize, method)
    ##################################################################
    ## At this point, stimuli contains the stimulation intensities, ##
    ## one row per electrode. Based on this, the sound a wearer of  ##
    ## a CI might percieve is estimated.                            ##
    ##################################################################
    for lrIdx in range(snd.data.shape[1]):
        soundData[:, lrIdx] = simulateSound(stimuli, freq, sampleRate)
    writeSoundToFile(soundData, sampleRate, outFileName)
Exemple #2
0
def writeSoundToFile(outData, sampleRate, outFileName=None):

    if not outData[0].dtype == np.dtype('int16'):
        defaultAmp = 2**13
        outData *= defaultAmp / np.max(outData)
        outData = np.int16(outData)

    ### this section is a copy-paste from thLib's writeWav, as it can't handle stereo sound
    if outFileName is None:
        (outFile, outDir) = ui.savefile('Write sound to ...', '*.wav')
        if outFile == 0:
            print('Output discarded.')
            return 0
        else:
            outFileName = os.path.join(outDir, outFile)
    else:
        outDir = os.path.abspath(os.path.dirname(outFileName))
        outFile = os.path.basename(outFileName)
    #        outFileName = tkFileDialog.asksaveasfilename()

    scipy.io.wavfile.write(str(outFileName), int(sampleRate), outData)
    print('Sounddata written to ' + outFile + ', with a sample rate of ' +
          str(sampleRate))
    print('OutDir: ' + outDir)

    ###

    #ugly hack, s.t. playing stereo is possible
    #(thLib accepts stereo files and keeps them stereo, but it is not possible
    # to construct stereo Sound objects, except from files.)
    dummySnd = thSound.Sound(outFileName)
    dummySnd.play()
Exemple #3
0
def main():
    nElectrodes = 21
    lowFreq = 400  #hz
    highFreq = 5000  #hz
    winSize = 6  #ms
    stepSize = .5  #ms

    method = 'gamma'  #alt: 'fourier', 'gamma'
    tailFactor = 5  #only takes effect if method='gamma'. determines
    #how lon

    inFileName = './SoundData/tiger.wav'
    #inFileName = './SoundData/vowels.wav'
    #inFileName = './SoundData/Mond_short.wav'

    if (('inFileName' in locals()) or
        ('inFileName' in globals())) and inFileName != None:
        snd = thSound.Sound(inFileName)
    else:
        snd = thSound.Sound()
        inFileName = snd.source

    sampleRate = snd.rate

    outStem, outSuffix = inFileName.rsplit('.', 1)
    outFileName = outStem + '_' + method + '_out.wav'

    if method == 'gamma':
        winTailSize = 5 * winSize
    else:
        winTailSize = winSize

    if snd.data.ndim < 2:
        snd.data = np.reshape(snd.data, (len(snd.data), 1))
    soundData = np.zeros(snd.data.shape)
    for lrIdx in range(snd.data.shape[1]):
        stimuli, freq = calculateStimuliWindowed(snd.data[:, lrIdx],
                                                 sampleRate, nElectrodes,
                                                 lowFreq, highFreq, winSize,
                                                 stepSize, winTailSize, method)

    for lrIdx in range(snd.data.shape[1]):
        soundData[:, lrIdx] = simulateSound(stimuli, freq, sampleRate)
    writeSoundToFile(soundData, sampleRate, outFileName)
def writeSoundToFile(outData, sampleRate, outFileName=None):
    """
    Generates a sound file from outData
    
    Args:
        otuData: array, output data representing the sound
        sampleRate: integer, sampling rate of the sound to be written
        outFileName: string, path and name of the output soundfile
    Returns:
        void
    """
    ########################################################
    ## this section is a slightly altered copy-paste from ##
    ## thLib's setData, as it couldn't originally deal    ##
    ## with 2D arrays.                                    ##
    ########################################################
    if not outData[0].dtype == np.dtype('int16'):
        defaultAmp = 2**13
        outData *= defaultAmp / np.max(outData)
        outData = np.int16(outData)

    #########################################################
    ## this section is a copy-paste from thLib's writeWav, ##
    ## as setData wouldn't accept Stereo sound.            ##
    #########################################################
    if outFileName is None:
        (outFile, outDir) = ui.savefile('Write sound to ...', '*.wav')
        if outFile == 0:
            print('Output discarded.')
            return 0
        else:
            outFileName = os.path.join(outDir, outFile)
    else:
        outDir = os.path.abspath(os.path.dirname(outFileName))
        outFile = os.path.basename(outFileName)
    #        outFileName = tkFileDialog.asksaveasfilename()

    scipy.io.wavfile.write(str(outFileName), int(sampleRate), outData)
    print('Sounddata written to ' + outFile + ', with a sample rate of ' +
          str(sampleRate))
    print('OutDir: ' + outDir)
    #################################
    ## End of copy-pasted sections ##
    #################################

    #ugly hack, s.t. playing stereo is possible
    #(thLib accepts stereo files and keeps them stereo, but it is not possible
    # to construct stereo Sound objects, except from files.)
    dummySnd = thSound.Sound(outFileName)
    dummySnd.play()
Exemple #5
0
def calcTransform(ci, inSound):
    ''' Step through the whole file to calculate
           i) the stimulation parameters, and
           ii) the reconstructed output
   '''

    #Allocate the required memory
    StimStrength = np.zeros(ci.dataNum)
    ReAssembled = np.zeros(ci.dataNum)

    time = np.arange(ci.winStepSize_pts) / float(inSound.rate)
    for ii in progressbar(
            range(1, ci.dataNum - ci.winCalcSize_pts + 2, ci.winStepSize_pts),
            'Computing ', 25):

        # Calculate PowerSpectrum
        Pxx, freq = pSpect(inSound.data[ii:(ii + ci.winCalcSize_pts - 1)],
                           inSound.rate)

        # set averaging ranges, only on the first loop
        # I have to do this here, since I need "freq"
        if ii == 1:
            average_freqs = np.zeros([len(freq), ci.Electrodes_num])
            stim_data = np.zeros([ci.Electrodes_num, len(time)])

            for jj in range(ci.Electrodes_num):
                average_freqs[((freq > ci.sample_freqs[jj]) *
                               (freq < ci.sample_freqs[jj + 1])), jj] = 1
                stim_freq = np.mean(ci.sample_freqs[jj:(jj + 2)])
                # "stim_data" are the sine-waves corresponding to each electrode stimulation
                stim_data[jj, :] = np.sin(2 * np.pi * stim_freq * time)

        # Average over the requested bins
        # The square root has to be taken, to get the amplitude
        StimStrength = np.sqrt(Pxx).dot(average_freqs)

        # Reassemble the output
        NewStim = StimStrength.dot(stim_data)
        ReAssembled[ii:(ii + ci.winStepSize_pts)] = NewStim

    # Return the output as normalized 32-bit integer
    outFloat = (ReAssembled - np.min(ReAssembled))
    outSound = (outFloat / np.max(outFloat) * (2**31 - 1)).astype(np.int32)
    return Sound.Sound(inData=outSound.astype(np.float64), inRate=inSound.rate)
Exemple #6
0
def main(inFile=None):
    ''' Main file. It
    * selects the sound source, and gets the data
    * defines the cochlear implant
    * calculates the simulated sound
    * writes the data to an out-file
    '''

    inSound = Sound.Sound(inFile)
    # inSound.play()
    newCi = CochleaImplant(inSound)
    ciSound = calcTransform(newCi, inSound)

    # Determine the name of the out-file, write and play it
    inFile = os.path.basename(str(inSound.source))
    inBase, inExt = inFile.split('.')
    fullOutFile = inBase + '_out.' + inExt
    ciSound.source = fullOutFile

    ciSound.writeWav(fullOutFile)
    ciSound.play()