#c# #audio
#c# #Аудио
Вопрос:
Я создал аудиосинтезатор, используя информацию, найденную на http://soundfile.sapp.org/doc/WaveFormat /.
private const int SAMPLE_RATE = 44100;
private const short BITS_PER_SAMPLE = 16;
short[] asSoundValues = new short[SAMPLE_RATE]
float fFreq = 440;
for (int iValueCount = 0; iValueCount < SAMPLE_RATE; iValueCount )
{
asSoundValues[iValueCount] = Convert.ToInt16(short.MaxValue *
Math.Sin(((Math.PI * 2 * fFreq) / SAMPLE_RATE) * iValueCount));
}
byte[] abBinarySoundValues = new byte[SAMPLE_RATE * sizeof(short)];
Buffer.BlockCopy(asSoundValues, 0, abBinarySoundValues, 0,
asSoundValues.Length * sizeof(short));
using (MemoryStream msMemoryStream = new MemoryStream())
{
using (BinaryWriter bwBinaryWriter = new BinaryWriter(msMemoryStream))
{
short sBlockAlign = BITS_PER_SAMPLE / 8;
int iSubChunkTwoSize = SAMPLE_RATE * sBlockAlign;
bwBinaryWriter.Write(new[] { 'R', 'I', 'F', 'F' });
bwBinaryWriter.Write(36 iSubChunkTwoSize);
bwBinaryWriter.Write(new[] { 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ' });
bwBinaryWriter.Write(16);
bwBinaryWriter.Write((short)1);
bwBinaryWriter.Write((short)1);
bwBinaryWriter.Write(SAMPLE_RATE);
bwBinaryWriter.Write(SAMPLE_RATE * sBlockAlign);
bwBinaryWriter.Write(sBlockAlign);
bwBinaryWriter.Write(BITS_PER_SAMPLE);
bwBinaryWriter.Write(new[] { 'd', 'a', 't', 'a' });
bwBinaryWriter.Write(iSubChunkTwoSize);
bwBinaryWriter.Write(abBinarySoundValues);
msMemoryStream.Position = 0;
new SoundPlayer(msMemoryStream).Play();
}
}
Звук длится 1 секунду. Как мне продлить этот звук, чтобы он длился дольше — например, 5 секунд?
Комментарии:
1.
short[] asSoundValues = new short[SAMPLE_RATE * numberOfSeconds]
?2. Пробовал — длина по-прежнему составляет 1 секунду.
Ответ №1:
В соответствии с форматом wave, это то, Subchunk2Size
что в конечном итоге определяет длину WAV, что помогло мне выяснить все, что нужно было бы изменить, кроме ваших массивов сэмплов. Итак, это все изменения, которые вам нужно будет внести:
for (int iValueCount = 0; iValueCount < SAMPLE_RATE * numberOfSeconds; iValueCount )
short[] asSoundValues = new short[SAMPLE_RATE * numberOfSeconds]
byte[] abBinarySoundValues = new byte[SAMPLE_RATE * sizeof(short) * numberOfSeconds];
int iSubChunkTwoSize = SAMPLE_RATE * sBlockAlign * numberOfSeconds;
Комментарии:
1. Это близко! 2-секундный пример: первая половина abBinarySoundValues должна быть заполнена значениями asSoundValues — вторая половина также должна быть заполнена значениями asSoundValues .
2. @ttom Я обновил свой ответ; ваш цикл for также нуждался в изменении.
Ответ №2:
Это работает (если я не сделал никаких опечаток):
private const int SAMPLE_RATE = 44100;
private const short BITS_PER_SAMPLE = 16;
short[] asSoundValues = new short[SAMPLE_RATE]
float fFreq = 440;
int iLengthOfTimeInSecs = 5;
for (int iValueCount = 0; iValueCount < SAMPLE_RATE; iValueCount )
{
asSoundValues[iValueCount] = Convert.ToInt16(short.MaxValue *
Math.Sin(((Math.PI * 2 * fFreq) / SAMPLE_RATE) * iValueCount));
}
int iNumOfShortsIn_asSoundValuesArray = SAMPLE_RATE;
int iNumOfBytesIn_asSoundValuesArray = SAMPLE_RATE * sizeof(short);
int iNumOfBytesIn_abBinarySoundValuesArray = iNumOfBytesIn_asSoundValuesArray *
iLengthOfTimeInSecs;
byte[] abBinarySoundValues = new byte[iNumOfBytesIn_abBinarySoundValuesArray];
for (int ii = 0; ii < iLengthOfTimeInSecs; ii )
{
Buffer.BlockCopy(asSoundValues,
0,
abBinarySoundValues,
iNumOfBytesIn_asSoundValuesArray * ii,
iNumOfBytesIn_asSoundValuesArray);
}
using (MemoryStream msMemoryStream = new MemoryStream())
{
using (BinaryWriter bwBinaryWriter = new BinaryWriter(msMemoryStream))
{
short sBlockAlign = BITS_PER_SAMPLE / 8;
int iSubChunkTwoSize = iNumOfShortsIn_asSoundValuesArray *
sBlockAlign * iLengthOfTimeInSecs;
bwBinaryWriter.Write(new[] { 'R', 'I', 'F', 'F' });
bwBinaryWriter.Write(36 iSubChunkTwoSize);
bwBinaryWriter.Write(new[] { 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ' });
bwBinaryWriter.Write(16);
bwBinaryWriter.Write((short)1);
bwBinaryWriter.Write((short)1);
bwBinaryWriter.Write(iNumOfShortsIn_asSoundValuesArray);
bwBinaryWriter.Write(iNumOfShortsIn_asSoundValuesArray * sBlockAlign);
bwBinaryWriter.Write(sBlockAlign);
bwBinaryWriter.Write(BITS_PER_SAMPLE);
bwBinaryWriter.Write(new[] { 'd', 'a', 't', 'a' });
bwBinaryWriter.Write(iSubChunkTwoSize);
bwBinaryWriter.Write(abBinarySoundValues);
msMemoryStream.Position = 0;
new SoundPlayer(msMemoryStream).Play();
}
}