Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.09.2010, 16:22   #1
DrAndriy
Пользователь
 
Регистрация: 18.08.2010
Сообщений: 18
Восклицание Функция конвертирования TMemoryStream к TList и обратно.

Подскажите как правильно занести потоковые данные типа TMemoryStream к TList и затем их прочитать от Tlist.
Хочу в потоки записать звуковые файлы и поместить их в Tlist, f затем их прослушать. sounds - массив строковый имен файлов в директории программы.

Такой код к сожалению не работает:

Код:
  Waves := TList.Create;
  Stream := TMemoryStream.Create;
  try
    for i := 0 to 5 do
    begin
      Stream.LoadFromFile(sounds[i]);
      Stream.Position := 0;
      Waves.Add(Stream.Memory);
      Stream.Clear;
    end;
  finally
    FreeAndNil(Stream);
  end;
Где ошибка?

Спасибо.
DrAndriy вне форума Ответить с цитированием
Старый 07.09.2010, 16:40   #2
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Что ты имеешь ввиду под звуковыми файлами? Точно в таком же виде, как они на диске? Тогда в списке указатели на MemoryStream'ы храни. Стрим не один, а для каждого файла новый заводи, и указатели в список.

Код:
var
  Waves: TList;
  NewStream : TMemoryStream;
  try
    for i := 0 to 5 do
    begin
      NewStream := TMemoryStream.Create;
      NewStream.LoadFromFile(sounds[i]);
      NewStream.Position := 0;
      Waves.Add(NewStream);
    end;
  finally
  end;
Если во время жизни списка тебе нужно удалять его элементы, то удобнее TObjectList, он с уборкой мусора.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 07.09.2010 в 16:45.
mutabor вне форума Ответить с цитированием
Старый 07.09.2010, 16:43   #3
DrAndriy
Пользователь
 
Регистрация: 18.08.2010
Сообщений: 18
По умолчанию

файлы типа *.wav
можно небольшой пример решения?
спасибо

Вот такой код:

загрузка:
Код:
  Waves := TList.Create;
  for i := 0 to 5 do
  begin
    Stream := TMemoryStream.Create;
    try
      Stream.LoadFromFile(sounds[i]);
      Stream.Position := 0;
      Waves.Add(Stream.Memory);
    finally
      FreeAndNil(Stream);
    end;
  end;
выгрузка:
Код:
procedure TForm1.Button2Click(Sender: TObject);
var
  i : Integer;
begin
  i := StrToInt(Edit1.Lines.Text);
  if i >= Waves.Count then
    Exit;
  TempStream.Clear;
  TempStream.LoadFromStream(TMemoryStream(Waves[i]));
  Chan := BASS_StreamCreateFile(True, TempStream.Memory, 0, TempStream.Size, 0);
  if not BASS_ChannelPlay(Chan, False) then
    Error('Error playing stream!');
end;
Коды не работают. прочитать поток из списка не удается.
Где ошибка?
Спасибо.

Последний раз редактировалось Stilet; 07.09.2010 в 17:20.
DrAndriy вне форума Ответить с цитированием
Старый 07.09.2010, 17:06   #4
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Вот ошибка - FreeAndNil(Stream);
Не нужно его освобождать, ты же его в список помещаешь. Рассматривай ссылку на объект как предмет, например зажигалку ты можешь переложить из одного кармана в другой, так и тут, ссылку на объект ты помещаешь в список, зачем же его сразу после этого удалять, тогда в списке у тебя ссылка-пустышка будет.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 07.09.2010, 17:18   #5
DrAndriy
Пользователь
 
Регистрация: 18.08.2010
Сообщений: 18
По умолчанию

ошибку понял. так лучше использовать TObjectList, чем Tlist? В моей задаче когда список будет прочитан содержимое его можно удалить. Можете пояснить подробнее как моя задача будет выглядеть если заменить Tlist на TObjectList. В чем принципиальная разница? Спасибо
DrAndriy вне форума Ответить с цитированием
Старый 07.09.2010, 17:27   #6
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Разница в том, что TObjectList освобождает автоматически свои элементы (вызывает метод Free), а в TList ты должен делать это вручную, если не будешь освобождать вручную будешь иметь утечку памяти, и в данном случае немаленькую. Читай хелп.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 07.09.2010, 19:19   #7
DrAndriy
Пользователь
 
Регистрация: 18.08.2010
Сообщений: 18
По умолчанию

А в каком модуле класс TObjectList? спасибо за ответ

TObjectList нашел. Но возникла новая проблема. Записать в список потоки удалось и даже читать можно:

Код:
procedure TForm1.Button2Click(Sender: TObject);
var
  i : Integer;
begin
  i := StrToInt(Edit1.Lines.Text);
  if i >= Waves.Count then
    Exit;
  TempStream.Clear;
  TempStream.LoadFromStream(TMemoryStream(Waves[i]));
  Chan := BASS_StreamCreateFile(True, TempStream.Memory, 0, TempStream.Size, 0);
  if not BASS_ChannelPlay(Chan, False) then
    Error('Error playing stream!');
end;
правда вместо
TempStream.LoadFromStream(TMemorySt ream(Waves[i]));
применил:
TempStream.CopyFrom(TMemoryStream(W aves[i]), TMemoryStream(Waves[i]).Size);

С загрузкой LoadFromStream работает нормально, а вот с TempStream.CopyFrom ошибка. Почему?

Но повторное обращение к индексу списка вызывает ошибку выполнения программы. Почему?

Спасибо

Последний раз редактировалось Stilet; 09.09.2010 в 09:31.
DrAndriy вне форума Ответить с цитированием
Старый 08.09.2010, 00:48   #8
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

1. Перед копированием потоков убедись, что позиции первого и второго потока в нужном месте. Если хочешь полностью скопировать, тогда обнули позиции.
2. Чтобы обращаться к элементам списка, нужно приводить указатели к типу объекта (List[Index] as Type), в твоем случае к TMemoryStream.
3. После использования потока (загрузки чего-то из него и т.п.) сбрасывай позицию в ноль, а то в следующий раз программа будет пытаться начать читать его с конца.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 08.09.2010 в 00:54.
mutabor вне форума Ответить с цитированием
Старый 08.09.2010, 17:49   #9
DrAndriy
Пользователь
 
Регистрация: 18.08.2010
Сообщений: 18
По умолчанию

спасибо, ошибку нашел.
DrAndriy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
TMemoryStream и Zlib Sanprof Общие вопросы Delphi 13 28.05.2010 16:43
TMemoryStream Владимир1988 Помощь студентам 0 13.02.2010 13:04
Плагин для конвертирования в .x файлы Longedok Gamedev - cоздание игр: Unity, OpenGL, DirectX 4 24.08.2008 15:03
как перевести из integer в real(и обратно), и из real в string(и обратно) Ga-sergey Общие вопросы Delphi 2 08.06.2007 21:13