philwzo@quiche.cs.mcgill.ca (Philippe WIECZOREK) (11/21/90)
The method (int)convertToFormat:(int)aFormat samplingRate:(double)aRate channelCount:(int)aChannelCount for converting a sound works fine to change the format or the sampling rate of a sound, but it seems not to work for changing the number of channel of the sound. Indeed, I did not manage to convert a stereo channel sound to a mono one. What is the correct way to do that ? Is the fdfilter.c's convertToMono (SNDSoundStruct **) function correct ? (the fdfilter.c is located in the directory : /NextDeveloper/Examples/DSP/ArrayProcessing/fdfilter ) Thanx for any reply... Phil. /============================================================\ /==============================================================\ // Philippe WIECZOREK. | e-mail : philwzo@cs.mcgill.ca \\ // Speech Lab. | Only NeXT makes it possible \\ // McGill University, | Please forgive me my english \\ // Montreal PQ. CANADA. | I am just a little frenchie ! :-) \\ /========================================================================\ /==========================================================================\
laughlin@fornax.UUCP (Bob Laughlin) (11/23/90)
In article <49@homer.cs.mcgill.ca> philwzo@quiche.cs.mcgill.ca (Philippe WIECZOREK) writes: > > The method (int)convertToFormat:(int)aFormat > samplingRate:(double)aRate > channelCount:(int)aChannelCount > for converting a sound works fine to change the format or the > sampling rate of a sound, but it seems not to work for changing > the number of channel of the sound. > Indeed, I did not manage to convert a stereo channel sound to > a mono one. > What is the correct way to do that ? > Is the fdfilter.c's convertToMono (SNDSoundStruct **) function > correct ? (the fdfilter.c is located in the directory : > /NextDeveloper/Examples/DSP/ArrayProcessing/fdfilter ) > > Thanx for any reply... > > Phil. > > /============================================================\ > /==============================================================\ > // Philippe WIECZOREK. | e-mail : philwzo@cs.mcgill.ca \\ > // Speech Lab. | Only NeXT makes it possible \\ > // McGill University, | Please forgive me my english \\ > // Montreal PQ. CANADA. | I am just a little frenchie ! :-) \\ > /========================================================================\ > /==========================================================================\ Neither sndconvert -c 1 nor convertToFormat:samplingRate:channelCount: are implemented for converting 2 channel to 1, although it will do the sampling rate conversion and maybe some of the format conversions. If you examine the error code returned from convertToFormat::: you will see this. The way that I did it is to allocate a new Sound object and copy the data over. Stereo Sound data is stored with alternating left/right samples (shorts). I needed to convert stereo sounds digitized with Digital Ears to mono and did'nt care which channel I got. You'd have to experiment to see whether the even numbered samples are the left or right channel. Below is a method to do this and optionally save the new file to disk. - convertSoundForAnalysis //--------------------------------------------------------------------------- // If the sound file read in is not of the proper format, convert it // to the proper format and allow user to save it to a file. For the // analysis we want 1 channel sound at 44,100 sampling rate and // 16 bit linear samples. sampledSound is an instance variable that // has a valid sound in it when this is called. //--------------------------------------------------------------------------- { id tempSound = nil ; int i, newDataSize ; short *oldData, *newData ; BOOL needToConvert = NO ; if ([sampledSound channelCount] != 1) { NXRunAlertPanel ("", "channelCount is being changed to 1", NULL, NULL, NULL) ; needToConvert = YES ; } if ([sampledSound samplingRate] != samplingRate) { NXRunAlertPanel ("", "samplingRate is being converted to %d", NULL, NULL, NULL, (int) samplingRate) ; needToConvert = YES ; } if ([sampledSound dataFormat] != SND_FORMAT_LINEAR_16) { NXRunAlertPanel ("", "dataFormat is being converted to SND_FORMAT_LINEAR_16", NULL, NULL, NULL) ; needToConvert = YES ; } if (needToConvert == NO) return self ; newDataSize = [sampledSound dataSize] / 2 ; tempSound = [Sound new] ; [tempSound setDataSize: newDataSize dataFormat: SND_FORMAT_LINEAR_16 samplingRate: samplingRate channelCount: 1 infoSize: 0] ; if ([sampledSound needsCompacting]) [sampledSound compactSamples] ; oldData = (short *) [sampledSound data] ; newData = (short *) [tempSound data] ; // stereo data alternates samples for the left and right channels for (i = 0; i < newDataSize / 2; ++i, oldData += 2) *(newData++) = *oldData ; [sampledSound free] ; sampledSound = tempSound ; // see if user wants to save converted sound file if (NXRunAlertPanel ("Alert", "Save converted sound to file?", "Yes", "No", NULL) == NX_ALERTDEFAULT) { if (!savePanel) { savePanel = [SavePanel new] ; [savePanel setPrompt:"Save sound to file"] ; } // make it easy to save file over the file read in if ([savePanel runModalForDirectory: soundDir file: soundFilename]) { [NXWait set] ; NXPing () ; if ([sampledSound writeSoundfile:(char *)[savePanel filename]]) NXRunAlertPanel ("Alert","Save sound file failed", NULL, NULL, NULL); [NXArrow set] ; NXPing () ; } } return self ; } -- Bob Laughlin laughlin@cs.sfu.ca