playing song on a specific earplug (channel) - matlab

I have a device that is like 3 headphones in one ( so 6 earplugs) . My goal is to play one diferent song on each earplug ( 6 songs). So I starded by playing one song on an earplug. For me one channel means one earplug (but maybe I am wrong) .I am using Psychtoolbox:
function BasicSoundOutputDemo( wavfilename)
AssertOpenGL;
% Read WAV file from filesystem:
[y, freq] = psychwavread(wavfilename);
aux = y' ;
wavedata = aux(1,:);
InitializePsychSound;
devices = PsychPortAudio('GetDevices' );
pahandle = PsychPortAudio('Open', [], [], 0, freq, 1);// nr channels = 1
PsychPortAudio('FillBuffer', pahandle, wavedata);
t1 = PsychPortAudio('Start', pahandle, 1, 0);
KbReleaseWait;
while ~KbCheck
% Wait a seconds...
WaitSecs(1);
end
PsychPortAudio('Stop', pahandle);
PsychPortAudio('Close', pahandle);
fprintf('Demo finished, bye!\n');
But it didn’t worked. Instead of playing the sound on just one earplug, it was playing on 2 earplugs.
I get this warnings
PTB-INFO: Using specially modified PortAudio engine, based on offical
version: PortAudio V19-devel WITH-DIM
Will use ASIO enhanced Portaudio driver DLL. See
Psychtoolbox/PsychSound/PortAudioLICENSE.txt for the exact terms of
use for this dll.
Disclaimer: "ASIO is a trademark and software of Steinberg Media
Technologies GmbH."
PTB-Warning: Although using the ASIO enabled Psychtoolbox sound
driver,
PTB-Warning: could not find any ASIO capable soundcard in your system.
PTB-Warning: If you think you should have an ASIO card, please check
your
PTB-Warning: system for properly installed and configured drivers and
retry.
PTB-Warning: Read "help InitializePsychSound" for more info about ASIO
et al.
PTB-INFO: New audio device with handle 0 opened as PortAudio stream:
PTB-INFO: For 1 channels Playback: Audio subsystem is MME, Audio
device name is Microsoft Sound Mapper - Output
PTB-INFO: Real samplerate 44100.000000 Hz. Input latency 0.000000
msecs, Output latency 464.399093 msecs.
Then I decided to try another aproch. Lets play the song on other 2 earplugs
I used PsychPortAudio('GetDevices') to find the id of the earplugs pair. Strange is that instead of 3 devices with 2 channels I found 4.
And I used PsychPortAudio('Open' for id 7,9,18 and 20 but every time the song was played on the same earplug pair, the same pair from when I tried to play on just one earplug.
This is a picture with the 4 devices
function BasicSoundOutputDemo( wavfilename)
AssertOpenGL;
% Read WAV file from filesystem:
[y, freq] = psychwavread(wavfilename);
wavedata = y' ;
nrchannels = size(wavedata,1); % Number of rows == number of channels.
InitializePsychSound;
devices = PsychPortAudio('GetDevices' );
pahandle = PsychPortAudio('Open', 18, [], 0, freq, nrchannels);
PsychPortAudio('FillBuffer', pahandle, wavedata);
t1 = PsychPortAudio('Start', pahandle, 1, 0);
KbReleaseWait;
while ~KbCheck
% Wait a seconds...
WaitSecs(1);
end
PsychPortAudio('Stop', pahandle);
PsychPortAudio('Close', pahandle);
fprintf('Demo finished, bye!\n');
Now the only thing that is different at warnigs it this
PTB-INFO: For 2 channels Playback: Audio subsystem is Windows
DirectSound, Audio device name is Speakers (USB Multi-Channel Audio
Device)
Sorry for this long post but i wanted to give you all the informations.
Can you tell were I am wrong. How can I play one song on a specific earplug. I think if I know that then I just copy the code and put another song and so I will play one song on each earplug

1) You likely don't want to run AssertOpenGL every time you present a sound.
2) Your code looks correct, though interestingly on my Apple laptop and built-in sound, sending a single channel signal is also playing from both headphone channels.
3) What audio device are you using? From your device listing, it looks like the 4 you have listed might be different interfaces to the same devices (2 outputs (one digital, one analog) X two APIs (one MME, one DirectSound). Are there any other entries in your device list?

a partial answer to my question. I found how to play a song in an earplug and another in the other. psychwavread gives me a 2 rows array. so i put in an array the first row of one song and the first row of the other song. so now i have a 2 row array simillar to the one from when i play one song, but now i play 2 songs
[y, freq] = psychwavread(wavfilename1);
[y1, freq1] = psychwavread(wavfilename2);
aux = y';
aux1 = y1';
wavedata = [aux1(1,:) ; aux(1,:)];

so i manage to play on 4 channels i am sure that i can play on 6 and 8. I installed ASIO4ALL and I choose the ASIO4ALL device id when open. when ASIO4all opens I can choose my 6 channels device and after that I just choose in the open function on which channels to play the sounds

Related

How do I control which channel sound is played through using MATLAB?

I'm a novice MATLAB user, so apologies if the question is very basic. I need a .wav sound file to be played in a single, specific channel -- let's say the left channel. As it is, my code reads in the sound file, and I add in a column of zeros to nullify the channel I don't want, like so:
currentDir = pwd;
soundFile = [currentDir '\sound1.wav']; % load the file
[y, Fs] = audioread(soundFile); % read the file in
soundData(:,1) = y(:,1); % keeps sound for the left channel
soundData(:,2) = 0; % nullifies the right channel
sound = audioplayer(soundData,Fs);
play(sound);
As it stands, the code currently produces a sound that is full volume in the left speaker, and half volume (but still very much audible) in the right speaker. I have tried this with at least 20 .wav files, with the same result.
In case it's relevant, this happens even when I write in code that explicitly matches the length of the sound variable in 0s, like so:
[y, Fs] = audioread(soundFile);
silentChannel = zeros(size(y));
soundData(:,1) = y(:,1); % keeps sound for the left channel
soundData(:,2) = silentChannel(:,2); % nullifies the right channel
Does anybody know what I'm doing wrong, or have any thoughts?
Your code is definitely correct and it should only play audio in the left channel. I suspect that the problem is caused by a sound-card/driver issues. Allow me suggest the following troubleshooting steps:
Save your output as a wav file using audiowrite('output.wav', soundData, Fs). Play this using a different audio player, such as Audacity. If you still hear output in both channels, it must be a sound-card/driver issue.
Assuming that you are using a Windows PC (going by the syntax in your file path), make sure all sound enhancements are disabled. How to do this depends on the PC. If there is a third-party app controlling the playback settings, you'd have to use that. Otherwise find the settings shown in the picture below in the Control Panel.
In MatLab the expected method for playing sound is the method sound(data,Fs)
To control the channel the sound emits on, you'll want to know how sound() reads data.
data is a matrix with the columns representing channels, and with the rows holding the samples of the waveform for a given sampling fequency Fs
here is a simple implementation.
function treismanwolfe()
close all
clear all
clc
Fs = 40000;
tau = 2*pi();
t = 0:tau/(Fs-1):tau/2;
left = sin(t).*(sin(t*200)+sin(t*1600));
left= left/max(abs(left));
left = left'; %turn column vector into row
right = sin(t).*(sin(t*800)+sin(t*400));
right= right/max(abs(right));
right = right'; %turn column vector into row
data = [left,right*0]; %multiply either by 0 to nullify
sound(data,Fs); %so you can hear it.
end
I hope this works for you. Enjoy!
When I run your code the audio output is only audible in the left channel as you have specified.
#Austin Kootz' version with the sound()-function is just as good and also produces what you're looking for, but with audioplayer-object you have the ability to stop the playback in the middle of the playback (as you probably know)
Have you tried converting your .wav to another format to see if that makes a change?

Creating alarm sound in psychtoolbox matlab

I am trying to create an experiment on psychtoolbox and one part of it involves sounding an alarm when the participant fail to respond.
I tried using the beep provided but it does not sound like an alarm at all. Is there any way to achieve that without having to download a external sound?
I have no knowledge of sound or sound waves so please help!
The following code will load a .wav file, and play it through the Psychtoolbox audio system. This allows you to have a timestamp of sound onset, and allows greater control than using sound() or beep. You could alternatively generate a tone using MATLAB itself (it is easy to generate a sine wave of a particular frequency) and use that instead of the .wav data.
%% this block only needs to be performed once, at the start of the experiment
% initialize the Psychtoolbox audio system in low latency mode
InitializePsychSound(1);
% load in a waveform for the warning
[waveform,Fs] = audioread('alarm.wav');
numChannels = size(waveform, 2);
% open the first audio device in low-latency, stereo mode
% if you have more than one device attached, you will need to specify the
% appropriate deviceid
pahandle = PsychPortAudio('Open', 2, [], 1, Fs, numChannels);
%% during the experiment, when you want to play the alarm
PsychPortAudio('FillBuffer', pahandle, waveform' );
startTime = PsychPortAudio('Start', pahandle, 1);
%% at the conclusion of the experiment
PsychPortAudio('Close');
If you'd like to generate your own sound, take a look at the Psychtoolbox function 'MakeBeep', and substitute that in, instead of the waveform, for example, a 1000 Hz tone, lasting 250ms, at a 44.1k sampling rate:
% generate a beep
beepWaveform = MakeBeep(1000,.250,44100);
% make stereo
beepWaveform = repmat(beepWaveform, 2, 1);
% fill buffer, play
PsychPortAudio('FillBuffer', pahandle, beepWaveform );
startTime = PsychPortAudio('Start', pahandle, 1);
To me, beep can do what you want by playing it multiple times in the loop like this:
% Adjust the no. of loop iterations depending on how long you want to play the alarm
for k=1:100
beep; pause(1);
end
Other than that, you can use built-in sounds like this:
load('gong'); % This sound seems suitable to me for alarm. Try others from the list
for k=1:100
sound(y,Fs); pause(1);
end
Here's a list of built-in sounds that you may want to try:
chirp
gong
handel
laughter
splat
train

Unable to create audio compressor filter

Function takes as input a string, the name of the video. It's read the video with the vision.VideoFileReader function and returns the same video, using thevision.VideoFileWriter function. Both the input video that the output videos have audio. Processing of a video about 6 MB, i have the output of a video more than 1 GB. The function has no errors, but i have to compress. Using the VideoCompressor, can compress the video up to 350 MB, i would use theAudioCompressor, but by obtaining an error.
This is my code, the following is the error returned.
function [ nFrames ] = showMovie( video )
v = VideoReader(video);
videoFReader = vision.VideoFileReader(video);
videoFWriter = vision.VideoFileWriter('FrameRate',v.FrameRate,'AudioInputPort',1,'VideoCompressor', 'MJPEG Compressor','AudioCompressor','MJPEG Compressor');
[audio,fs] = audioread(video);
op=floor(fs/v.FrameRate);
nFrames = 0;
while ~isDone(videoFReader)
nFrames=nFrames+1;
frame=step(videoFReader);
audios=audio( (nFrames-1)*op + 1 : nFrames*op , : );
step(videoFWriter,frame,audios);
end
release(videoFReader);
release(videoFWriter);
end
I can't use the property AudioCompressor. I tried both the Compressor MJPEG and the DV Video Encoder value, but I get this error:
Error using VideoFileWriter / step
Unable to create audio compressor filter
Error in showMovie (line 15)
step (videoFWriter, frame, audios);
You're trying to specify a video compressor for your audio which is resulting in the error. Different compression algorithms are used for the audio and video components. You need to specify a valid audio compressor.
To get a list of available options on your machine, you can use tab completion in the command window:
videoWriter.AudioCompressor = ' % <tab> key
As Rotem has noted, this list can also include Video compression algorithms, but it should also include any valid audio compression algorithms for which you have the correct codecs installed.
The only AudioCompressor compressor that works in my system is: 'None (uncompressed)'
I tried it on 64 bit version of Matlab (R2014b).
The reason for that is that my Windows system lacks x64 (64 bit) audio codec supported by Matlab.
Note: 64 bit Matlab requires x64 codecs, and 32 bit Matlab requires x86 codecs.
When I use videoWriter.AudioCompressor = ' % <tab> key as Suever mentioned,
When I tried the same code using 32 bit version of Matlab (R2013b), I got the following list:
AC-3 ACM Codec
AC-3 ACM Extensible
CCITT A-Law
CCITT U-Law
GSM 6.10
IMA ADPCM
Microsoft ADPCM
None (uncompressed)
Note: The video codecs shown in 64 bit version, are not displayed in the 32 bit Matlab.
I guess displaying video codecs in AudioCompressor is a Matlab bug.
Just for the record, I tried the <tab> key before Suever posed his answer.
I read about it in Matlab documentation: http://www.mathworks.com/help/vision/ref/vision.videofilewriter-class.html
To launch the tab completion functionality, type the following up to the open quote.
y.VideoCompressor='
A list of compressors available on your system will appear after you press the Tab key
The following code sample works in system:
video = 'xylophone.mpg';
v = VideoReader(video);
videoFReader = vision.VideoFileReader(video);
videoFWriter = vision.VideoFileWriter('FrameRate',v.FrameRate,'AudioInputPort',1,'VideoCompressor', 'MJPEG Compressor','AudioCompressor', 'None (uncompressed)');
[audio,fs] = audioread(video);
op=floor(fs/v.FrameRate);
nFrames = 0;
while ~isDone(videoFReader)
nFrames=nFrames+1;
frame=step(videoFReader);
audios=audio( (nFrames-1)*op + 1 : min(nFrames*op, length(audio)) , : );
%Handle last audio sample.
if (length(audios) < op)
audios = [audios; audios(1:op - length(audios), :)];
end
step(videoFWriter,frame,audios);
end
release(videoFReader);
release(videoFWriter);
I was searching the Web for free x64 audio codec that works with Matlab, but I couldn't find one.

Issues with creating a 30kHz soundwave in MATLAB

I want to create a 30kHz sound with MATLAB ( after which I use the Earthworks microphone ( M50 ) to test / analyse the audio replay (sound) produced from the synthetised signal stored by MATLAB in a .WAV file ).
I use the following code, but whether it is some wrong, and if I want to create another 50kHz wave, how should I modify the code?
Fs = 96200;
toneFreq1 = 30000;
nSeconds = 20;
f1 = sin( linspace( 0, nSeconds*toneFreq1*2*pi, round( nSeconds * Fs ) ) );
sound( f1, Fs )
wavwrite( f1, Fs, 24, '30khz.wav' );
First, most soundcards are not able to play back using your Fs. Typically, they offer 88200 or 96000 Hz, so you should choose one of them.
Second, due to Nyquist-Shannon theorem you can't create a frequency higher than half the sampling rate. I.e. with Fs=96000 the highest possible frequency is theoretically 48000 Hz, but then you need to use cos instead of sin.
Update: You are creating, playing back, recording, and analysing a sound. So, you have various sources of error.
My two points above correct your problems with creating the sound. The following matlab program shows clearly that the synthetic signal comprises exactly the sine wav you intended to create. So, the problem your original question was about, is solved:
clear
Fs = 96000;
toneFreq1 = 30000; % change between 0 and Fs/2=48000
nSeconds = 20;
f1 = cos( linspace (0, nSeconds*toneFreq1*2*pi, round(nSeconds*Fs) ) );
freqz( f1, length(f1) )
Thus, the new spectrogram image of your modified question reflects other problems that are due to playing back, recording, and/or analysing.
It is hard to say, what problem you face. I just can give you some hints:
1) Most probable, your amplifier and/or loudspeaker are not able to reproduce frequencies much above 20kHz. You should start with frequencies between 8 and 12kHz, then you are able to hear them. If you are older than, say 40 years, it could be hard for you to hear frequencies above ca. 15kHz. But even if you are 20 years old you're not able to hear frequencies above ca. 18 to 20kHz (at least you need huge amplification to hear them).
2) Your microphone is able to convert these high frequencies into an electrical signal, but it is possible that either your microphone amplifier or your sound card is bandwidth-limited to say 22 or 24kHz.
3) Your program that converts the measured signal into a spectrogram might have bugs.
4) The segmentation at the beginning and end of the measured signal also introduces artifacts into the spectrum.
If you need further help, you should post your recording and analysis code. But I guess that with my hints you are able to find the problem on your own. Nonetheless, it would be interesting to inform us about your results.

record sound Synchronaouslly from 3 separate Microphone

I try to record sound from 3 separate USB-Microphones. Using (Matlab 2008)
I use this Command:
%% Definr audio Channel
r1 = audiorecorder(44100, 16,1,1);
r2 = audiorecorder(44100, 16,1,2);
r3 = audiorecorder(44100, 16,1,3);
%% Start record
record(r1); % speak into microphone...
record(r2);
record(r3);
%% Stop record
stop(r1);
stop(r2);
stop(r3);
I want to compare between recorder files from 3 microphone, but Microphons dont start and stop record in same time. and alwayes there are about (1500 to 3000 sample) deferance between recorder files.
so the problem:
I want to start record (in 3 microphone) in same time. and Stop all in same time.
are there any command to start record in same time (or constant time, not same time exactly).
I hope I could exolain what i need
and hope find a help...................................Thanx
Rather than using three separate audiorecorder objects, just use one and call its constructor with 3 in the third argument (nChannels - see http://www.mathworks.co.uk/help/matlab/ref/audiorecorder.html ). This will instruct it to record three channels simultaneously. That is,
r = audiorecorder(44100, 16, 3, 1);