Is it possible to record and play audio simultaneously?

I am developing an iOS app which allows users to practice shadowing (*language learning method). Thus, I’d like to play audios and record your voice simultaneously. However, during recording, playing audio is very unstable e.g. low volume, unnatural pitch, etc. Is there any way to do it?

My cord is as below. It would be grateful if you give me any insight.

const loadNewPlaybackInstance = async (audioPath, playbackInstance, setState) => {
  if (playbackInstance !== null) {
    await playbackInstance.unloadAsync()
    playbackInstance = null
  }
  const initialStatus = {
   shouldPlay: false,
   rate: 1,
   shouldCorrectPitch: true,
   volume: 1,
   isMuted: false,
   isLooping: false,
 }
  const { sound, status } = await Audio.Sound.createAsync(audioPath, initialStatus)
  setState(sound)
}

const beginRecording = async () => {
    await Audio.setAudioModeAsync({
      allowsRecordingIOS: true,
      interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_MIX_WITH_OTHERS,
      playsInSilentModeIOS: true,
      shouldDuckAndroid: true,
      interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DUCK_OTHERS,
      playThroughEarpieceAndroid: true,
      staysActiveInBackground: false,
    })
    const recording = new Audio.Recording()
    const recordingSettings = JSON.parse(JSON.stringify(Audio.RECORDING_OPTIONS_PRESET_LOW_QUALITY))
    await recording.prepareToRecordAsync(recordingSettings)
    recordingInstanceRef.current = recording
    await recordingInstanceRef.current.startAsync() 
}


useEffect(() => {
    const { audioPath } = script[sourceId].sourceContents[unitId]
    loadNewPlaybackInstance(audioPath, playbackInstance, updatePlaybackInstance)
  }, [])

  useEffect(() => {
     if (!onPlayingAudio && playbackInstance) {
       playbackInstance.stopAsync()
     }
  }, [onPlayingAudio])

  useEffect(() => {
     if (currentSentenceId) {
       const currentIndex = getCurrentIndex(sourceId, unitId, currentSentenceId)
       const positionMillis = 1000*script[sourceId].sourceContents[unitId].sentences[currentIndex].position
       playbackInstance.playAsync()
       playbackInstance.setPositionAsync(positionMillis)
    }
  }, [currentSentenceId])

  useEffect(() => {
    if (onRecording) {
      beginRecording()
    } else if (recordingInstanceRef.current){
      stopRecording()
    }
  }, [onRecording])

Hey @takuya0206, I’m not sure how well this would work (either in a managed Expo project or bare), but could you share a snack that reproduces the problems you’re seeing?

Thank you for your reply. I I tried to figure it out on my own after I posted. It turned out that recording and playing audios can work simultaneously on EMULATOR. However, on your iPhone, audios can be played only at low volume and bluetooth earphones are suddenly disconnected.

I will share my snack as below. You can reproduce the problem by tapping “Osaka Univ. - Self-learning Materials” => “Arrived at India” => “Shadowing.” It would be great if I could allow users to use bluetooth earphones at least. Any advice will be appreciated.
*Note: my app is for Japanese people who want to learn Hindi language. I have translated some texts for the snack, but it still may not be friendly for English speakers.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.